練習使用圖標,菜單,加速鍵,消息框等資源。
1. 圖標(注冊類時使用自己畫的大圖標和小圖標)。
2. 菜單(設計一個菜單,能控制動態改變圖標(3選1單選),在四個位置顯示大圖標(復選),“關于”)。
3. 加速鍵(每個菜單項都有加速鍵)。
4. 消息框(改變圖標前確認是否要修改, About)。
5. 顯示菜單前動態生成一個下拉菜單,加入到主菜單中(File下Exit,位置0), 也要處理加速鍵。
6.選擇圖標3時復選菜單灰化,不顯示復選大圖標。
實現功能 5 時,自己查MSDN
CopyAcceleratorTable
CreateAcceleratorTable
DestroyAcceleratorTable
1. 我最初是在Win7寫此程序,動態改動標題欄圖標時,使用 ::SetClassLong( hWnd, GCL_HICON, (long)(hIcon) ); 沒有效果,仔細看老師的ppt,確實是這么講的,然后到 MSDN 中查閱 SetClassLong 函數時,看到 GCL_HICONSM,我猜測是因為我的窗口類為 WNDCLASSEX,其中大小圖標是有區別的,應該用 GCL_HICONSM ,于是我調用 ::SetClassLong( hWnd, GCL_HICONSM, (long)(hIcon) ); 標題欄的小圖標可以修改了。然而回到WinXP繼續開發時,標題欄圖標又無法修改了,以為是WinXP下不支持24位圖標,改為4位,無效。大小圖標分別建立資源,依然無效。最后將窗口類換為 WNDCLASS 后,SetClassLong 可以正常工作。
2. 設置加速鍵時,對 Ctrl + 1 這種有數字的加速鍵,我誤用了小鍵盤的數字鍵 Ctrl + numpad1,后來才發現。
截圖:
程序信息消息框:

圖標類型 1

圖標類型 1 時,顯示圖標

換圖標時的詢問對話框:

換為圖標 3 時,不顯示復選大圖標

換為圖標 3 時,復選菜單無效灰化

鍵盤加速鍵都可以正常工作。
源碼:
WinZJ.cpp
1
// WinZJ.cpp : Defines the entry point for the application.
2
//
3
4
#include "stdafx.h"
5
#include "resource.h"
6
7
#define MAX_LOADSTRING 100
8
9
// Global Variables:
10
HINSTANCE hInst; // current instance
11
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
12
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
13
14
// Forward declarations of functions included in this code module:
15
ATOM MyRegisterClass(HINSTANCE hInstance);
16
BOOL InitInstance(HINSTANCE, int);
17
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
18
19
int APIENTRY _tWinMain(HINSTANCE hInstance,
20
HINSTANCE hPrevInstance,
21
LPTSTR lpCmdLine,
22
int nCmdShow)
23

{
24
UNREFERENCED_PARAMETER(hPrevInstance);
25
UNREFERENCED_PARAMETER(lpCmdLine);
26
27
// TODO: Place code here.
28
MSG msg;
29
HACCEL hAccelTable;
30
31
ACCEL entryAccel[ 100 ];
32
int nEntryAccel;
33
34
// Initialize global strings
35
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
36
LoadString(hInstance, IDC_WINZJ, szWindowClass, MAX_LOADSTRING);
37
MyRegisterClass(hInstance);
38
39
// Perform application initialization:
40
if (!InitInstance (hInstance, nCmdShow))
41
{
42
return FALSE;
43
}
44
45
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINZJ));
46
nEntryAccel = ::CopyAcceleratorTable( hAccelTable, NULL, 0 );
47
::CopyAcceleratorTable( hAccelTable, entryAccel, nEntryAccel );
48
entryAccel[ nEntryAccel ].cmd = IDM_EXIT;
49
entryAccel[ nEntryAccel ].fVirt = ( FVIRTKEY | FCONTROL | FSHIFT );
50
entryAccel[ nEntryAccel ].key = VK_DELETE;
51
++nEntryAccel;
52
::DestroyAcceleratorTable( hAccelTable );
53
hAccelTable = ::CreateAcceleratorTable( entryAccel, nEntryAccel );
54
55
// Main message loop:
56
while (GetMessage(&msg, NULL, 0, 0))
57
{
58
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
59
{
60
TranslateMessage(&msg);
61
DispatchMessage(&msg);
62
}
63
}
64
65
::DestroyAcceleratorTable( hAccelTable );
66
return (int) msg.wParam;
67
}
68
69
70
71
//
72
// FUNCTION: MyRegisterClass()
73
//
74
// PURPOSE: Registers the window class.
75
//
76
// COMMENTS:
77
//
78
// This function and its usage are only necessary if you want this code
79
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
80
// function that was added to Windows 95. It is important to call this function
81
// so that the application will get 'well formed' small icons associated
82
// with it.
83
//
84
ATOM MyRegisterClass(HINSTANCE hInstance)
85

{
86
WNDCLASS wc;
87
88
wc.style = CS_HREDRAW | CS_VREDRAW;
89
wc.lpfnWndProc = WndProc;
90
wc.cbClsExtra = 0;
91
wc.cbWndExtra = 0;
92
wc.hInstance = hInstance;
93
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINZJ));
94
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
95
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
96
wc.lpszMenuName = MAKEINTRESOURCE(IDC_WINZJ);
97
wc.lpszClassName = szWindowClass;
98
99
return ::RegisterClass( &wc );
100
}
101
102
//
103
// FUNCTION: InitInstance(HINSTANCE, int)
104
//
105
// PURPOSE: Saves instance handle and creates main window
106
//
107
// COMMENTS:
108
//
109
// In this function, we save the instance handle in a global variable and
110
// create and display the main program window.
111
//
112
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
113

{
114
HWND hWnd;
115
116
hInst = hInstance; // Store instance handle in our global variable
117
118
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
119
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
120
121
if (!hWnd)
122
{
123
return FALSE;
124
}
125
126
ShowWindow(hWnd, nCmdShow);
127
UpdateWindow(hWnd);
128
129
return TRUE;
130
}
131
132
BOOL ChangeIcon( HWND hWnd )
{
133
return IDYES == ::MessageBox( hWnd, TEXT("確定要修改嗎?"), TEXT("Confirmation"), MB_YESNO | MB_ICONQUESTION );
134
}
135
136
HICON GetIcon( DWORD dwIconMenuId, LPTSTR str )
{
137
DWORD dwIconId;
138
switch ( dwIconMenuId )
{
139
case IDM_ICON_1 :
140
dwIconId = IDI_WINZJ;
141
lstrcpy( str, TEXT("當前使用的圖標是:圖標 1") );
142
break;
143
case IDM_ICON_2 :
144
dwIconId = IDI_ICON_OTHER;
145
lstrcpy( str, TEXT("當前使用的圖標是:圖標 2") );
146
break;
147
case IDM_ICON_3 :
148
dwIconId = IDI_ICON_OTHER2;
149
lstrcpy( str, TEXT("當前使用的圖標是:圖標 3") );
150
break;
151
default :
152
return NULL;
153
}
154
return ::LoadIcon( hInst, MAKEINTRESOURCE(dwIconId) );
155
}
156
157
//
158
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
159
//
160
// PURPOSE: Processes messages for the main window.
161
//
162
// WM_COMMAND - process the application menu
163
// WM_PAINT - Paint the main window
164
// WM_DESTROY - post a quit message and return
165
//
166
//
167
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
168

{
169
static DWORD dwIconMenuId;
170
171
PAINTSTRUCT ps;
172
HDC hdc;
173
HMENU hMenu = ::GetMenu( hWnd );
174
int wmId = LOWORD(wParam);
175
int wmEvent = HIWORD(wParam);
176
HICON hIcon;
177
TCHAR str[ 100 ];
178
179
switch (message)
180
{
181
case WM_CREATE :
182
::CheckMenuRadioItem( hMenu, IDM_ICON_1, IDM_ICON_1, IDM_ICON_1, MF_BYCOMMAND );
183
dwIconMenuId = IDM_ICON_1;
184
{
185
HMENU hSubMenu = ::CreatePopupMenu();
186
::AppendMenu( hSubMenu, MF_STRING, IDM_EXIT, TEXT("Exit\tCtrl+Shift+Delete") );
187
::InsertMenu( hMenu, 0, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT)hSubMenu, TEXT("&File") );
188
}
189
break;
190
case WM_COMMAND:
191
switch (wmId)
192
{
193
case IDM_APP_INFO :
194
::MessageBox( hWnd, TEXT("第二次上機練習\n圖標,菜單,加速鍵,消息框\n\n學號:*********\n姓名:****\n"), TEXT("Lab2"), MB_ICONINFORMATION );
195
break;
196
case IDM_EXIT :
197
::DestroyWindow( hWnd );
198
break;
199
case IDM_SHOW_1 :
200
case IDM_SHOW_2 :
201
case IDM_SHOW_3 :
202
case IDM_SHOW_4 :
203
if ( ::GetMenuState( hMenu, wmId, MF_BYCOMMAND ) & MF_CHECKED )
{
204
::CheckMenuItem( hMenu, wmId, MF_UNCHECKED );
205
}
206
else
{
207
::CheckMenuItem( hMenu, wmId, MF_CHECKED );
208
}
209
::InvalidateRect( hWnd, NULL, TRUE );
210
break;
211
case IDM_ICON_1 :
212
case IDM_ICON_2 :
213
case IDM_ICON_3 :
214
if ( (wmId!=dwIconMenuId) && (::ChangeIcon(hWnd)) )
{
215
// 注意 Resource.h 中 IDM_ICON_1 .. IDM_ICON_3 等差 1
216
::CheckMenuRadioItem( hMenu, IDM_ICON_1, IDM_ICON_3, wmId, MF_BYCOMMAND );
217
dwIconMenuId = wmId;
218
if ( wmId == IDM_ICON_3 )
{
219
::EnableMenuItem( hMenu, IDM_SHOW_1, MF_BYCOMMAND | MF_GRAYED );
220
::EnableMenuItem( hMenu, IDM_SHOW_2, MF_BYCOMMAND | MF_GRAYED );
221
::EnableMenuItem( hMenu, IDM_SHOW_3, MF_BYCOMMAND | MF_GRAYED );
222
::EnableMenuItem( hMenu, IDM_SHOW_4, MF_BYCOMMAND | MF_GRAYED );
223
}
224
else
{
225
::EnableMenuItem( hMenu, IDM_SHOW_1, MF_BYCOMMAND | MF_ENABLED );
226
::EnableMenuItem( hMenu, IDM_SHOW_2, MF_BYCOMMAND | MF_ENABLED );
227
::EnableMenuItem( hMenu, IDM_SHOW_3, MF_BYCOMMAND | MF_ENABLED );
228
::EnableMenuItem( hMenu, IDM_SHOW_4, MF_BYCOMMAND | MF_ENABLED );
229
}
230
::InvalidateRect( hWnd, NULL, TRUE );
231
}
232
break;
233
default:
234
return DefWindowProc(hWnd, message, wParam, lParam);
235
}
236
break;
237
case WM_PAINT:
238
hdc = BeginPaint(hWnd, &ps);
239
240
hIcon = ::GetIcon( dwIconMenuId, str );
241
242
::SetClassLong( hWnd, GCL_HICON, (long)(hIcon) );
243
244
::TextOut( hdc, 100, 100, str, lstrlen(str) );
245
::DrawIcon( hdc, 300, 100, hIcon );
246
247
if (dwIconMenuId != IDM_ICON_3 )
{
248
// 注意 Resource.h 中 IDM_SHOW_1 .. IDM_SHOW_4 等差 1
249
for ( wmId = IDM_SHOW_1; wmId <= IDM_SHOW_4; ++wmId )
{
250
if ( ::GetMenuState( hMenu, wmId, MF_BYCOMMAND ) & MF_CHECKED )
{
251
::DrawIcon( hdc, 230 + (wmId-IDM_SHOW_1)%2*100, 230 + (wmId-IDM_SHOW_1)/2*100, hIcon );
252
}
253
}
254
}
255
256
EndPaint(hWnd, &ps);
257
break;
258
case WM_DESTROY:
259
PostQuitMessage(0);
260
break;
261
default:
262
return DefWindowProc(hWnd, message, wParam, lParam);
263
}
264
return 0;
265
}
266
WinZJ.rc
1
// Microsoft Visual C++ generated resource script.
2
//
3
#include "resource.h"
4
5
#define APSTUDIO_READONLY_SYMBOLS
6
/**////////////////////////////////////////////////////////////////////////////// 7
//
8
// Generated from the TEXTINCLUDE 2 resource.
9
//
10
#ifndef APSTUDIO_INVOKED
11
#include "targetver.h"
12
#endif
13
#define APSTUDIO_HIDDEN_SYMBOLS
14
#include "windows.h"
15
#undef APSTUDIO_HIDDEN_SYMBOLS
16
17
/**////////////////////////////////////////////////////////////////////////////// 18
#undef APSTUDIO_READONLY_SYMBOLS
19
20
/**////////////////////////////////////////////////////////////////////////////// 21
// Chinese (Simplified, PRC) resources
22
23
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
24
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
25
26
/**////////////////////////////////////////////////////////////////////////////// 27
//
28
// Icon
29
//
30
31
// Icon with lowest ID value placed first to ensure application icon
32
// remains consistent on all systems.
33
IDI_ICON_OTHER ICON "icon_other.ico"
34
IDI_ICON_OTHER2 ICON "icon_other2.ico"
35
#endif // Chinese (Simplified, PRC) resources
36
/**//////////////////////////////////////////////////////////////////////////////
37
38
39
///////////////////////////////////////////////////////////////////////////// 40
// English (United States) resources
41
42
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
43
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
44
45
/**////////////////////////////////////////////////////////////////////////////// 46
//
47
// Icon
48
//
49
50
// Icon with lowest ID value placed first to ensure application icon
51
// remains consistent on all systems.
52
IDI_WINZJ ICON "WinZJ.ico"
53
54
/**////////////////////////////////////////////////////////////////////////////// 55
//
56
// Menu
57
//
58
59
IDC_WINZJ MENU
60
BEGIN
61
POPUP "圖標類型(&I)"
62
BEGIN
63
MENUITEM "圖標 1\tCtrl+1", IDM_ICON_1
64
MENUITEM "圖標 2\tCtrl+2", IDM_ICON_2
65
MENUITEM "圖標 3\tCtrl+3", IDM_ICON_3
66
END
67
POPUP "顯示圖標(&D)"
68
BEGIN
69
MENUITEM "顯示 1\tCtrl+Shift+1", IDM_SHOW_1
70
MENUITEM "顯示 2\tCtrl+Shift+2", IDM_SHOW_2
71
MENUITEM "顯示 3\tCtrl+Shift+3", IDM_SHOW_3
72
MENUITEM "顯示 4\tCtrl+Shift+4", IDM_SHOW_4
73
END
74
POPUP "關于(&A)"
75
BEGIN
76
MENUITEM "程序信息(I)\tF1", IDM_APP_INFO
77
END
78
END
79
80
81
/**////////////////////////////////////////////////////////////////////////////// 82
//
83
// Accelerator
84
//
85
86
IDC_WINZJ ACCELERATORS
87
BEGIN
88
VK_F1, IDM_APP_INFO, VIRTKEY, NOINVERT
89
"1", IDM_ICON_1, VIRTKEY, CONTROL, NOINVERT
90
"2", IDM_ICON_2, VIRTKEY, CONTROL, NOINVERT
91
"3", IDM_ICON_3, VIRTKEY, CONTROL, NOINVERT
92
"1", IDM_SHOW_1, VIRTKEY, SHIFT, CONTROL, NOINVERT
93
"2", IDM_SHOW_2, VIRTKEY, SHIFT, CONTROL, NOINVERT
94
"3", IDM_SHOW_3, VIRTKEY, SHIFT, CONTROL, NOINVERT
95
"4", IDM_SHOW_4, VIRTKEY, SHIFT, CONTROL, NOINVERT
96
END
97
98
99
#ifdef APSTUDIO_INVOKED
100
/**//////////////////////////////////////////////////////////////////////////////101
//
102
// TEXTINCLUDE
103
//
104
105
1 TEXTINCLUDE
106
BEGIN
107
"resource.h\0"
108
END
109
110
2 TEXTINCLUDE
111
BEGIN
112
"#ifndef APSTUDIO_INVOKED\r\n"
113
"#include ""targetver.h""\r\n"
114
"#endif\r\n"
115
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
116
"#include ""windows.h""\r\n"
117
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
118
"\0"
119
END
120
121
3 TEXTINCLUDE
122
BEGIN
123
"\r\n"
124
"\0"
125
END
126
127
#endif // APSTUDIO_INVOKED
128
129
130
/**//////////////////////////////////////////////////////////////////////////////131
//
132
// String Table
133
//
134
135
STRINGTABLE
136
BEGIN
137
IDS_APP_TITLE "WinZJ——第二次上機練習"
138
IDC_WINZJ "WINZJ"
139
END
140
141
#endif // English (United States) resources
142
/**//////////////////////////////////////////////////////////////////////////////143
144
145
146
#ifndef APSTUDIO_INVOKED
147
/**//////////////////////////////////////////////////////////////////////////////148
//
149
// Generated from the TEXTINCLUDE 3 resource.
150
//
151
152
153
/**//////////////////////////////////////////////////////////////////////////////154
#endif // not APSTUDIO_INVOKED
155
156
resource.h
1
//{{NO_DEPENDENCIES}}
2
// Microsoft Visual C++ generated include file.
3
// Used by WinZJ.rc
4
//
5
#define IDC_MYICON 2
6
#define IDS_APP_TITLE 103
7
#define IDM_EXIT 105
8
#define IDI_WINZJ 107
9
#define IDC_WINZJ 109
10
#define IDR_MAINFRAME 128
11
#define IDI_ICON_OTHER 129
12
#define IDI_ICON_OTHER2 130
13
#define IDM_APP_INFO 32771
14
#define IDM_SHOW_1 32774
15
#define IDM_SHOW_2 32775
16
#define IDM_SHOW_3 32776
17
#define IDM_SHOW_4 32777
18
#define IDM_ICON_1 32784
19
#define IDM_ICON_2 32785
20
#define IDM_ICON_3 32786
21
#define IDC_STATIC -1
22
23
// Next default values for new objects
24
//
25
#ifdef APSTUDIO_INVOKED
26
#ifndef APSTUDIO_READONLY_SYMBOLS
27
#define _APS_NO_MFC 1
28
#define _APS_NEXT_RESOURCE_VALUE 133
29
#define _APS_NEXT_COMMAND_VALUE 32794
30
#define _APS_NEXT_CONTROL_VALUE 1000
31
#define _APS_NEXT_SYMED_VALUE 110
32
#endif
33
#endif
34
targetver.h
1
#pragma once
2
3
// Including SDKDDKVer.h defines the highest available Windows platform.
4
5
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
6
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
7
8
#include <SDKDDKVer.h>
9
stdafx.h
1
// stdafx.h : include file for standard system include files,
2
// or project specific include files that are used frequently, but
3
// are changed infrequently
4
//
5
6
#pragma once
7
8
#include "targetver.h"
9
10
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
11
// Windows Header Files:
12
#include <windows.h>
13
14
// C RunTime Header Files
15
#include <stdlib.h>
16
#include <malloc.h>
17
#include <memory.h>
18
#include <tchar.h>
19
20
21
// TODO: reference additional headers your program requires here
22
stdafx.cpp
1
// stdafx.cpp : source file that includes just the standard includes
2
// WinZJ.pch will be the pre-compiled header
3
// stdafx.obj will contain the pre-compiled type information
4
5
#include "stdafx.h"
6
7
// TODO: reference any additional headers you need in STDAFX.H
8
// and not in this file
9