练习使用图标,菜单,加速键,消息框等资源。
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