图标,菜单,加速键,消息框——Windows编程上机作业之二
练习使用图标,菜单,加速键,消息框等资源。
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
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
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
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
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
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
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