【MFC】学习笔记:按钮控件(Button)

    技术2022-07-12  75

    01.目录

    目录

    01.目录02.按钮控件介绍03.按钮控件分类3.1 命令按钮3.2 单选按钮3.3 复选按钮 04.按钮控件的创建4.1 拖拽方式4.2 重写方式4.2.1 创建函数原型4.2.2 主要成员函数 05.按钮控件实例(借鉴)

    02.按钮控件介绍

    按钮,这应该是用的最多,也是见得最多的一种控件。 各大App,不管有名无名,按钮基本上都是不可或缺的控件之一。 比如:王者荣耀登陆界面的“进入游戏”就是一个按钮,只是给他整的花里胡哨了而已。 下面说说按钮控件的概念:

    控件是一类特殊的窗口,如按钮、文本框之类的,用来将信息传送给用户或获取用户的输入;

    控件都是一些高度封装好的对象,有自己的WM_PAINT处理代码,不必用户自己去重绘控件;

    控件的消息机制:当点击控件等操作发生时,用户不用具体去处理这些鼠标消息,MFC会处理这些最基本的控件上的消息并将其转化为“通知”(Notify),比如点击按钮时不需要用户去处理按钮的ButtonDown消息,而是MFC将这种消息转化为一个BN_CLICKED通知,然后用户只需要响应OnButtonClicked函数即可;

    PS: a. 一般普通消息,如WM_LBUTTONDOWN、WM_PAINT等都是基本的消息,这些消息直接反应了触发消息的事件;

    b. 通知消息是一种特殊的Windows消息,它主要来自控件,虽然触发通知的都是一些基本消息,如BUTTONDOWN等,但Windows将它们转换成控件发出的通知,通知消息直接反应了触发控件的事件;

    控件一般都挂载其它窗口上,因此控件都是其它窗口的子窗口,所以控件有时也叫子窗口控件: i. 父窗口移动控件就会跟着移动; ii. 父窗口被销毁控件也会跟着被销毁; iii. 这些动作都由MFC自动完成;

    03.按钮控件分类

    按钮控件一般分为: 1.命令按钮(Button) 2.单选按钮(Radio Button) 3.复选按钮或者叫复选框(Check Box)

    3.1 命令按钮

    命令按钮就是我们前面多次提到的狭义的按钮控件,用来响应用户的鼠标单击操作,进行相应的处理,它可以显示文本也可以嵌入位图。单选按钮使用时,一般是多个组成一组,组中每个单选按钮 的选中状态具有互斥关系,即同组的单选按钮只能有一个被选中。

    命令按钮是我们最熟悉也是最常用的一种按钮控件。

    3.2 单选按钮

    单选按钮有选中和未选中两种状态,为选中状态时单选按钮中心会出现一个蓝点,以标识选 中状态。

    一个圆圈+一些字(基本样式),当然这个是可以根据风格改的。 软件中 一般很少用默认样式,除了一些工业软件,比如自己公司做的很多软件就是用默认样式。

    3.3 复选按钮

    一般的复选框也是有选中和未选中两种状态,选中时复选框内会增加一个“√”,而三态复选框(设置了BS_3STATE风格)有选中、未选中和不确定三种状态,不确定状态时复选框内出现一个灰色“√”。 按钮控件会向父窗口发送通知消息,最常用的通知消息莫过于BN_CLICKED和BN_DOUBLECLICKED了。用户在按钮上单击鼠标时会向父窗口发送BN_CLICKED消息,双击鼠标时发送BN_DOUBLECLICKED消息。

    复选框就是正方形 + 一些字(基本样式),一般这种样式都是用于工业软件,不是特别在意界面,但是一些游戏啊,直播啊,都会给这些常用控件“穿一件衣服”。

    04.按钮控件的创建

    按钮控件的创建有两种方式: 1.第一种是最常用的:拖拽 2.第二种是用于原生控件:程序写出来的控件

    4.1 拖拽方式

    拖拽方式就比较常见了,没有哪一个程序员会在拖控件和写控件间犹豫,肯定都是选择编译器封装好的直接拖来用就好了,这个就不多说,大致说一下步骤:

    新建MFC项目(至于选择单文档,多文档自己决定,均可)——切换视图为资源视图(如果界面没有,点击工具栏的视图->其他视图->资源视图)——选择一个Dialog,没有就创建,如果不知道怎么创建,请回看MFC学习笔记(创建与修改对话框),——选择左侧或者右侧工具栏,是所有按钮都在里面

    4.2 重写方式

    一般来说这种是用于写原生控件,就是自己写控件,不用系统默认的,自己给他给样式或者属性等等

    4.2.1 创建函数原型

    MFC提供了CButton类封装按钮控件的所有操作。 之前的教程中,我们是在对话框模板上直接添加的按钮控件资源,但某些特殊情况下需要我们动态创建按钮控件,即通过CButton类的成员函数Create来创建按钮。下面是Create函数的原型:

    virtual BOOL Create( LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

    参数说明: lpszCaption:指定按钮控件显示的文本。 dwStyle:指定按钮控件的风格,可以设置为以下按钮风格的任意组合。 BS_AUTOCHECKBOX :同BS_CHECKBOX,不过单击鼠标时按钮会自动反转 BS_AUTORADIOBUTTON: 同BS_RADIOBUTTON,不过单击鼠标时按钮会自动反转 BS_AUTO3STATE :同BS_3STATE,不过单击按钮时会改变状态 BS_CHECKBOX:指定在矩形按钮右侧带有标题的选择框 BS_DEFPUSHBUTTON:指定默认的命令按钮,这种按钮的周围有一个黑框,用户可以按回车键来快速选择该按钮 BS_GROUPBOX:指定一个组框 BS_LEFTTEXT:使控件的标题显示在按钮的左边 BS_OWNERDRAW:指定一个自绘式按钮 BS_PUSHBUTTON:指定一个命令按钮 BS_RADIOBUTTON:指定一个单选按钮,在圆按钮的右边显示正文 BS_3STATE:同BS_CHECKBOX,不过控件有3 种状态—选择、未选择和变灰 当然,除了以上列出的风格,一般还会为按钮设置WS_CHILD、WS_VISIBLE和WS_TABSTOP等风格,WS_TABSTOP风格使按钮控件具有tab停止属性,即按tab键切换焦点控件时能够将焦点 停在按钮控件上。创建一组单选按钮时,第一个按钮的风格应设置为WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_GROUP|BS_AUTORADIOBUTTON,其他单选按钮的风格应 为WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,不包含WS_TABSTOP和WS_GROUP。 在对话框模板上直接添加按钮控件时,它的属性中包含了上述风格,例如,复选框的Tri_state属性实际上代表的就是BS_3STATE风格。 剩下的三个参数与静态文本框的Create函数中的相应参数类似,大家可以参考前面静态文本框的讲解,也可以查阅MSDN。

    4.2.2 主要成员函数

    下面是CButton类的一些主要的成员函数,至于其他的函数大家可以在MSDN中查看。

    // 设置要在按钮中显示的位图。参数hBitmap为位图的句柄。返回值为按钮原来位图的句柄。 HBITMAP SetBitmap(HBITMAP hBitmap); //获取之前由SetBitmap函数设置的按钮位图的句柄。 HBITMAP GetBitmap( ) const; //设置按钮的风格。参数nStyle指定按钮的风格,bRedraw指定按钮是否重绘,为TRUE则重绘,否则不重绘,默认为重绘。 void SetButtonStyle(UINT nStyle,BOOL bRedraw = TRUE); // 获取按钮控件的风格。 UINT GetButtonStyle( ) const; //设置按钮的选择状态。参数nCheck为0表示未选中状态,1表示选中状态,2表示不确定状态(仅用于复选框)。 void SetCheck(int nCheck); //获取按钮的选择状态。返回值的意义同SetCheck函数的nCheck参数。 int GetCheck( ) const; //设置要显示到按钮上的光标图。参数hCursor指定了光标的句柄。返回值为按钮原来光标的句柄。 HCURSOR SetCursor(HCURSOR hCursor); // 获取之前由SetCursor设置的光标的句柄。 HCURSOR GetCursor( ); //设置要在按钮上显示的图标。参数hIcon指定了图标的句柄。返回值为按钮原来图标的句柄。 HICON SetIcon(HICON hIcon); // 获取之前由SetIcon设置的图标的句柄。 HICON GetIcon( ) const; //设置按钮的高亮状态。参数bHighlight指定按钮是否高亮显示,非0则高亮显示,否则取消高亮显示状态。 void SetState(BOOL bHighlight); //获取按钮控件的选择状态、高亮状态和焦点状态。我们可以通过将返回值与各个掩码相与来获得各种状态值,掩码与对应的相与结果说明如下: /* 掩码0x0003:用来获取单选按钮或复选框的状态。相与结果为0表示未选中,1表示被选中,2表示不确定状态(仅用于复选框)。 掩码0x0004:用来判断按钮是否是高亮显示。相与结果为非0值表示按钮是高亮显示的。当单击按钮并按住鼠标左键时,按钮会呈高亮显示。 掩码0x0008:相与结果为非零值表示按钮拥有输入焦点。 */ UINT GetState( ) const; //下面再列出几个继承自CWnd类的成员函数,通过它们获取或设置按钮控件的状态非常方便,只需要知道按钮的ID。 //用来设置按钮的选择状态。参数nIDButton指定了按钮的ID。nCheck的值为0表示按钮未被选择,为1表示按钮被选择,为2表示按钮处于不确定状态(仅用于复选框)。 void CheckDlgButton(int nIDButton,UINT nCheck); // 返回复选框或单选按钮的选择状态。返回值为0表示按钮未被选择,为1表示按钮被选择,为2表示按钮处于不确定状态(仅用于复选框)。 UINT IsDlgButtonChecked(int nIDButton) const; // 用来选择组中的一个单选按钮。参数nIDFirstButton指定了组中第一个按钮的ID,nIDLastButton指定了组中最后一个按钮的ID,nIDCheckButton指定了要选择的按钮的ID。 void CheckRadioButton(int nIDFirstButton,int nIDLastButton,int nIDCheckButton); //用来获得一组单选按钮中被选中按钮的ID。参数nIDFirstButton 说明了组中第一个按钮的ID,nIDLastButton 说明了组中最后一个按钮的ID。 int GetCheckedRadioButton(int nIDFirstButton, int nIDLastButton);

    另外,CWnd类的成员函数GetWindowText()、SetWindowText()等也可以用来获取或设置按钮中显示的文本。 关于按钮控件Button、Radio Button和Check Box的使用基础就介绍到此。

    05.按钮控件实例(借鉴)

    公司电脑不能截图,所以写出来也没法上传,所以就直接借用网上的资源吧。

    创建一个基于对话框的MFC工程,名称设为“Example23”。 .

    在自动生成的主对话框IDD_EXAMPLE23_DIALOG的模板中,删除“TODO: Place dialog controls here.”静态文本框,添加两个Group Box,属性Caption分别改为“网站类型”、“网站”。

    在Group Box“网站类型”中加入三个Radio Button,Caption分别设为“门户”、“论坛”和“博客”,ID分别设为IDC_PORTAL_RADIO、IDC_FORUM_RADIO和IDC_BLOG_RADIO。

    在Group Box“网站”中加入六个Check Box,Caption分别设为“鸡啄米”、“新浪”、“天涯论坛”、“韩寒博客”、“网易”和“凤凰网论坛”,ID分别设为IDC_CHECK1、IDC_CHECK2、IDC_CHECK3、IDC_CHECK4、IDC_CHECK5和IDC_CHECK6。然后为每个复选框添加CButton类型的变量m_check1、m_check2、m_check3、m_check4、m_check5和m_check6。

    在两个Group Box下面,添加一个静态文本框和一个编辑框。静态文本框的Caption设为“选择的网站:”。编辑框的ID设为IDC_WEBSITE_SEL_EDIT,属性Read Only改为True,使此编辑框为只读状态,不允许用户编辑。

    将“OK”按钮的Caption修改为“确定”,“Cancel”按钮的Caption修改为“退出”。到此,对话框模板就修改好了,如下图:

    为“门户”、“论坛”和“博客”三个单选按钮分别添加点击消息的消息处理函数CExample23Dlg::OnBnClickedPortalRadio()、CExample23Dlg::OnBnClickedForumRadio()和CExample23Dlg::OnBnClickedBlogRadio()。

    说明: 在某个单选按钮被点击之后,我们可以先将六个网站复选框都禁用且置为非选中状态,而后将选择的网站类型对应的网站复选框激活。为了代码复用,我们将置所有复选框为禁用且非选中状态的操作写到一个函数里,此函数为CExample23Dlg::InitAllCheckBoxStatus(),然后就可以在三个单选按钮的消息处理函数中调用InitAllCheckBoxStatus(),实现复选框状态的初始化。 三个消息处理函数及InitAllCheckBoxStatus()函数的实现如下:

    C++代码

    void CExample23Dlg::OnBnClickedPortalRadio() { // TODO: Add your control notification handler code here // 如果选择了“门户”单选按钮,则激活复选框“新浪”和“网易”,其他复选框禁用并非选中 InitAllCheckBoxStatus(); m_check2.EnableWindow(TRUE); m_check5.EnableWindow(TRUE); } void CExample23Dlg::OnBnClickedForumRadio() { // TODO: Add your control notification handler code here // 如果选择了“论坛”单选按钮,则激活复选框“天涯论坛”和“凤凰网论坛”,其他复选框禁用并非选中 InitAllCheckBoxStatus(); m_check3.EnableWindow(TRUE); m_check6.EnableWindow(TRUE); } void CExample23Dlg::OnBnClickedBlogRadio() { // TODO: Add your control notification handler code here // 如果选择了“博客”单选按钮,则激活复选框“鸡啄米”和“韩寒博客”,其他复选框禁用并非选中 InitAllCheckBoxStatus(); m_check1.EnableWindow(TRUE); m_check4.EnableWindow(TRUE); } // 初始化所有复选框的状态,即全部禁用,全部非选中 void CExample23Dlg::InitAllCheckBoxStatus() { // 全部禁用 m_check1.EnableWindow(FALSE); m_check2.EnableWindow(FALSE); m_check3.EnableWindow(FALSE); m_check4.EnableWindow(FALSE); m_check5.EnableWindow(FALSE); m_check6.EnableWindow(FALSE); // 全部非选中 m_check1.SetCheck(0); m_check2.SetCheck(0); m_check3.SetCheck(0); m_check4.SetCheck(0); m_check5.SetCheck(0); m_check6.SetCheck(0); } 程序运行后,我们希望网站类型默认选择为“门户”,则修改对话框初始化函数CExample23Dlg::OnInitDialog()为:

    C++代码

    BOOL CExample23Dlg::OnInitDialog() { CDialogEx::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here // 默认选中“门户”单选按钮 CheckDlgButton(IDC_PORTAL_RADIO, 1); OnBnClickedPortalRadio(); return TRUE; // return TRUE unless you set the focus to a control } 9. 点击“确定”后,将选择的网站名字显示到编辑框中,那么需要修改“确定”按钮(原来的OK按钮)的消息处理函数CExample23Dlg::OnBnClickedOk()如下: C++代码 void CExample23Dlg::OnBnClickedOk() { // TODO: Add your control notification handler code here CString strWebsiteSel; // 选择的网站 // 若选中“鸡啄米”则将其加入结果字符串 if (1 == m_check1.GetCheck()) { strWebsiteSel += _T("鸡啄米 "); } // 若选中“新浪”则将其加入结果字符串 if (1 == m_check2.GetCheck()) { strWebsiteSel += _T("新浪 "); } // 若选中“天涯论坛”则将其加入结果字符串 if (1 == m_check3.GetCheck()) { strWebsiteSel += _T("天涯论坛 "); } // 若选中“韩寒博客”则将其加入结果字符串 if (1 == m_check4.GetCheck()) { strWebsiteSel += _T("韩寒博客 "); } // 若选中“网易”则将其加入结果字符串 if (1 == m_check5.GetCheck()) { strWebsiteSel += _T("网易 "); } // 若选中“凤凰网论坛”则将其加入结果字符串 if (1 == m_check6.GetCheck()) { strWebsiteSel += _T("凤凰网论坛 "); } // 将结果字符串显示于“选择的网站”后的编辑框中 SetDlgItemText(IDC_WEBSITE_SEL_EDIT, strWebsiteSel); // 为了避免点“确定”后对话框退出,将OnOk注掉 //CDialogEx::OnOK(); } 到此程序编写完成。运行程序弹出结果对话框,选择网站后界面如下图: 按钮控件的内容就这些了。掌握了按钮控件的基本用法,又动手编写了这个实例后,相信大家对按钮控件已经很熟悉了。欢迎大家继续来学习交流。

    按钮框就讲到这里,主要是今天工作用到了复选框,复习的时候就直接写一篇博客。 借鉴博客:http://www.jizhuomi.com/software/182.html 版权声明:转载请注明出处 谢谢大家的支持,欢迎大家一起交流学习

    Processed: 0.016, SQL: 9