练习使用图标,菜单,加速键,消息框等资源。
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:
10HINSTANCE hInst; // current instance
11TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
12TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
13
14// Forward declarations of functions included in this code module:
15ATOM MyRegisterClass(HINSTANCE hInstance);
16BOOL InitInstance(HINSTANCE, int);
17LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
18
19int 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//
84ATOM 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//
112BOOL 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
132BOOL ChangeIcon( HWND hWnd ) {
133 return IDYES == ::MessageBox( hWnd, TEXT("确定要修改吗?"), TEXT("Confirmation"), MB_YESNO | MB_ICONQUESTION );
134}
135
136HICON 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//
167LRESULT 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)
24LANGUAGE 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.
33IDI_ICON_OTHER ICON "icon_other.ico"
34IDI_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)
43LANGUAGE 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.
52IDI_WINZJ ICON "WinZJ.ico"
53
54/**////////////////////////////////////////////////////////////////////////////// 55//
56// Menu
57//
58
59IDC_WINZJ MENU
60BEGIN
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
78END
79
80
81/**////////////////////////////////////////////////////////////////////////////// 82//
83// Accelerator
84//
85
86IDC_WINZJ ACCELERATORS
87BEGIN
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
96END
97
98
99#ifdef APSTUDIO_INVOKED
100/**//////////////////////////////////////////////////////////////////////////////101//
102// TEXTINCLUDE
103//
104
1051 TEXTINCLUDE
106BEGIN
107 "resource.h\0"
108END
109
1102 TEXTINCLUDE
111BEGIN
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"
119END
120
1213 TEXTINCLUDE
122BEGIN
123 "\r\n"
124 "\0"
125END
126
127#endif // APSTUDIO_INVOKED
128
129
130/**//////////////////////////////////////////////////////////////////////////////131//
132// String Table
133//
134
135STRINGTABLE
136BEGIN
137 IDS_APP_TITLE "WinZJ——第二次上机练习"
138 IDC_WINZJ "WINZJ"
139END
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