Win32 处理多个按钮共用一个事件消息
今天在学习制作计算器小程序中,碰到要多个按钮共用一个事件的问题,
现记录下来.
在窗体上按钮排列

排列的时候要按顺序排放,也就是说,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 处理多个按钮共用一个事件消息的更多相关文章
- 第34天学习打卡(GUI编程之组件和容器  frame panel 布局管理 事件监听  多个按钮共享一个事件 )
		GUI编程 组件 窗口 弹窗 面板 文本框 列表框 按钮 图片 监听事件 鼠标 键盘事件 破解工具 1 简介 GUi的核心技术:Swing AWT 1.界面不美观 2.需要jre环境 为什么要学习GU ... 
- 【读书笔记】iOS-storyBoard-为一个按钮添加一个点击事件
		按照故事板的用语,应用中的一个界面屏幕被称作一个”场景(Scene)",以后添加额外的场景时,停靠区中将有另一个部分. 一,新建立一个工程,如图所示. 二,选中Main.storyboard ... 
- jquery移动端一个按钮两个事件
		当一个按钮已经有一个事件,如点击,弹窗显示,若还要加个事件,可以用touchstart 如: var videoCover = $("#videoCover");//视频封面 $( ... 
- avalon 双工绑定以及一个按钮多个事件
		<html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> ... 
- win32 htmlayout点击按钮创建新窗口,以及按钮图片样式
		最近在做一个C++ win32的桌面图形程序,我不是C++程序员,做这个只是因为最近没什么java的活. windows api,之前接触的时候,还是大学,那时用这个开发打飞机游戏纯粹是娱乐.现在基本 ... 
- winform 多个label绑定一个事件
		1当多个label帮到到一个事件后 private void jiandao_Click(object sender, EventArgs e) { //sender显示的是窗体上接受事件的label ... 
- Unity3D NGUI 给button按钮添加单间事件
		Unity3D中, NGUI 给button按钮添加单间事件的方法很多,在这里只给推荐一种比较常用的方法. 推荐方法:使用UIListener. 1.给button组价添加上UIListener.选择 ... 
- 菜鸟学JS(四)——javascript为按钮注册回车事件(设置默认按钮)
		不得不说,在JS方面,自己真的是个不折不扣的菜鸟.对于JS以及一些JS框架如JQuery等JS框架,自己也只是处在简单应用的阶段,当然自己也在不断的学习当中,希望将来能跟大家分享更多JS方面的心得.今 ... 
- Objective-C:模拟按钮点击事件理解代理模式
		OC中的协议(Protocol)和和.NET中的接口(Interface)类似,简单来讲,就是一系列方法的列表,其中声明的方法可以被任何类实现.不同的是,在.NET中,如果某个类实现了一个接口,就必须 ... 
- JQ避免出现多次执行一个事件的解决方案
		点击按钮之后会多次执行一个事件的话,就在方法结尾加入如下代码,这样的话事件就可以只执行一次了 //避免出现多次执行事件的问题 event.stopPropagation(); 此外,时间的重复绑定也有 ... 
随机推荐
- Ethercat设备数据 转 EthernetIP项目案例
			1 案例说明 1. 设置网关采集EtherCAT设备数据 2. 把采集的数据转成EthernetIP协议转发给其他系统. 2 VFBOX网关工作原理 VFBOX网 ... 
- Vue 的父组件和子组件生命周期钩子函数执行顺序?
			https://www.cnblogs.com/thinheader/p/9462125.html 参考连接 Vue 的父组件和子组件生命周期钩子函数执行顺序可以归类为以下 4 部分: 加载渲染过程 ... 
- yb课堂之用户登陆校验拦截器开发 《十一》
			开发对应的登陆拦截器 开发loginInterceptor 登陆校验成功放行 登陆不成功返回json数据 LoginInterceptor.java package net.ybclass.onlin ... 
- axios和AJAX的区别
			axios和ajax的区别 Axios和Ajax都是用于处理网络请求和与服务器进行通信的技术,但它们之间存在一些关键的区别:12 一.技术基础:Ajax(Asynchronous JavaScript ... 
- 学习Java的第一周总结
			经历了一周关于Java的学习后,我想已经初步了解了Java.在这一周中我跟随黑马程序员的脚步初步学习,现在已经安装了jdk环境(当然它不只是一个运行环境,还附带了许多开发工具)并能够用它输出" ... 
- 解决方案 | pywintypes.com_error: (-2147418111, '被呼叫方拒绝接收呼叫。', None, None)
			解决方案:加一个time.sleep(1)即可 
- webpack4.15.1 学习笔记(三) — 模块热替换HMR
			目录 模块热替换 HMR HMR监听文件变化 HMR 修改样式表 模块热替换 HMR 允许在运行时更新各种模块,而无需进行完全刷新.不适用于生产环境,意味着应当只在开发环境使用.启用HMR实际上就是更 ... 
- Docker 容器开发:虚拟化
			Docker 容器开发:虚拟化 Docker 的核心价值在于虚拟化或者说环境隔离[通过虚拟化技术实现虚拟环境],解决环境配置和部署的依赖问题实现解耦 我对虚拟化的理解源自<Operating S ... 
- 计算复杂性学习笔记(TCS笔记)
			感觉最近太摆了,每天很空虚,不愿意搞应试那一套,还是得学点东西.还是准备一边学tcs一边搞搞oi好打icpc,搞这个纯属兴趣,也是填个坑.最近进了一个初中生建的数学交流群,感觉群里初中生也很厉害,开始 ... 
- spring boot 快速入门(一)创建一个简单的Spring Boot项目
			1.什么是Spring Boot Spring Boot makes it easy to create stand-alone, production-grade Spring based Appl ... 
