Windows 标准控件:按钮控件的使用
该文章根据 CC-BY-4.0 协议发表,转载请遵循该协议。
本文地址:https://fenying.net/post/2011/07/20/windows-sdk-command-button/
本文展示 Windows 标准控件之按钮控件的使用方法。
以下程序在 Windows 7 简体中文破解版、Visual C++ 2008 专业版、Windows 7 SDK 环境下编译通过。
1/* File Begin */
2// wTest.cpp : 定义应用程序的入口点。
3// This is a Win32 Application C Project.
4// Author: Fenying
5// Time: 2011-07-20
6// Version: 0.0.0.1
7// (C) Maple Knights & Fenying Studio Reserved.
8// Description: Windows 7 Ultimate SP1 & Visual C++ 2008 Pro & Windows 7 SDK & Win32 Application C Project are required.
9
10#include <tchar.h>
11#include <Windows.h>
12#include <CommCtrl.h>
13
14#ifdef NULL
15 #undef NULL
16 #define NULL 0
17#else
18 #define NULL 0
19#endif
20
21//[0] 使用系统主题
22#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
23
24//[A] 全局变量:
25HINSTANCE hInst; // 当前实例
26LPCTSTR szTitle; // 标题栏文本
27LPCTSTR szWindowClass; // 主窗口类名
28HWND hBtnO; // 第一个按钮句柄
29HFONT hForeFont; // 默认字体
30
31//[B] 此代码模块中包含的函数的前向声明:
32LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
33INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
34void SetFont(HWND hWndDst);
35HWND CreateButton(DWORD dwStyle, LPCTSTR pTitle, HWND hParent, INT x, INT y, INT width, INT height, WORD wID);
36
37//[C] 宏常量
38
39#define GLOBAL_FORE_FONT_NAME _T("Tahoma")
40#define BTN_PUSHBUTTON 1
41#define BTN_DEFPUSHBUTTON 2
42#define BTN_CHECKBOX 3
43#define BTN_AUTOCHECKBOX 4
44#define BTN_3STATECHECKBOX 5
45#define BTN_AUTO3STATECHECKBOX 6
46#define BTN_GROUPBOX 7
47#define BTN_RADIOBOX 8
48#define BTN_AUTORADIOBOX 9
49#define BTN_COMMNADLINK 10
50#define BTN_DEFCOMMNADLINK 11
51#define BTN_SPLITBUTTON 12
52#define BTN_DEFSPLITBUTTON 13
53
54//[D] 主函数
55int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
56
57 MSG msg;
58 WNDCLASSEX wcex;
59 HWND hWnd;
60
61 // 初始化字符串
62 szWindowClass = _T("my_wnd_cls");
63 szTitle = _T("Hello World");
64
65 // 初始化默认字体
66 hForeFont = CreateFontW(14,0,0,0,0,0,0,0,DEFAULT_CHARSET,0,0,0,0, GLOBAL_FORE_FONT_NAME);
67
68 // 注册窗口类
69 wcex.cbSize = sizeof(WNDCLASSEX);
70
71 wcex.style = CS_HREDRAW | CS_VREDRAW;
72 wcex.lpfnWndProc = WndProc;
73 wcex.cbClsExtra = 0;
74 wcex.cbWndExtra = 0;
75 wcex.hInstance = hInstance;
76 wcex.hIcon = NULL;
77 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
78 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
79 wcex.lpszMenuName = NULL;
80 wcex.lpszClassName = szWindowClass;
81 wcex.hIconSm = NULL;
82
83 RegisterClassEx(&wcex);
84
85 // 创建窗体
86 hInst = hInstance; // 将实例句柄存储在全局变量中
87
88 hWnd = CreateWindow(szWindowClass, szTitle, WS_TABSTOP|WS_OVERLAPPEDWINDOW, 200, 0, 800, 600, NULL, NULL, hInstance, NULL);
89
90 if (!hWnd) {
91 MessageBox(NULL,_T("Failed to create a window."), szTitle, MB_OK);
92 return FALSE;
93 }
94
95 ShowWindow(hWnd, nCmdShow);
96 UpdateWindow(hWnd);
97
98 // 主消息循环:
99 while (GetMessage(&msg, NULL, 0, 0)) {
100 TranslateMessage(&msg);
101 DispatchMessage(&msg);
102 }
103
104 return (int) msg.wParam;
105}
106
107//[E] 消息回调函数
108LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
109 int wmId, wmEvent;
110 HWND hCtl;
111
112 switch (uMsg) {
113 case WM_CREATE: // 当窗体被创建时
114
115 // 创建一个标准命令按钮 Push Button
116 hBtnO = CreateButton(BS_PUSHBUTTON, _T("Button"), hWnd, 50, 50, 200, 32, BTN_PUSHBUTTON);
117
118 // 创建一个缺省标准命令按钮 Default Push Button
119 CreateButton(BS_DEFPUSHBUTTON, _T("Default Button"), hWnd, 50, 85, 200, 32, BTN_DEFPUSHBUTTON);
120
121 // 创建一个二态复选框 CheckBox,其被单击时不会自动改变选择状态
122 CreateButton(BS_CHECKBOX, _T("CheckBox"), hWnd, 50, 120, 200, 24, BTN_CHECKBOX);
123
124 // 创建一个二态自动复选框 Auto CheckBox,其被单击时会自动改变选择状态
125 CreateButton(BS_AUTOCHECKBOX, _T("Auto CheckBox"), hWnd, 50, 150, 200, 24, BTN_AUTOCHECKBOX);
126
127 // 创建一个三态复选框 3 State CheckBox,其被单击时不会自动改变选择状态
128 CreateButton(BS_3STATE, _T("3 State CheckBox"), hWnd, 50, 180, 200, 24, BTN_3STATECHECKBOX);
129
130 // 创建一个三态自动复选框 Auto 3 State CheckBox,其被单击时会自动改变选择状态
131 CreateButton(BS_AUTO3STATE, _T("Auto 3 State CheckBox"), hWnd, 50, 210, 200, 24, BTN_AUTO3STATECHECKBOX);
132
133 // 创建一个组合框 Group Box
134 CreateButton(BS_GROUPBOX, _T("Group Box"), hWnd, 50, 240, 200, 100, BTN_GROUPBOX);
135
136 // 创建一个单选框 Radio Box,其被单击时不会自动改变选择状态
137 CreateButton(BS_RADIOBUTTON, _T("Radio Box"), hWnd, 50, 350, 200, 24, BTN_RADIOBOX);
138
139 // 创建一个自动单选框 Auto Radio Box,其被单击时会自动改变选择状态
140 CreateButton(BS_AUTORADIOBUTTON, _T("Auto Radio Box"), hWnd, 50, 380, 200, 24, BTN_AUTORADIOBOX);
141
142 // 创建一个自动单选框 Auto Radio Box,其被单击时会自动改变选择状态
143 CreateButton(BS_AUTORADIOBUTTON, _T("Auto Radio Box"), hWnd, 50, 410, 200, 24, BTN_AUTORADIOBOX);
144
145 // Windows Vista Required.
146#if _WIN32_WINNT >= 0x600
147
148 // 创建一个命令链接按钮 Command Link
149 CreateButton(BS_COMMANDLINK, _T("Command Link"), hWnd, 300, 50, 200, 48, BTN_COMMNADLINK);
150
151 // 创建一个缺省命令链接按钮 Def Command Link
152 CreateButton(BS_DEFCOMMANDLINK, _T("Def Command Link"), hWnd, 300, 100, 200, 48, BTN_DEFCOMMNADLINK);
153
154 // 创建一个分割按钮 Split Button
155 CreateButton(BS_SPLITBUTTON, _T("Split Button"), hWnd, 300, 150, 200, 48, BTN_SPLITBUTTON);
156
157 // 创建一个缺省分割按钮 Def Split Button
158 CreateButton(BS_DEFSPLITBUTTON, _T("Def Split Button"), hWnd, 300, 200, 200, 48, BTN_DEFSPLITBUTTON);
159
160#endif
161 //
162
163 break;
164
165 case WM_COMMAND: //控件事件
166 hCtl = (HWND)lParam;
167 wmId = LOWORD(wParam); // wParam 的低字表示控件标识,即 CreateWindowEx 函数的 hMenu 参数
168 wmEvent = HIWORD(wParam); // wParam 的高字表示控件事件
169 if (lParam)
170 switch (wmId) {
171 case BTN_PUSHBUTTON: //命令按钮的事件
172 switch (wmEvent) {
173 case BN_CLICKED: // 单击事件。
174 /*******************************************************
175 * 单击事件消息。
176 *******************************************************/
177 MessageBox(hWnd, _T("Hi, You clicked the command button"), szTitle, MB_OK);
178 break;
179 case BN_DOUBLECLICKED:
180 /*******************************************************
181 * 双击事件消息。
182 * 此消息不能和 BN_CLICKED 同时处理,否则无法接收此消息。
183 * BS_USERBUTTON, BS_RADIOBUTTON, BS_OWNERDRAW 三种按钮可
184 * 以自动支持此消息,其他按钮必须添加 BS_NOTIFY 样式。
185 *******************************************************/
186 MessageBox(hWnd, _T("Hi, You double clicked the command button"), szTitle, MB_OK);
187 break;
188 default:
189 goto onNothing;
190 }
191 break;
192
193 case BTN_DEFPUSHBUTTON: //缺省命令按钮的事件
194 switch (wmEvent) {
195 case BN_CLICKED: // 单击事件。
196 switch (SendMessage(hBtnO, BM_GETSTATE, 0, 0)) {
197 /*******************************************************
198 * BM_GETSTATE - 获取 Push Button 的状态,
199 * 返回值取如下值:
200 * BST_PUSHED - 已按下
201 * BST_UNCHECKED - 未按下
202 *******************************************************/
203 case BST_PUSHED:
204 SendMessage(hBtnO, BM_SETSTATE, BST_UNCHECKED, 0);
205 /*******************************************************
206 * BM_SETSTATE - 设置 Push Button 的状态,
207 * 其第三个参数 wParam 决定按钮的状态
208 * BST_PUSHED - 已按下
209 * BST_UNCHECKED - 未按下
210 *******************************************************/
211 break;
212 case BST_UNCHECKED:
213 SendMessage(hBtnO, BM_SETSTATE, BST_PUSHED, 0);
214 break;
215 default:
216 goto onNothing;
217 }
218 break;
219 default:
220 goto onNothing;
221 }
222 break;
223
224 case BTN_COMMNADLINK: //命令链接按钮
225 switch (wmEvent) {
226 case BN_CLICKED: // 单击事件。
227 MessageBox(hWnd, _T("Hi, You clicked the default command button"), szTitle, MB_OK);
228 break;
229 default:
230 goto onNothing;
231 }
232 break;
233
234
235 case BTN_CHECKBOX: //二态复选框的事件
236 switch (wmEvent) {
237 case BN_CLICKED:
238 switch (SendMessage(hCtl, BM_GETCHECK, 0, 0)) {
239 /*******************************************************
240 * BM_GETCHECK - 获取单/复选框选中状态
241 * 其返回值可取如下:
242 * BST_CHECKED - 已选中状态
243 * BST_UNCHECKED - 未选中状态
244 * BST_INDETERMINATE - 默认选中状态(三态复选框支持)
245 *******************************************************/
246 case BST_CHECKED:
247 SendMessage(hCtl, BM_SETCHECK, BST_UNCHECKED, 0); //设置为灰色钩
248 /*******************************************************
249 * BM_SETCHECK - 设置单/复选框选中状态
250 * 其第三个参数 wParam 可取如下值作为单/复选框的选中状态:
251 * BST_CHECKED - 已选中状态
252 * BST_UNCHECKED - 未选中状态
253 * BST_INDETERMINATE - 默认选中状态(三态复选框支持)
254 *******************************************************/
255 break;
256 case BST_UNCHECKED: //未选中时
257 SendMessage(hCtl, BM_SETCHECK, BST_CHECKED, 0);
258 break;
259 default:
260 goto onNothing;
261 }
262 break;
263 case BN_SETFOCUS:
264 /*******************************************************
265 * BN_SETFOCUS - 获取焦点通知
266 * 当一个按钮具有 BS_NOTIFY 时,如果获得了焦点,会收到此
267 * 通知消息。
268 *******************************************************/
269 SetWindowText(hCtl, _T("With Focus."));
270 break;
271 case BN_KILLFOCUS:
272 /*******************************************************
273 * BN_KILLFOCUS - 失去焦点通知
274 * 当一个按钮具有 BS_NOTIFY 时,如果失去了焦点,会收到此
275 * 通知消息。
276 *******************************************************/
277 SetWindowText(hCtl, _T("Without Focus."));
278 break;
279 default:
280 goto onNothing;
281 }
282 break;
283
284 case BTN_3STATECHECKBOX: //三态复选框的事件
285 switch (wmEvent) {
286 case BN_CLICKED:
287 switch (SendMessage(hCtl, BM_GETCHECK, 0, 0)) {
288 case BST_CHECKED: // 选中时
289 SendMessage(hCtl, BM_SETCHECK, BST_INDETERMINATE, 0); // 设置为灰色钩
290 break;
291 case BST_UNCHECKED: // 未选中时
292 SendMessage(hCtl, BM_SETCHECK, BST_CHECKED, 0); // 设置为选中
293 break;
294 case BST_INDETERMINATE: //灰色钩子时,这个灰色钩子必须有 BS_AUTO3STATE 的样式
295 SendMessage(hCtl, BM_SETCHECK, BST_UNCHECKED, 0); // 设置为未选中
296 break;
297 default:
298 goto onNothing;
299 }
300 break;
301 default:
302 goto onNothing;
303 }
304 break;
305
306 case BTN_RADIOBOX: //单选框的事件
307 switch (wmEvent) {
308 case BN_CLICKED:
309 switch (SendMessage(hCtl, BM_GETCHECK, 0, 0)) {
310 case BST_CHECKED: // 选中时
311 SendMessage(hCtl, BM_SETCHECK, BST_UNCHECKED, 0); // 设置为灰色钩
312 break;
313 case BST_UNCHECKED: // 未选中时
314 SendMessage(hCtl, BM_SETCHECK, BST_CHECKED, 0); // 设置为选中
315 break;
316 default:
317 goto onNothing;
318 }
319 break;
320 default:
321 goto onNothing;
322 }
323 break;
324
325 default:
326 goto onNothing;
327 }
328 // 分析菜单选择:
329 break;
330 case WM_DESTROY:
331 PostQuitMessage(0);
332 break;
333 default:
334 goto onNothing;
335 }
336 return 0;
337onNothing:
338 return DefWindowProc(hWnd, uMsg, wParam, lParam);
339}
340
341//[F] 设置字体
342void SetFont(HWND hWndDst) {
343 PostMessage(hWndDst, WM_SETFONT, (WPARAM)hForeFont, 1);
344}
345
346//[G] 创建按钮控件
347HWND CreateButton(DWORD dwStyle, LPCTSTR pTitle, HWND hParent, INT x, INT y, INT width, INT height, WORD wID) {
348 HWND hTmp;
349 if (hTmp = CreateWindowEx(NULL, WC_BUTTON, pTitle, BS_NOTIFY|WS_TABSTOP|WS_CHILD|WS_VISIBLE| dwStyle, x, y, width, height, hParent, (HMENU)wID, hInst, NULL))
350 SetFont(hTmp);
351
352 return hTmp;
353}
354
355/* File End */
comments powered by Disqus