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

现记录下来.

在窗体上按钮排列

排列的时候要按顺序排放,也就是说,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. Linux greybus

    背景 在研究高通平台驱动震动马达时,我需要为内核驱动实现以下功能:/sys/class/timed_output/vibrator/enable":sysfs文件系统注册接口.提供show. ...

  2. 通过 源码 安装 python

    为了vim PYTHON="3.4.1" tget () { #try wget filename=`basename $1` echo "Downloading [${ ...

  3. C语言gcc编译环境搭建

    第一步,根据以下链接下载gcc工具包: gcc工具包下载地址: 链接:https://pan.baidu.com/s/1JqEjakTcWLPv7p6zkah6sA提取码:k4d2 第二步,将下载好的 ...

  4. 写给rust初学者的教程(二):所有权、生存期

    这系列RUST教程一共三篇.这是第二篇,介绍RUST语言的关键概念,主要是所有权和生存期等. 第一篇:写给rust初学者的教程(一):枚举.特征.实现.模式匹配 在写第一篇中的练习代码时,不知道你有没 ...

  5. springboot实现登录demo

    实现简单的登录功能 实体类 定义实体类为User3类. 使用@Data:提供类的get,set,equals,hashCode,canEqual,toString方法: 使用@AllArgsConst ...

  6. 在Django中查找重复项目

    在Django中查找重复项目通常涉及使用查询集(QuerySet)和模型(Model).假设你有一个模型,比如Item,你想查找其中重复的项目,可以通过以下步骤来实现: 确定重复的标准: 首先需要确定 ...

  7. [oeasy]python0072_整数类型_int_integer_整型变量

    帮助手册 回忆上次内容   上次了解的是 字符串 字符串 就是 字符的串 字符串长度 可以用 len函数 字符可以用下标索引 []   可以用str 将整型数字 转化为 字符串   字符的长度本身 有 ...

  8. oeasy教您玩转vim - 35 - # 正则表达

    ​ 查找进阶 回忆上节课内容 实时搜索 :set incsearch 大写小写 ignorecase 查找当前单词 * 正向按单词 # 反向按单词 g* 正向不按单词 g# 反向不按单词 继续查找 n ...

  9. 工作单元(UnitOfWork) 模式 (1)

    在开始UnitOfWork模式之前有必要回顾下我们耳熟能详的Data Access Object(DAO)模式,即数据访问对象.DAO是一种简单的模式,我们构建应用的时候经常会使用到它,它的功能就是将 ...

  10. ASP.NET Core 程序集注入(三)

    前言: 在Autofac的使用中,提供了个种注入的API其中GetAssemblies()用着特别的舒坦. 1.core2.0也可以使用Autofac的包,但框架自身也提供了默认的注入Api,ISer ...