Windows 标准控件:按钮控件的使用
该文章迁移自作者的旧博客站点。
源地址:http://fenying.blog.163.com/blog/static/102055993201162092619233/。
源地址:http://fenying.blog.163.com/blog/static/102055993201162092619233/。
本文展示 Windows 标准控件之按钮控件的使用方法。
以下程序在 Windows 7 简体中文破解版、Visual C++ 2008 专业版、Windows 7 SDK 环境下编译通过。
/* File Begin */
// wTest.cpp : 定义应用程序的入口点。
// This is a Win32 Application C Project.
// Author: Fenying
// Time: 2011-07-20
// Version: 0.0.0.1
// (C) Maple Knights & Fenying Studio Reserved.
// Description: Windows 7 Ultimate SP1 & Visual C++ 2008 Pro & Windows 7 SDK & Win32 Application C Project are required.
#include <tchar.h>
#include <Windows.h>
#include <CommCtrl.h>
#ifdef NULL
#undef NULL
#define NULL 0
#else
#define NULL 0
#endif
//[0] 使用系统主题
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
//[A] 全局变量:
HINSTANCE hInst; // 当前实例
LPCTSTR szTitle; // 标题栏文本
LPCTSTR szWindowClass; // 主窗口类名
HWND hBtnO; // 第一个按钮句柄
HFONT hForeFont; // 默认字体
//[B] 此代码模块中包含的函数的前向声明:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
void SetFont(HWND hWndDst);
HWND CreateButton(DWORD dwStyle, LPCTSTR pTitle, HWND hParent, INT x, INT y, INT width, INT height, WORD wID);
//[C] 宏常量
#define GLOBAL_FORE_FONT_NAME _T("Tahoma")
#define BTN_PUSHBUTTON 1
#define BTN_DEFPUSHBUTTON 2
#define BTN_CHECKBOX 3
#define BTN_AUTOCHECKBOX 4
#define BTN_3STATECHECKBOX 5
#define BTN_AUTO3STATECHECKBOX 6
#define BTN_GROUPBOX 7
#define BTN_RADIOBOX 8
#define BTN_AUTORADIOBOX 9
#define BTN_COMMNADLINK 10
#define BTN_DEFCOMMNADLINK 11
#define BTN_SPLITBUTTON 12
#define BTN_DEFSPLITBUTTON 13
//[D] 主函数
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
MSG msg;
WNDCLASSEX wcex;
HWND hWnd;
// 初始化字符串
szWindowClass = _T("my_wnd_cls");
szTitle = _T("Hello World");
// 初始化默认字体
hForeFont = CreateFontW(14,0,0,0,0,0,0,0,DEFAULT_CHARSET,0,0,0,0, GLOBAL_FORE_FONT_NAME);
// 注册窗口类
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = NULL;
RegisterClassEx(&wcex);
// 创建窗体
hInst = hInstance; // 将实例句柄存储在全局变量中
hWnd = CreateWindow(szWindowClass, szTitle, WS_TABSTOP|WS_OVERLAPPEDWINDOW, 200, 0, 800, 600, NULL, NULL, hInstance, NULL);
if (!hWnd) {
MessageBox(NULL,_T("Failed to create a window."), szTitle, MB_OK);
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// 主消息循环:
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
//[E] 消息回调函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
int wmId, wmEvent;
HWND hCtl;
switch (uMsg) {
case WM_CREATE: // 当窗体被创建时
// 创建一个标准命令按钮 Push Button
hBtnO = CreateButton(BS_PUSHBUTTON, _T("Button"), hWnd, 50, 50, 200, 32, BTN_PUSHBUTTON);
// 创建一个缺省标准命令按钮 Default Push Button
CreateButton(BS_DEFPUSHBUTTON, _T("Default Button"), hWnd, 50, 85, 200, 32, BTN_DEFPUSHBUTTON);
// 创建一个二态复选框 CheckBox,其被单击时不会自动改变选择状态
CreateButton(BS_CHECKBOX, _T("CheckBox"), hWnd, 50, 120, 200, 24, BTN_CHECKBOX);
// 创建一个二态自动复选框 Auto CheckBox,其被单击时会自动改变选择状态
CreateButton(BS_AUTOCHECKBOX, _T("Auto CheckBox"), hWnd, 50, 150, 200, 24, BTN_AUTOCHECKBOX);
// 创建一个三态复选框 3 State CheckBox,其被单击时不会自动改变选择状态
CreateButton(BS_3STATE, _T("3 State CheckBox"), hWnd, 50, 180, 200, 24, BTN_3STATECHECKBOX);
// 创建一个三态自动复选框 Auto 3 State CheckBox,其被单击时会自动改变选择状态
CreateButton(BS_AUTO3STATE, _T("Auto 3 State CheckBox"), hWnd, 50, 210, 200, 24, BTN_AUTO3STATECHECKBOX);
// 创建一个组合框 Group Box
CreateButton(BS_GROUPBOX, _T("Group Box"), hWnd, 50, 240, 200, 100, BTN_GROUPBOX);
// 创建一个单选框 Radio Box,其被单击时不会自动改变选择状态
CreateButton(BS_RADIOBUTTON, _T("Radio Box"), hWnd, 50, 350, 200, 24, BTN_RADIOBOX);
// 创建一个自动单选框 Auto Radio Box,其被单击时会自动改变选择状态
CreateButton(BS_AUTORADIOBUTTON, _T("Auto Radio Box"), hWnd, 50, 380, 200, 24, BTN_AUTORADIOBOX);
// 创建一个自动单选框 Auto Radio Box,其被单击时会自动改变选择状态
CreateButton(BS_AUTORADIOBUTTON, _T("Auto Radio Box"), hWnd, 50, 410, 200, 24, BTN_AUTORADIOBOX);
// Windows Vista Required.
#if _WIN32_WINNT >= 0x600
// 创建一个命令链接按钮 Command Link
CreateButton(BS_COMMANDLINK, _T("Command Link"), hWnd, 300, 50, 200, 48, BTN_COMMNADLINK);
// 创建一个缺省命令链接按钮 Def Command Link
CreateButton(BS_DEFCOMMANDLINK, _T("Def Command Link"), hWnd, 300, 100, 200, 48, BTN_DEFCOMMNADLINK);
// 创建一个分割按钮 Split Button
CreateButton(BS_SPLITBUTTON, _T("Split Button"), hWnd, 300, 150, 200, 48, BTN_SPLITBUTTON);
// 创建一个缺省分割按钮 Def Split Button
CreateButton(BS_DEFSPLITBUTTON, _T("Def Split Button"), hWnd, 300, 200, 200, 48, BTN_DEFSPLITBUTTON);
#endif
//
break;
case WM_COMMAND: //控件事件
hCtl = (HWND)lParam;
wmId = LOWORD(wParam); // wParam 的低字表示控件标识,即 CreateWindowEx 函数的 hMenu 参数
wmEvent = HIWORD(wParam); // wParam 的高字表示控件事件
if (lParam)
switch (wmId) {
case BTN_PUSHBUTTON: //命令按钮的事件
switch (wmEvent) {
case BN_CLICKED: // 单击事件。
/*******************************************************
* 单击事件消息。
*******************************************************/
MessageBox(hWnd, _T("Hi, You clicked the command button"), szTitle, MB_OK);
break;
case BN_DOUBLECLICKED:
/*******************************************************
* 双击事件消息。
* 此消息不能和 BN_CLICKED 同时处理,否则无法接收此消息。
* BS_USERBUTTON, BS_RADIOBUTTON, BS_OWNERDRAW 三种按钮可
* 以自动支持此消息,其他按钮必须添加 BS_NOTIFY 样式。
*******************************************************/
MessageBox(hWnd, _T("Hi, You double clicked the command button"), szTitle, MB_OK);
break;
default:
goto onNothing;
}
break;
case BTN_DEFPUSHBUTTON: //缺省命令按钮的事件
switch (wmEvent) {
case BN_CLICKED: // 单击事件。
switch (SendMessage(hBtnO, BM_GETSTATE, 0, 0)) {
/*******************************************************
* BM_GETSTATE - 获取 Push Button 的状态,
* 返回值取如下值:
* BST_PUSHED - 已按下
* BST_UNCHECKED - 未按下
*******************************************************/
case BST_PUSHED:
SendMessage(hBtnO, BM_SETSTATE, BST_UNCHECKED, 0);
/*******************************************************
* BM_SETSTATE - 设置 Push Button 的状态,
* 其第三个参数 wParam 决定按钮的状态
* BST_PUSHED - 已按下
* BST_UNCHECKED - 未按下
*******************************************************/
break;
case BST_UNCHECKED:
SendMessage(hBtnO, BM_SETSTATE, BST_PUSHED, 0);
break;
default:
goto onNothing;
}
break;
default:
goto onNothing;
}
break;
case BTN_COMMNADLINK: //命令链接按钮
switch (wmEvent) {
case BN_CLICKED: // 单击事件。
MessageBox(hWnd, _T("Hi, You clicked the default command button"), szTitle, MB_OK);
break;
default:
goto onNothing;
}
break;
case BTN_CHECKBOX: //二态复选框的事件
switch (wmEvent) {
case BN_CLICKED:
switch (SendMessage(hCtl, BM_GETCHECK, 0, 0)) {
/*******************************************************
* BM_GETCHECK - 获取单/复选框选中状态
* 其返回值可取如下:
* BST_CHECKED - 已选中状态
* BST_UNCHECKED - 未选中状态
* BST_INDETERMINATE - 默认选中状态(三态复选框支持)
*******************************************************/
case BST_CHECKED:
SendMessage(hCtl, BM_SETCHECK, BST_UNCHECKED, 0); //设置为灰色钩
/*******************************************************
* BM_SETCHECK - 设置单/复选框选中状态
* 其第三个参数 wParam 可取如下值作为单/复选框的选中状态:
* BST_CHECKED - 已选中状态
* BST_UNCHECKED - 未选中状态
* BST_INDETERMINATE - 默认选中状态(三态复选框支持)
*******************************************************/
break;
case BST_UNCHECKED: //未选中时
SendMessage(hCtl, BM_SETCHECK, BST_CHECKED, 0);
break;
default:
goto onNothing;
}
break;
case BN_SETFOCUS:
/*******************************************************
* BN_SETFOCUS - 获取焦点通知
* 当一个按钮具有 BS_NOTIFY 时,如果获得了焦点,会收到此
* 通知消息。
*******************************************************/
SetWindowText(hCtl, _T("With Focus."));
break;
case BN_KILLFOCUS:
/*******************************************************
* BN_KILLFOCUS - 失去焦点通知
* 当一个按钮具有 BS_NOTIFY 时,如果失去了焦点,会收到此
* 通知消息。
*******************************************************/
SetWindowText(hCtl, _T("Without Focus."));
break;
default:
goto onNothing;
}
break;
case BTN_3STATECHECKBOX: //三态复选框的事件
switch (wmEvent) {
case BN_CLICKED:
switch (SendMessage(hCtl, BM_GETCHECK, 0, 0)) {
case BST_CHECKED: // 选中时
SendMessage(hCtl, BM_SETCHECK, BST_INDETERMINATE, 0); // 设置为灰色钩
break;
case BST_UNCHECKED: // 未选中时
SendMessage(hCtl, BM_SETCHECK, BST_CHECKED, 0); // 设置为选中
break;
case BST_INDETERMINATE: //灰色钩子时,这个灰色钩子必须有 BS_AUTO3STATE 的样式
SendMessage(hCtl, BM_SETCHECK, BST_UNCHECKED, 0); // 设置为未选中
break;
default:
goto onNothing;
}
break;
default:
goto onNothing;
}
break;
case BTN_RADIOBOX: //单选框的事件
switch (wmEvent) {
case BN_CLICKED:
switch (SendMessage(hCtl, BM_GETCHECK, 0, 0)) {
case BST_CHECKED: // 选中时
SendMessage(hCtl, BM_SETCHECK, BST_UNCHECKED, 0); // 设置为灰色钩
break;
case BST_UNCHECKED: // 未选中时
SendMessage(hCtl, BM_SETCHECK, BST_CHECKED, 0); // 设置为选中
break;
default:
goto onNothing;
}
break;
default:
goto onNothing;
}
break;
default:
goto onNothing;
}
// 分析菜单选择:
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
goto onNothing;
}
return 0;
onNothing:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
//[F] 设置字体
void SetFont(HWND hWndDst) {
PostMessage(hWndDst, WM_SETFONT, (WPARAM)hForeFont, 1);
}
//[G] 创建按钮控件
HWND CreateButton(DWORD dwStyle, LPCTSTR pTitle, HWND hParent, INT x, INT y, INT width, INT height, WORD wID) {
HWND hTmp;
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))
SetFont(hTmp);
return hTmp;
}
/* File End */
comments powered by Disqus