UI子窗口控件多少会一点之按钮类
调用
CreateWindow()
/
CreateWindowEx()
函数创建窗口的时候,将窗口样式指定为
WS_CHILD
或
WS_CHILDWINDOW
就可以创建一个子窗口。子窗口的位置可以在父窗口客户区的任何地方,这样的子窗口需要程序注册窗口类并提供窗口过程。程序也可以通过系统预定义的窗口类和窗口过程来创建标准子窗口控件,程序中常见的标准子窗口挫件有按钮、单选按钮、复选按钮、编辑框、组合框、列表框、滚动条控件等,像资源管理器窗口就包含多个子窗口控件,例如工具栏、树视图控件、滚动条控件等。标准子窗口控件也称为通用控件(Common Control) 。
创建按钮对象
程序可以把窗口类名指定为系统预定义的
相关子窗口控件类名
来调用
CreateWindow()
/
CreateWindowEx()
函数创建一个子窗口控件(对应形参的
lpClassName
),子窗口控件和父窗口之间可以互相发送消息来进行通信。子窗口控件在对话框程序中用得更普遍,不需要调用
CreateWindow()
/
CreateWindowEx()
函数,直接在资源脚本文件中定义子窗口控件即可,也可以通过资源编辑器从工具箱中拖曳子窗口控件到对话框程序界面的合适位置。
系统预定义的窗口类名字符串含义
- Button按钮(普通按钮、单选按钮、复选按钮、分组框)
- Edit编辑框
- ListBox列表框
- ComboBox组合框ScrollBar滚动条Static静态控件
- MDIClientMDl 客户窗口
另外,有一些类名是系统内部使用的,例如
ComboLBox (多一个L)
表示组合框内的列表框的类名,
#32770
表示对话框类名等。
按钮样式
按钮(Button)类有许多样式属性,基于Button类指定不同的样式可以创建普通按钮、单选按钮、复选按钮和分组框等。Button类可以指定的按钮样式如表所示,BS_前缀表示Button Style.
宏含义
BS_PUSHBUTTON
普通按钮
BS_DEFPUSHBUTTON
默认按钮,和普通按钮一样,但是有一个较深的轮廓。如果是在对话框程序中,当其他按钮没有键盘焦点时,用户可以通过按下Enter键选择该按钮
BS_RADIOBUTTON
单选按钮,可以选中、取消选中
BS_AUTOCHECKBOX
自动单选按钮
BS_RADIOBUTTON
自动复选框
BS_AUTORADIOBUTTON
单选按钮,可以选中、取消选中
BS_CHECKBOX
复选框,可以选中,取消选中。
BS_ATUOCHECKBOX
自动复选框
BS_ATUO3TATE
自动三态复选框
BS_LEFTTEXT或BS_RIGHTBUTTON
对于单选按钮﹑复选框或三态复选框,文本默认显示在按钮右侧,该样式表示显示在按钮左侧
BS_TEXT
按钮矩形内显示文本
BS_LEFT
左对齐按钮矩形内的文本
BS_RIGHT
右对齐按钮矩形内的文本
BS_CENTTER
文本在按钮矩形内水平居中
BS_TOP
文本在按钮矩形的顶部
BS_BOTTOM
文本在按钮矩形的底部
BS_VCENTER
文本在按钮矩形内垂直居中
BS_FLAT
按钮默认具有三维样式,该样式表示按钮是二维样式
BS_PUSHLIKE
使单选按钮、复选框或三态复选框看起来像按钮—样
BS_OWNERDRAW
自绘按钮,当按钮需要重绘时父窗口会收到WM_DRAWITEM消息,不能将该样式与任何其他按钮样式—起使用
BS_ICON
图标按钮
BS_BITMAP
位图按钮
BS_GROUPBOX
分组框,用于对其他控件进行分组,由一个矩形和显示在矩形左上角的文本组成
BS_NOTIFY
系统可以发送包含
BN_KTLLFOCUS
和
BS_SETFOCUS
通知码的WM_COMMAND消息到其父窗口
BS_SPLITBUTTON
拆分按钮。拆分按钮分为两部分,左侧是主要部分,类似于普通或默认按纽﹔右刻有一个向下的小箭头,单击箭头时可以弹出一个菜单。拆分按扭是通用控件版本6中引A的一种出钮,如图所示:
BS_DEFSPLITBUTTON
默认拆分按钮,有一个较深的轮廓。如果是在对话框程序中,当其他按钮没有键盘焦点时,用户可以通过按下Eat er键选择该按钮
BS_COMMANDLTNK
命令链接按钮,左侧有一个篮色箭头指向按钮文本(Windows 7系统中为绿色箭头〉。命令链接按钮是通用控件版本6中引入的一种按钮
下面介绍自动单选按钮、自动复选框和自动三态复选框。以三态复选框与自动三态复选框为例,用户单击三态复选框以后不会自动选中或变灭,程序需要响应单击事件设置选中或变灰状态﹔而如果是自动三态复选框,则单击一次就会自动选中,再单击一次则复选框显示为灰色,第三次单击则会取消选中,如此循环,程序在需要的时候只需要获取其状态即可。
普通按钮、默认按钮、单选按钮和复选框都可以同时指定BS_ICON或BS BITMAP样式,例如
BS_PUSHBUTTON|BS_BITMAP
,或
BS_AUTORADIOBUTTON| BS_BITMAP
,表示在普通按钮上显示一副位图,或单选按钮旁边显示一副位图。
BS_ICON
或
BS_BITMAP
样式也可以单独使用,表示在普通按钮上显示一个图标或一副位图。指定BS_ICON或BS_BITMAP样式以后,需要发送BM_SETIMAGE消息为其设置图标或位图,后面再详细解释这个消息。
BS_前缀的样式是按钮专用样式。除了这些按钮专用样式,因为子窗口控件也是一个窗口,所以大部分用于普通窗口的API函数和窗口样式适用于子窗口控件。例如下表的窗口样式可以用于按钮。
宏含义
WS_CHILD
或
WS_CHILDWINDOW
窗口是子窗口
WS_VISIBLE
WS_VISABLE
窗口最初可见,可以通过调用
ShowWindow()
或
SetWindowPos()
函数显示和隐藏窗口
WS_GROUP
WS_GROUP
该窗口是一组控件的第一个控件,该组由第一个具有WS_GROUP样式的控件和在其后定义的所有控件组成,直到下一个具有
WS_GROUP
样式的控件(不包括该控件)出现。如果是在对话框程序中,用户可以使用方向键将键盘焦点从组中的一个控件移动到下一个控件。另外,每个组中的第一个控件通常具有
WS_TABSTOP
样式,如果是在对话框程序中,按下Tab键可以将键盘焦点移动到下一个具有
WS_TABSTOP
样式的按件。
WS_TABSTOP
该窗口是一个控件,当用户按下Tab键时,该控件可以接收键盘焦点,如果是在对话框程序中,按下Tab键可以将键盘焦点移动到下一个具有
WS_TABSTOP
样式的控件上
WS_BORDER
窗口有一个细线边框
WS_DLGFRAME
窗口具有对话框样式的边框
WS_SIZEBOX
或
WS_THICKFRAME
窗口具有大小调整边框
WS_DISABLED
窗口最初被禁用,禁用的窗口无法接收用户的输入,要想启用可以调用
EnableWindow()
函数
其中,
WS_CHILD
和
WS_VISIBLE
是必须指定的,
WS_CHILD
表示该窗口是一个子窗口。如果不指定
WS_VISIBLE
样式,则子窗口控件不会显示。
另外,一些扩展窗口样式也可以用于子窗口控件,例如
WS_EX_ACCEPTFILES
表示该子窗口控件可以接受拖放文件。
按钮与父窗口通信
按钮可以向其父窗口发送消息,父窗口也可以向按钮发送消息。父窗口可以通过调用
SendMessage()
或
SendDlgltemMessage()
函数发送消息到子窗口控件∶
LRESULT SendMessage(HWND hWnd, UINT Msg,WPARAM wParam,LPARAM lParam);
LRESULT SendDIgItemMessage(HWND hDIg,int nIDDIgltem, UINT Msg, WPARAM wParam,LPARAM lParam);
SendDlgltemMessage()
函数的hDlg
指的是Dialog对话框,该函数通常用于在对话框程序中向子窗口控件发送消息,但是也可以在普通重叠窗口中向子窗口控件发送消息。hDlg
参数指定父窗口句柄,nIDDIgltem
参数指定子窗口控件ID,每个子窗口控件都有一个ID。调用CreateWindow/CreateWindowEx
函数创建子窗口控件的时候,第10个参数hMenu
不再指定为菜单句柄,而是指定为子窗口控件ID。- 对于
BS_ICON
或BS_BITMAP
样式的按钮,BM_SETIMAGE
消息用于为按钮设置图标或位图。- 其中wParam
参数指定图像类型,可以是IMAGE_ICON(图标)或IMAGE_BITMAP(位图),-lParam
参数可以指定为图像的句柄(HICON或HBITMAP),-返回值
是先前与按钮关联的图像的句柄(如果有的话),否则返回值是NULL ; BM_GETIMAGE
消息用于获取与按钮关联的图标或位图的句柄.- 其中wParam
参数指定图像类型,可以是IMAGE_ICON(图标)或IMAGE_BITMAP(位图)-lParam
参数没有用到,指定为0即可。-返回值
是与按钮关联的图像的句柄(如果有的话),否则返回值是NULL。BM_SETSTYLE
消息用于设置按钮的样式.- 其中wParam
参数可以指定为按钮新样式的组合-lParam
参数可以指定为TRUE(重绘按钮)或FALSE(不重绘按钮)。当然,通过调用SetWindowLongPtr()
函数也可以达到同样的目的。BM_SETCHECK
消息用于设置单选按钮、复选框或三态复选框的选中状态.- 其中wParam
参数可以指定为BST_CHECKED (选中)、BST_UNCHECKED (取消选中)或BST_INDETERMINATE(灰色,表示不确定状态,用于三态复选框)-lParam
参数没有用到,指定为0即可。BM_GETCHECK
消息用于获取单选按钮、复选框或三态复选框的选中状态.-wParam
和lParam
参数没有用到,都指定为0即可-返回值
可以是BST_CHECKED (已选中)、BST_UNCHECKED (未选中)或BST_INDETERMINATE(灰色,表示不确定状态,用于三态复选框)。BM_SETSTATE
消息用于设置普通按钮是否按下的状态.-wParam
参数可以指定为TRUE(突出显示,按下状态)或FALSE(取消突出显示,非按下状态)-lParam
参数没有用到,指定为0即可。BM_GETSTATE
消息用于获取普通按钮、单选按钮、复选框或三态复选框的当前状态(选中状态,是否按下和是否具有键盘焦点等)-wParam
和lParam
参数没有用到,都指定为0即可.- 返回值可以是BST_CHECKED (已选中)、BST_UNCHECKED(未选中)、BST_INDETERMINATE(灰色,表示不确定状态,用于三态复选框)、BST_PUSHED(普通按钮处于按下状态)、BST_FOCUS(按钮具有键盘焦点)、 BST_HOT(鼠标悬停在按钮上)、BST_DROPDOWNPUSHED(按钮处于下拉状态,并且仅当按钮具有BTNS_DROPDOWN样式时用于工具栏按钮)。BM_CLICK
消息可以模拟用户单击按钮-lParam
参数都没有用到。该消息会导致系统向按钮的父窗口发送包含BN_CLICKED通知码的WM_COMMAND消息。- 调用
CheckDlgButton()
或CheckRadioButton()
函数等同于发送BM_SETCHECK消息 - 调用
IsDlgButtonChecked()
函数等同于发送BM_GETCHECK消息
BOOL CheckDlgButton(
_In_ HWND hDIg,//父窗口句柄
_In_ int nIDButton,//子窗口控件ID
_In_ UINTuCheck //设置选中状态,BST_CHECKED BST_UNCHECKED或BST_INDETERMINATE);
BOOL CheckRadioButton(
_In_ HWND hDlg,//父窗口句柄
_In_ int nlDFirstButton,//组中第一个单选按钮的ID
_In_ int nlDLastButton,//组中最后一个单选按钮的ID
_ln_ int nlDCheckButton //要设置选中的单选按钮的ID);
UINT IsDlgButtonChecked(
_In_ HWND hDlg,//父窗口句柄
_In_ int nlDButton //子窗口控件ID,);//函数返回值可以是BST_CHECKED BST_UNCHECKED或BST_INDETERMINATE
一组复选按钮中通常可以同时选中多个,而一组单选按钮中通常只能选中一个。
CheckDlgButton()
函数通常用于设置复选框的选中状态。
CheckDlgButton()
函数也可以用于设置单选按钮,但是如果在一组单选按钮中选中一个,还需要多次调用
CheckDlgButton()
取消选中其他的,所以设置单选按钮的状态通常使用
CheckRadioButton()
函数,指定一组单选按钮的第一个和最后一个以及需要选中哪一个,函数会自动完成任务。
建议使用自动单选按钮,同组的单选按钮会随着用户选中一个而自动取消选中其他单选按钮。在程序中只需要在初始化的时候设置选中哪一个,并在需要查用户选择了哪一个的时候调用
lsDlgButtonChecked()
函数检查每一个单选按钮项的选中状态即可。
同样,复选按钮也不会因为用户的单击而自动变为选中或取消选中等,因此建议使用自动复选按钮,在初始化的时候设置选中哪些,并在需要的时候调用
lsDlgButtonChecked()
函数检查每一个的状态即可。
当用户单击按钮时,它会接收键盘焦点,系统会向按钮的父窗口发送包含
BN_CLICKED
通知码的
WM_COMMAND
消息。不过对于自动单选按钮、自动复选框或自动三态复选框通常不需要处理该消息,因为这些按钮可以自动设置其状态。如果是普通按钮,则可能需要处理该消息。
下表再次列出
WM_COMMAND
消息的
wParam
和
IParam
参数的含义。
HIWORD (wParam)
LOWORD (wParam)
HWND(lParam)
菜单命今ID
比如说,
ID_MEUN
菜单项ID,比如说,记事本程序的打开菜单项ID
IDM_FILE_OPEN
,保存菜单项
IDM_FILE_SAVE
0加速键(快捷键)菜单项ID,同上0子窗口控件通知码,比如说
BN_CLICKED
按钮比点击了。控件ID,比如说按钮控件的ID
ID_BUTTON
控件句柄
通知码,可以类比QT中的发出的信号。
// 为按钮绑定事件 connect(信号的发送者,发送的信号,信号的接受者,处理的函数(槽函数))connect(btn,&QPushButton::clicked, this,&QWidget::close);
BN_SETFOCUS
: 按钮获得了键盘焦点
BN_KILLFOCUS
:按钮失去了键盘焦点
BN_DBLCLK
或
BN_DOUBLECLICKED
:双击按钮
获得键盘焦点的按钮周围会显示一圈虚线,此时按下空格键就相当于单击了按钮。只有具有
BS_NOTIFY
样式的按钮会发送
BN_SETFOCUS
BN_KILLFOCUS
和
BN_DBLCLK
通知码,但是无论如何设置按钮样式,单击按钮都会发送
BN_CLICKED
通知码。
BS_GROUPBOX
样式表示分组框,用于对其他控件进行分组,由一个矩形和显示在矩形左上角的文本组成。分组框不会获得键盘焦点,既不处理鼠标或键盘输入,也不会导致系统发送
WM_COMMAND
消息到父窗口。
对于自绘按钮、组合框和列表框等,程序只需要在必要的时候负责绘制它们的外观即可,系统会正常处理用户和这些控件的交互,例如用户单击控件,系统会向父窗口发送
WM_COMMAND
消息。在介绍自绘菜单的时候说过,
WM_DRAWITEM
消息既用于菜单项,也用于其他些子窗口控件的自绘,当菜单项或子窗口控件需要自绘的时候,窗口过程会收到WM_DRAWITEM消息。
如果WM_DRAWITEM消息是由子窗口控件发送的,则
wParam
参数是子窗口控件的ID
如果是由菜单项发送的,则
wParam
参数为0。
lParam
参数是一个指向
DRAWITEMSTRUCT
结构的指
针.
typedefstructtagDRAWITEMSTRUCT{
UINT ctlType;//控件类型,如果是ODT_MENU,表示菜单项
UINT CtlID;//该字段不用于菜单项
UINT itemID;//菜单项ID
UINT itemAction;//所需的绘制操作
UINT itemState;//新的状态
HWND hwndItem;//菜单句柄
HDC hDC;//设备环境句柄
RECT rcItem;//绘制区域
ULONG_PTR itemData;//程序自定义数据,最初由MENUITEMINFO结构的dwltemData指定的}DRAWITEMSTRUCT,NEAR *PDRAWITEMSTRUCT,FAR *LPDRAWITEMSTRUCT;
接下来实现一个例子,Buttons程序在窗口客户区中使用系统预定义的Button类调用
CreateWindowEx()
函数分别创建了普通按钮、图标按钮、位图按钮、自绘按钮、一组自动单选按钮、一组自动复选按钮、一组自动三态复选按钮、默认按钮。
- resource.h
//{{NO_DEPENDENCIES}}// Microsoft Visual C++ 生成的包含文件。// 供 Buttons.rc 使用//#defineIDB_KONGLONG101#defineIDI_SMILE102#defineIDC_PUSHBUTTON1000#defineIDC_ICONBUTTON1001#defineIDC_BITMAPBUTTON1002#defineIDC_OWNERDRAWBUTTON1003#defineIDC_GROUPBOX11004#defineIDC_AUTORADIOBUTTON11005#defineIDC_AUTORADIOBUTTON21006#defineIDC_AUTORADIOBUTTON31007#defineIDC_GROUPBOX21008#defineIDC_AUTOCHECKBOX11009#defineIDC_AUTOCHECKBOX21010#defineIDC_AUTOCHECKBOX31011#defineIDC_GROUPBOX31012#defineIDC_AUTO3STATE11013#defineIDC_AUTO3STATE21014#defineIDC_AUTO3STATE31015#defineIDC_DEFPUSHBUTTON1016// Next default values for new objects// #ifdefAPSTUDIO_INVOKED#ifndefAPSTUDIO_READONLY_SYMBOLS#define_APS_NEXT_RESOURCE_VALUE103#define_APS_NEXT_COMMAND_VALUE40001#define_APS_NEXT_CONTROL_VALUE1017#define_APS_NEXT_SYMED_VALUE101#endif#endif
#include<Windows.h>#include<tchar.h>#include<strsafe.h>#include"resource.h"// 函数声明
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);// 按下默认按钮
VOID OnDefPushButton(HWND hwnd);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow){
WNDCLASSEX wndclass;
TCHAR szAppName[]=TEXT("Buttons");// 程序标题、窗口类名
HWND hwnd;
MSG msg;
wndclass.cbSize =sizeof(WNDCLASSEX);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WindowProc;
wndclass.cbClsExtra =0;
wndclass.cbWndExtra =0;
wndclass.hInstance = hInstance;
wndclass.hIcon =LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor =LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName =NULL;
wndclass.lpszClassName = szAppName;
wndclass.hIconSm =NULL;RegisterClassEx(&wndclass);
hwnd =CreateWindowEx(0, szAppName, szAppName, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,300,600,NULL,NULL, hInstance,NULL);ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);while(GetMessage(&msg,NULL,0,0)!=0){TranslateMessage(&msg);DispatchMessage(&msg);}return msg.wParam;}// 全局变量struct{int m_nStyle;
PTSTR m_pText;}Buttons[]={
BS_PUSHBUTTON | BS_NOTIFY | WS_TABSTOP,TEXT("普通按钮"),// CtrlID 1000
BS_ICON | BS_NOTIFY | WS_TABSTOP,TEXT("图标按钮"),
BS_BITMAP | BS_NOTIFY | WS_TABSTOP,TEXT("位图按钮"),
BS_OWNERDRAW,TEXT("自绘按钮"),
BS_GROUPBOX,TEXT("政治面貌"),// CtrlID 1004
BS_AUTORADIOBUTTON | BS_NOTIFY | WS_GROUP | WS_TABSTOP,TEXT("中共党员"),
BS_AUTORADIOBUTTON | BS_NOTIFY,TEXT("共青团员"),
BS_AUTORADIOBUTTON | BS_NOTIFY,TEXT("无党派人士"),
BS_GROUPBOX,TEXT("个人爱好"),// CtrlID 1008
BS_AUTOCHECKBOX | BS_NOTIFY | WS_GROUP | WS_TABSTOP,TEXT("看书"),
BS_AUTOCHECKBOX | BS_NOTIFY,TEXT("唱歌"),
BS_AUTOCHECKBOX | BS_NOTIFY,TEXT("听音乐"),
BS_GROUPBOX,TEXT("荣誉称号"),// CtrlID 1012
BS_AUTO3STATE | BS_NOTIFY | WS_GROUP | WS_TABSTOP,TEXT("团队核心"),
BS_AUTO3STATE | BS_NOTIFY,TEXT("技术能手"),
BS_AUTO3STATE | BS_NOTIFY,TEXT("先进个人"),
BS_DEFPUSHBUTTON | BS_NOTIFY | WS_TABSTOP,TEXT("默认按钮"),// CtrlID 1016};#defineNUM(sizeof(Buttons)/sizeof(Buttons[0]))
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){static HWND hwndButton[NUM];// 子窗口控件句柄数组int arrPos[NUM]={10,40,70,100,// 每个子窗口控件的起始Y坐标130,150,180,210,250,270,300,330,370,390,420,450,490};
LPDRAWITEMSTRUCT lpDIS;if(WM_CREATE == uMsg){for(int i =0; i < NUM; i++){// 创建17个子窗口控件
hwndButton[i]=::CreateWindowEx(0,TEXT("Button"),
Buttons[i].m_pText,
WS_CHILD | WS_VISIBLE | Buttons[i].m_nStyle,20, arrPos[i],150,25,
hwnd,(HMENU)(1000+ i),((LPCREATESTRUCT)lParam)->hInstance,NULL);}// 移动3个分组框的位置::MoveWindow(hwndButton[4],10, arrPos[4],170,115, TRUE);::MoveWindow(hwndButton[8],10, arrPos[8],170,115, TRUE);::MoveWindow(hwndButton[12],10, arrPos[12],170,115, TRUE);// 为图标按钮、位图按钮设置图标、位图
HANDLE hImage =::LoadImage(((LPCREATESTRUCT)lParam)->hInstance,MAKEINTRESOURCE(IDI_SMILE), IMAGE_ICON,20,20, LR_DEFAULTCOLOR);//根据resourceID 查图片句柄::SendDlgItemMessage(hwnd, IDC_ICONBUTTON, BM_SETIMAGE, IMAGE_ICON,(LPARAM)hImage);//给按钮设置图标
HBITMAP hBitMap =::LoadBitmap(((LPCREATESTRUCT)lParam)->hInstance,MAKEINTRESOURCE(IDB_KONGLONG));// 根据resourceID 查位图句柄::SendDlgItemMessage(hwnd, IDC_BITMAPBUTTON, BM_SETIMAGE, IMAGE_BITMAP,(LPARAM)hBitMap);//给按钮设置位图// 设置默认按钮的文本::SetDlgItemText(hwnd, IDC_DEFPUSHBUTTON,TEXT("获取单选复选状态"));// 单选按钮组、复选按钮组、三态复选按钮组,默认情况下分别选中一项::CheckRadioButton(hwnd, IDC_AUTORADIOBUTTON1, IDC_AUTORADIOBUTTON3, IDC_AUTORADIOBUTTON2);::CheckDlgButton(hwnd, IDC_AUTOCHECKBOX3, BST_CHECKED);::CheckDlgButton(hwnd, IDC_AUTO3STATE2, BST_INDETERMINATE);return0;}elseif(WM_COMMAND == uMsg){if(HIWORD(wParam)== BN_CLICKED){// 子窗口控件ID常量定义请参见resource.h,可以根据需要在此处理每个控件的点击事件if(LOWORD(wParam)== IDC_PUSHBUTTON){}elseif(LOWORD(wParam)== IDC_ICONBUTTON){}elseif(LOWORD(wParam)== IDC_BITMAPBUTTON){}elseif(LOWORD(wParam)== IDC_OWNERDRAWBUTTON){}elseif(LOWORD(wParam)== IDC_AUTORADIOBUTTON1){}elseif(LOWORD(wParam)== IDC_AUTORADIOBUTTON2){}elseif(LOWORD(wParam)== IDC_AUTORADIOBUTTON3){}elseif(LOWORD(wParam)== IDC_AUTOCHECKBOX1){}elseif(LOWORD(wParam)== IDC_AUTOCHECKBOX2){}elseif(LOWORD(wParam)== IDC_AUTOCHECKBOX3){}elseif(LOWORD(wParam)== IDC_AUTO3STATE1){}elseif(LOWORD(wParam)== IDC_AUTO3STATE2){}elseif(LOWORD(wParam)== IDC_AUTO3STATE3){}elseif(LOWORD(wParam)== IDC_DEFPUSHBUTTON){OnDefPushButton(hwnd);}}return0;}elseif(WM_DRAWITEM == uMsg){//按钮重绘
lpDIS =(LPDRAWITEMSTRUCT)lParam;// 先把按钮矩形填充为和窗口背景一致的白色,然后画一个黑色圆角矩形::SelectObject(lpDIS->hDC,GetStockObject(NULL_PEN));::SelectObject(lpDIS->hDC,GetStockObject(WHITE_BRUSH));::Rectangle(lpDIS->hDC,0,0, lpDIS->rcItem.right +1, lpDIS->rcItem.bottom +1);::SelectObject(lpDIS->hDC,GetStockObject(BLACK_BRUSH));::RoundRect(lpDIS->hDC,0,0, lpDIS->rcItem.right +1, lpDIS->rcItem.bottom +1,20,20);// 当用户点击按钮的时候,绘制COLOR_HIGHLIGHT颜色的圆角矩形if(lpDIS->itemState & ODS_SELECTED){SelectObject(lpDIS->hDC,GetSysColorBrush(COLOR_HIGHLIGHT));RoundRect(lpDIS->hDC,0,0, lpDIS->rcItem.right +1, lpDIS->rcItem.bottom +1,20,20);}if(lpDIS->itemState & ODS_FOCUS){::InflateRect(&lpDIS->rcItem,-2,-2);::DrawFocusRect(lpDIS->hDC,&lpDIS->rcItem);}// 自绘按钮的文本,透明背景的白色文字::SetBkMode(lpDIS->hDC, TRANSPARENT);::SetTextColor(lpDIS->hDC,RGB(255,255,255));::DrawText(lpDIS->hDC,TEXT("自绘按钮"),_tcslen(TEXT("自绘按钮")),&lpDIS->rcItem, DT_CENTER | DT_VCENTER | DT_SINGLELINE);// 恢复设备环境::SelectObject(lpDIS->hDC,GetStockObject(BLACK_PEN));::SelectObject(lpDIS->hDC,GetStockObject(WHITE_BRUSH));}elseif(WM_DESTROY == uMsg){PostQuitMessage(0);return0;}return::DefWindowProc(hwnd, uMsg, wParam, lParam);}
VOID OnDefPushButton(HWND hwnd){
TCHAR szBuf[128]={0};//查自动单选按钮 哪一项被选中了if(::IsDlgButtonChecked(hwnd, IDC_AUTORADIOBUTTON1)& BST_CHECKED){::StringCchCopy(szBuf,_countof(szBuf),TEXT("政治面貌:中共党员\n"));}if(::IsDlgButtonChecked(hwnd, IDC_AUTORADIOBUTTON2)& BST_CHECKED){::StringCchCopy(szBuf,_countof(szBuf),TEXT("政治面貌:共青团员\n"));}if(::IsDlgButtonChecked(hwnd, IDC_AUTORADIOBUTTON3)& BST_CHECKED){::StringCchCopy(szBuf,_countof(szBuf),TEXT("政治面貌:无党派人士\n"));}//查自动复选按钮中 哪一个自动复选按钮项被选中了::StringCchCat(szBuf,_countof(szBuf),TEXT("个人爱好:"));if(::IsDlgButtonChecked(hwnd, IDC_AUTOCHECKBOX1)& BST_CHECKED){::StringCchCat(szBuf,_countof(szBuf),TEXT("看书 "));}if(::IsDlgButtonChecked(hwnd, IDC_AUTOCHECKBOX2)& BST_CHECKED){::StringCchCat(szBuf,_countof(szBuf),TEXT("唱歌 "));}if(::IsDlgButtonChecked(hwnd, IDC_AUTOCHECKBOX3)& BST_CHECKED){::StringCchCat(szBuf,_countof(szBuf),TEXT("听音乐"));}::StringCchCat(szBuf,_countof(szBuf),TEXT("\n"));::StringCchCat(szBuf,_countof(szBuf),TEXT("荣誉称号:"));//查 自动三态复选按钮 哪一个自动三态复选按钮被选中了if(::IsDlgButtonChecked(hwnd, IDC_AUTO3STATE1)& BST_CHECKED){::StringCchCat(szBuf,_countof(szBuf),TEXT("团队核心 "));}if(::IsDlgButtonChecked(hwnd, IDC_AUTO3STATE2)& BST_CHECKED){::StringCchCat(szBuf,_countof(szBuf),TEXT("技术能手 "));}if(::IsDlgButtonChecked(hwnd, IDC_AUTO3STATE3)& BST_CHECKED){::StringCchCat(szBuf,_countof(szBuf),TEXT("先进个人"));}::StringCchCat(szBuf,_countof(szBuf),TEXT("\n"));::MessageBox(hwnd, szBuf,TEXT("个人简介汇总"), MB_OK);}
MFC
在MFC中这些类型的按钮都用一个
CButton
类来表示。同样的WIN32的程序我们也可以用MFC来实现。要实现按钮自绘的话,MFC中通过继承CButton来做。
- resource.h
//{{NO_DEPENDENCIES}}// Microsoft Visual C++ 生成的包含文件。// 供 HelloMFC.rc 使用//#defineIDM_ABOUTBOX0x0010#defineIDS_ABOUTBOX101#defineIDB_KONGLONG150#defineIDD_HELLOMFC_DIALOG102#defineIDI_ICON1160#defineIDI_SMILE174#defineIDR_MAINFRAME128#defineIDC_PUSHBUTTON1000#defineIDC_ICONBUTTON1001#defineIDC_BITMAPBUTTON1002#defineIDC_OWNERDRAWBUTTON1003#defineIDC_GROUPBOX11004#defineIDC_AUTORADIOBUTTON11005#defineIDC_AUTORADIOBUTTON21006#defineIDC_AUTORADIOBUTTON31007#defineIDC_GROUPBOX21008#defineIDC_AUTOCHECKBOX11009#defineIDC_AUTOCHECKBOX21010#defineIDC_AUTOCHECKBOX31011#defineIDC_GROUPBOX31012#defineIDC_AUTO3STATE11013#defineIDC_AUTO3STATE21014#defineIDC_AUTO3STATE31015#defineIDC_DEFPUSHBUTTON1016#defineIDC_BUTTON11017// Next default values for new objects// #ifdefAPSTUDIO_INVOKED#ifndefAPSTUDIO_READONLY_SYMBOLS#define_APS_NEXT_RESOURCE_VALUE107#define_APS_NEXT_COMMAND_VALUE40001#define_APS_NEXT_CONTROL_VALUE1032#define_APS_NEXT_SYMED_VALUE101#endif#endif
- HelloMFCDlg.h
#pragmaonce#include<winnt.h>#include<WinUser.h>#include<string>
class COwnderButton;
class CHelloMFCDlg;
class COwnderButton:public CButton
{DECLARE_DYNAMIC(COwnderButton)
public:COwnderButton();~COwnderButton();
protected:
virtual voidDrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
protected:DECLARE_MESSAGE_MAP()
afx_msg voidOnMouseMove(UINT nFlags, CPoint point);
virtual voidPreSubclassWindow();};
class CHelloMFCDlg : public CDialogEx
{
public:CHelloMFCDlg(CWnd* pParent = nullptr);~CHelloMFCDlg();#ifdefAFX_DESIGN_TIMEenum{ IDD = IDD_HELLOMFC_DIALOG };#endif
protected:
virtual voidDoDataExchange(CDataExchange* pDX);
virtual voidPreSubclassWindow();
protected:
HICON m_hIcon;
virtual BOOL OnInitDialog();
afx_msg voidOnSysCommand(UINT nID, LPARAM lParam);
afx_msg voidOnPaint();
afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()
private:
virtual voidPostNcDestroy();
public:
CButton m_pushButton;
CButton m_iconButton;
CButton m_bitmapButton;
COwnderButton m_ownedrawButton;
CStatic m_groupbox1;
CButton m_autoRadioButton1;
CButton m_autoRadioButton2;
CButton m_autoRadioButton3;
CStatic m_groupbox2;
CButton m_autoCheckBox1;
CButton m_autoCheckBox2;
CButton m_autoCheckBox3;
CStatic m_groupbox3;
CButton m_auto3State1;
CButton m_auto3State2;
CButton m_auto3State3;
CButton m_defpushButton;
afx_msg voidOnBnClickedDefpushbutton();};
- HelloMFCDlg.cpp
// HelloMFCDlg.cpp: 实现文件//#include"pch.h"#include"framework.h"#include"HelloMFC.h"#include"HelloMFCDlg.h"#include"afxdialogex.h"#include<strsafe.h>#include<afxcmn.h>#ifdef_DEBUG#definenewDEBUG_NEW#endifBEGIN_MESSAGE_MAP(CHelloMFCDlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_DEFPUSHBUTTON,&CHelloMFCDlg::OnBnClickedDefpushbutton)END_MESSAGE_MAP()
CHelloMFCDlg::CHelloMFCDlg(CWnd* pParent /*=nullptr*/):CDialogEx(IDD_HELLOMFC_DIALOG, pParent){
m_hIcon =AfxGetApp()->LoadIcon(IDR_MAINFRAME);}
CHelloMFCDlg::~CHelloMFCDlg(){//delete[] button;}void CHelloMFCDlg::DoDataExchange(CDataExchange* pDX){
CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_PUSHBUTTON, m_pushButton);DDX_Control(pDX, IDC_ICONBUTTON,m_iconButton);DDX_Control(pDX, IDC_BITMAPBUTTON,m_bitmapButton);DDX_Control(pDX, IDC_OWNERDRAWBUTTON, m_ownedrawButton);DDX_Control(pDX, IDC_AUTORADIOBUTTON1,m_autoRadioButton1);DDX_Control(pDX, IDC_AUTORADIOBUTTON2, m_autoRadioButton2);DDX_Control(pDX, IDC_AUTORADIOBUTTON3, m_autoRadioButton3);DDX_Control(pDX, IDC_AUTOCHECKBOX1, m_autoCheckBox1);DDX_Control(pDX, IDC_AUTOCHECKBOX2, m_autoCheckBox2);DDX_Control(pDX, IDC_AUTOCHECKBOX3, m_autoCheckBox3);DDX_Control(pDX, IDC_AUTO3STATE1,m_auto3State1);DDX_Control(pDX, IDC_AUTO3STATE2, m_auto3State2);DDX_Control(pDX, IDC_AUTO3STATE3, m_auto3State3);DDX_Control(pDX, IDC_DEFPUSHBUTTON,m_defpushButton);DDX_Control(pDX, IDC_GROUPBOX1, m_groupbox1);DDX_Control(pDX, IDC_GROUPBOX2, m_groupbox2);DDX_Control(pDX, IDC_GROUPBOX3, m_groupbox3);}
BOOL CHelloMFCDlg::OnInitDialog(){
CDialogEx::OnInitDialog();SetIcon(m_hIcon, TRUE);SetIcon(m_hIcon, FALSE);//设置17个子窗口控件样式
m_pushButton.SetButtonStyle(WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_NOTIFY | WS_TABSTOP);
m_pushButton.SetWindowText(_T("普通按钮"));
m_iconButton.SetButtonStyle(WS_CHILD | WS_VISIBLE| BS_ICON | BS_NOTIFY | WS_TABSTOP);
m_iconButton.SetWindowText(_T("图标按钮"));
m_bitmapButton.SetButtonStyle(WS_CHILD | WS_VISIBLE | BS_BITMAP | BS_NOTIFY | WS_TABSTOP);
m_bitmapButton.SetWindowText(_T("位图按钮"));
m_ownedrawButton.SetButtonStyle(WS_CHILD | WS_VISIBLE|BS_OWNERDRAW);
m_ownedrawButton.SetWindowText(_T("自绘按钮"));
m_groupbox1.SetWindowText(_T("政治面貌"));
m_autoRadioButton1.SetButtonStyle(WS_CHILD | WS_VISIBLE|BS_AUTORADIOBUTTON | BS_NOTIFY | WS_GROUP | WS_TABSTOP);
m_autoRadioButton1.SetWindowText(_T("中共党员"));
m_autoRadioButton2.SetButtonStyle(WS_CHILD | WS_VISIBLE |BS_AUTORADIOBUTTON | BS_NOTIFY);
m_autoRadioButton2.SetWindowText(_T("共青团员"));
m_autoRadioButton3.SetButtonStyle(WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | BS_NOTIFY);
m_autoRadioButton3.SetWindowText(_T("无党派人士"));
m_groupbox2.SetWindowText(_T("个人爱好"));
m_autoCheckBox1.SetButtonStyle(WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | BS_NOTIFY | WS_GROUP | WS_TABSTOP);
m_autoCheckBox1.SetWindowText(TEXT("看书"));
m_autoCheckBox2.SetButtonStyle(WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | BS_NOTIFY);
m_autoCheckBox2.SetWindowText(TEXT("唱歌"));
m_autoCheckBox3.SetButtonStyle(WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | BS_NOTIFY);
m_autoCheckBox3.SetWindowText(TEXT("听音乐"));
m_groupbox3.SetWindowText(TEXT("荣誉称号"));
m_auto3State1.SetButtonStyle(WS_CHILD | WS_VISIBLE | BS_AUTO3STATE | BS_NOTIFY | WS_GROUP | WS_TABSTOP);
m_auto3State1.SetWindowText(TEXT("团队核心"));
m_auto3State2.SetButtonStyle(WS_CHILD | WS_VISIBLE | BS_AUTO3STATE | BS_NOTIFY);
m_auto3State2.SetWindowText(TEXT("技术能手"));
m_auto3State3.SetButtonStyle(WS_CHILD | WS_VISIBLE | BS_AUTO3STATE | BS_NOTIFY);
m_auto3State3.SetWindowText(TEXT("先进个人"));
m_defpushButton.SetWindowText(TEXT("默认按钮"));//设置按钮的选中状态
m_autoRadioButton1.SetCheck(BST_UNCHECKED);
m_autoRadioButton2.SetCheck(BST_CHECKED);
m_autoRadioButton3.SetCheck(BST_UNCHECKED);
m_autoCheckBox1.SetCheck(BST_UNCHECKED);
m_autoCheckBox2.SetCheck(BST_UNCHECKED);
m_autoCheckBox3.SetCheck(BST_CHECKED);
m_auto3State1.SetCheck(BST_UNCHECKED);
m_auto3State2.SetCheck(BST_INDETERMINATE);
m_auto3State3.SetCheck(BST_UNCHECKED);return TRUE;}void CHelloMFCDlg::OnSysCommand(UINT nID, LPARAM lParam){
CDialogEx::OnSysCommand(nID, lParam);}void CHelloMFCDlg::OnPaint(){if(IsIconic()){
CPaintDC dc(this);SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()),0);int cxIcon =GetSystemMetrics(SM_CXICON);int cyIcon =GetSystemMetrics(SM_CYICON);
CRect rect;GetClientRect(&rect);int x =(rect.Width()- cxIcon +1)/2;int y =(rect.Height()- cyIcon +1)/2;
dc.DrawIcon(x, y, m_hIcon);}else{
CDialogEx::OnPaint();}}
HCURSOR CHelloMFCDlg::OnQueryDragIcon(){return static_cast<HCURSOR>(m_hIcon);}void CHelloMFCDlg::PostNcDestroy(){// TODO: 在此添加专用代码和/或调用基类
delete this;
CDialogEx::PostNcDestroy();}IMPLEMENT_DYNAMIC(COwnderButton, CButton)BEGIN_MESSAGE_MAP(COwnderButton, CButton)ON_WM_MOUSEMOVE()END_MESSAGE_MAP()void COwnderButton::DrawItem(LPDRAWITEMSTRUCT lpDIS){// 先把按钮矩形填充为和窗口背景一致的白色,然后画一个黑色圆角矩形::SelectObject(lpDIS->hDC,GetStockObject(NULL_PEN));::SelectObject(lpDIS->hDC,GetStockObject(WHITE_BRUSH));::Rectangle(lpDIS->hDC,0,0, lpDIS->rcItem.right +1, lpDIS->rcItem.bottom +1);::SelectObject(lpDIS->hDC,GetStockObject(BLACK_BRUSH));::RoundRect(lpDIS->hDC,0,0, lpDIS->rcItem.right +1, lpDIS->rcItem.bottom +1,20,20);// 当用户点击按钮的时候,绘制COLOR_HIGHLIGHT颜色的圆角矩形if(lpDIS->itemState & ODS_SELECTED){SelectObject(lpDIS->hDC,GetSysColorBrush(COLOR_HIGHLIGHT));RoundRect(lpDIS->hDC,0,0, lpDIS->rcItem.right +1, lpDIS->rcItem.bottom +1,20,20);}if(lpDIS->itemState & ODS_FOCUS){::InflateRect(&lpDIS->rcItem,-2,-2);::DrawFocusRect(lpDIS->hDC,&lpDIS->rcItem);}// 自绘按钮的文本,透明背景的白色文字::SetBkMode(lpDIS->hDC, TRANSPARENT);::SetTextColor(lpDIS->hDC,RGB(255,255,255));::DrawText(lpDIS->hDC,TEXT("自绘按钮"),_tcslen(TEXT("自绘按钮")),&lpDIS->rcItem, DT_CENTER | DT_VCENTER | DT_SINGLELINE);// 恢复设备环境::SelectObject(lpDIS->hDC,GetStockObject(BLACK_PEN));::SelectObject(lpDIS->hDC,GetStockObject(WHITE_BRUSH));}void COwnderButton::OnMouseMove(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值
CButton::OnMouseMove(nFlags, point);//MessageBox("鼠标移动到了按钮!");}void COwnderButton::PreSubclassWindow(){}
COwnderButton::COwnderButton(){}
COwnderButton::~COwnderButton(){}void CHelloMFCDlg::PreSubclassWindow(){// TODO: 在此添加专用代码和/或调用基类
CDialogEx::PreSubclassWindow();// 加载位图资源}void CHelloMFCDlg::OnBnClickedDefpushbutton(){// TODO: 在此添加控件通知处理程序代码
TCHAR szBuf[128]={0};if(m_autoRadioButton1.GetCheck()){::StringCchCopy(szBuf,_countof(szBuf),TEXT("政治面貌:中共党员\n"));}if(m_autoRadioButton2.GetCheck()){::StringCchCopy(szBuf,_countof(szBuf),TEXT("政治面貌:共青团员\n"));}if(m_autoRadioButton3.GetCheck()){::StringCchCopy(szBuf,_countof(szBuf),TEXT("政治面貌:无党派人士\n"));}::StringCchCat(szBuf,_countof(szBuf),TEXT("个人爱好:"));if(m_autoCheckBox1.GetCheck()){::StringCchCat(szBuf,_countof(szBuf),TEXT("看书 "));}if(m_autoCheckBox2.GetCheck()){::StringCchCat(szBuf,_countof(szBuf),TEXT("唱歌 "));}if(m_autoCheckBox3.GetCheck()){::StringCchCat(szBuf,_countof(szBuf),TEXT("听音乐"));}::StringCchCat(szBuf,_countof(szBuf),TEXT("\n"));::StringCchCat(szBuf,_countof(szBuf),TEXT("荣誉称号:"));if(m_auto3State1.GetCheck()){::StringCchCat(szBuf,_countof(szBuf),TEXT("团队核心 "));}elseif(m_auto3State2.GetCheck()){::StringCchCat(szBuf,_countof(szBuf),TEXT("技术能手 "));}elseif(m_auto3State3.GetCheck()){::StringCchCat(szBuf,_countof(szBuf),TEXT("先进个人"));}::StringCchCat(szBuf,_countof(szBuf),TEXT("\n"));MessageBox(szBuf,TEXT("个人简介汇总"), MB_OK);}
版权归原作者 晴城丶 所有, 如有侵权,请联系我们删除。