0


33_UI子窗口控件多少会一点之按钮类

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_ICONBS_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消息用于获取单选按钮、复选框或三态复选框的选中状态.- wParamlParam参数没有用到,都指定为0即可- 返回值可以是BST_CHECKED (已选中)、BST_UNCHECKED (未选中)或BST_INDETERMINATE(灰色,表示不确定状态,用于三态复选框)。
  • BM_SETSTATE消息用于设置普通按钮是否按下的状态.- wParam参数可以指定为TRUE(突出显示,按下状态)或FALSE(取消突出显示,非按下状态)- lParam参数没有用到,指定为0即可。
  • BM_GETSTATE消息用于获取普通按钮、单选按钮、复选框或三态复选框的当前状态(选中状态,是否按下和是否具有键盘焦点等)- wParamlParam 参数没有用到,都指定为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);}
标签: ui java 开发语言

本文转载自: https://blog.csdn.net/WNX10086/article/details/135632507
版权归原作者 晴城丶 所有, 如有侵权,请联系我们删除。

“33_UI子窗口控件多少会一点之按钮类”的评论:

还没有评论