今天在学习制作计算器小程序中,碰到要多个按钮共用一个事件的问题,

现记录下来.

在窗体上按钮排列

排列的时候要按顺序排放,也就是说,0-9的ID号要连着的.

#define IDD_DIALOG1                     101
#define IDC_BTN_1 1001
#define IDC_BTN_2 1002
#define IDC_BTN_3 1003
#define IDC_BTN_4 1004
#define IDC_BTN_5 1005
#define IDC_BTN_6 1006
#define IDC_BTN_7 1007
#define IDC_BTN_8 1008
#define IDC_BTN_9 1009
#define IDC_BTN_10 1010
#define IDC_BTN_11 1011
#define IDC_BTN_12 1012
#define IDC_BTN_13 1013
#define IDC_BTN_14 1014
#define IDC_BTN_15 1015
#define IDC_BTN_16 1016
#define IDC_BTN_17 1017
#define IDC_BTN_18 1018
#define IDC_BTN_19 1019
#define IDC_EDIT1 1020

在WM_COMMAND消息中去捕获

CString str;
void OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
UINT btnId = LOWORD(wParam);
HWND hBtn = (HWND)lParam;
HWND hEdit = GetDlgItem(hWnd, IDC_EDIT1); //数字0-9,小数点按钮消息
if (btnId >= IDC_BTN_1 && btnId <= IDC_BTN_11)
{
CString tem;
GetWindowText(hBtn, tem.GetBuffer(), 4);//根据按下的数字按钮获得相应的数字字符
str.Format(TEXT("%s%s"), str, tem);
SetWindowText(hEdit, str);
} //处理+-*/运算符按钮
if (btnId >= IDC_BTN_12 && btnId <= IDC_BTN_15)
{ }
}

原来用swith语句的,但是出现了case 不能判断>=格式,所以只能用if语句了,

其他的同样的道理,要操作哪几个按钮,只要把它们的ID号连着,用if语句判断是否在指定的范围内的ID号就行了.

上面的程序只有点0-9和小数点有效,其它的没有反应.

//补充

今天去查看了下MFC中是如何弄的多个按键共有一个消息的,原来MFC中定义的消息结构中多了个控件ID的最后范围:
struct AFX_MSGMAP_ENTRY
{
UINT nMessage; // windows message
UINT nCode; // control code or WM_NOTIFY code
UINT nID; // control ID (or 0 for windows messages)
UINT nLastID; // used for entries specifying a range of control id's
UINT_PTR nSig; // signature type (action) or pointer to message #
AFX_PMSG pfn; // routine to call (or special value)
};

所以我在原来的甚础上也添加了这个

//定义消息结构体
struct MSGMAP_STRUCT
{
UINT uMsg; //消息id号
UINT uCod; //控件反射的事件id号
UINT uCtrID; //控件id号
UINT uLastID; //控件ID结束范围
AFX_PMSG pfn; //函数指针
};

最后在WM_COMMAND消息中判断下消息中的uLastID是否为零,不为零就继续判断传来的控件ID是不是指定的范围内,

如果是就返回找到的消息和对应的消息响应函数,下面这要结合我写的https://www.cnblogs.com/greenleaf1976/p/14780317.html就能明白

if(uMsg==WM_COMMAND)\
{\
if(pMsg->uLastID!=0)\
{\
if (LOWORD(wParam)>=pMsg->uCtrID && LOWORD(wParam) <= pMsg->uLastID)\
{\
return pMsg;\
}\
}\
else if (pMsg->uCtrID == LOWORD(wParam) && pMsg->uCod == HIWORD(wParam))\
return pMsg;\

消息宏的定义

//定义添加消息结构宏
#define ON_WM_MESSAGE(msg,pfn) {msg,0,0,0,(AFX_PMSG)pfn},
#define ON_COMMAND(ctrlID,pfn) {WM_COMMAND,0,ctrlID,0,(AFX_PMSG)pfn},
#define ON_COMMAND_CTRL(ctrlEvent,ctrlID,pfn) {WM_COMMAND,ctrlEvent,ctrlID,0,(AFX_PMSG)pfn},
#define ON_NOTIFY(ctrlEvent,ctrlID,pfn) {WM_NOTIFY,ctrlEvent,ctrlID,0,(AFX_PMSG)pfn},
#define ON_COMMAND_RANGE(ctrlID,ctrLastID,pfn) {WM_COMMAND,0,ctrlID,ctrLastID,(AFX_PMSG)pfn},

在静态消息数组中添加

BEGIN_MESSAGE_MAP(MyTestDialog, QDialog)
ON_WM_MESSAGE(WM_CLOSE, &MyTestDialog::OnClose)
ON_NOTIFY(LVN_ITEMCHANGED, 1001, &MyTestDialog::OnListCtrlItemChanged)
ON_WM_MESSAGE(WM_SIZE,&MyTestDialog::OnSize)
ON_NOTIFY(NM_CLICK,1002,&MyTestDialog::OnStatusClick)
ON_COMMAND_RANGE(10001,10004,&MyTestDialog::OnBtnArrClick)//这个就是多个控件共用一个消息响应函数,(控件ID必须是连续的)
ON_COMMAND(10001,&MyTestDialog::OnBtn1Click)
END_MESSAGE_MAP()

最后来个效果:

LRESULT MyTestDialog::OnBtnArrClick(WPARAM wParam, LPARAM lParam)
{
UINT ctrlID = LOWORD(wParam);//控件ID
UINT code = HIWORD(wParam);
HWND hbtn = (HWND)lParam;  //控件句柄
CString str;
GetWindowText(hbtn, str.GetBuffer(), 10);//获得控件ID上对应的文本
str.Format(TEXT("%s,id=%d,code=%d"), str, ctrlID, code);//格式化显示控件文本,控件ID,控件事件ID
MessageBox(str);
return 0;
}

这是按下btn1;

这是按下btn2;

这是按下btn3;

这是btn4;

Win32 处理多个按钮共用一个事件消息的更多相关文章

  1. 第34天学习打卡(GUI编程之组件和容器 frame panel 布局管理 事件监听 多个按钮共享一个事件 )

    GUI编程 组件 窗口 弹窗 面板 文本框 列表框 按钮 图片 监听事件 鼠标 键盘事件 破解工具 1 简介 GUi的核心技术:Swing AWT 1.界面不美观 2.需要jre环境 为什么要学习GU ...

  2. 【读书笔记】iOS-storyBoard-为一个按钮添加一个点击事件

    按照故事板的用语,应用中的一个界面屏幕被称作一个”场景(Scene)",以后添加额外的场景时,停靠区中将有另一个部分. 一,新建立一个工程,如图所示. 二,选中Main.storyboard ...

  3. jquery移动端一个按钮两个事件

    当一个按钮已经有一个事件,如点击,弹窗显示,若还要加个事件,可以用touchstart 如: var videoCover = $("#videoCover");//视频封面 $( ...

  4. avalon 双工绑定以及一个按钮多个事件

    <html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    ...

  5. win32 htmlayout点击按钮创建新窗口,以及按钮图片样式

    最近在做一个C++ win32的桌面图形程序,我不是C++程序员,做这个只是因为最近没什么java的活. windows api,之前接触的时候,还是大学,那时用这个开发打飞机游戏纯粹是娱乐.现在基本 ...

  6. winform 多个label绑定一个事件

    1当多个label帮到到一个事件后 private void jiandao_Click(object sender, EventArgs e) { //sender显示的是窗体上接受事件的label ...

  7. Unity3D NGUI 给button按钮添加单间事件

    Unity3D中, NGUI 给button按钮添加单间事件的方法很多,在这里只给推荐一种比较常用的方法. 推荐方法:使用UIListener. 1.给button组价添加上UIListener.选择 ...

  8. 菜鸟学JS(四)——javascript为按钮注册回车事件(设置默认按钮)

    不得不说,在JS方面,自己真的是个不折不扣的菜鸟.对于JS以及一些JS框架如JQuery等JS框架,自己也只是处在简单应用的阶段,当然自己也在不断的学习当中,希望将来能跟大家分享更多JS方面的心得.今 ...

  9. Objective-C:模拟按钮点击事件理解代理模式

    OC中的协议(Protocol)和和.NET中的接口(Interface)类似,简单来讲,就是一系列方法的列表,其中声明的方法可以被任何类实现.不同的是,在.NET中,如果某个类实现了一个接口,就必须 ...

  10. JQ避免出现多次执行一个事件的解决方案

    点击按钮之后会多次执行一个事件的话,就在方法结尾加入如下代码,这样的话事件就可以只执行一次了 //避免出现多次执行事件的问题 event.stopPropagation(); 此外,时间的重复绑定也有 ...

随机推荐

  1. Apache Kylin(二)在EMR上搭建Kylin

    EMR上搭建kylin 1. 启动EMR集群 根据官网说明: http://kylin.apache.org/docs21/install/kylin_aws_emr.html 启动EMR时,若是 h ...

  2. 在高通lk中添加自定义源文件

    在高通lk中添加自定义源文件 背景 在lk开发中,需要添加一个自定义功能,但是又不希望代码污染无关的文件(把无关代码添加到某个源文件中是一种罪). 以添加一个aw9523b.c的驱动为例,在aboot ...

  3. 使用bootchart 对 高通Android 进行性能分析

    使用bootchart 对 高通Android 进行性能分析 Android版本:7.0 适用平台:高通和MTK 参考: https://blog.csdn.net/qq_19923217/artic ...

  4. rust项目中通过log4rs将日志写入文件

    java项目中使用最广泛的日志系统应该是log4j(2)了.如果你也是一个Java程序员,可能在写rust的时候会想怎么能顺手地平移日志编写习惯到rust中来. log4rs就是干这个的.从名字就能看 ...

  5. 韦东山IMX6ULL Linux开发板基于Buildroot系统QT应用环境配置开发运行

    @ 目录 一. 编译系统 1.设置交叉编译工具链 2.编译系统 二. QT下载 1.安装 Qtcreator 2.创建第一个程序 3.配置 QtCreator 开发环境 4.移植QT程序到开发板 一. ...

  6. 2.模块文件以及增删改查(CURD操作)

    创建 db.py db.py 文件是我们管理数据库连接和模型基类的地方.它让我们的代码更加模块化和可维护,实际生产中也是类似的,无论是在 FastAPI 或者 Flask 等框架中,当使用到 SqlA ...

  7. 开源GTKSystem.Windows.Forms,在这里更新预告

    开源GTKSystem.Windows.Forms,在这里更新预告 gitee码云开源地址:https://gitee.com/easywebfactory/gtksystem-windows-for ...

  8. 6.Class 与 Style 绑定

    操作元素的 class 列表和内联样式是数据绑定的一个常见需求. 因为它们都是属性,所以我们可以用 v-bind 处理它们:只需要通过表达式计算出字符串结果即可. 不过,字符串拼接麻烦且易错.因此,在 ...

  9. 探究kubernetes 探针参数periodSeconds和timeoutSeconds

    探究kubernetes 探针参数 periodSeconds和timeoutSeconds 问题起源 kubernetes probes的配置中有两个容易混淆的参数,periodSeconds和ti ...

  10. centos下安装Docker容器

    安装前的准备工作 1.列出docker安装过的相关包 sudo yum list installed | grep docker 2.删除相关安装包 #根据查找出来的进行删除,不同版本可能有不一样的情 ...