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;

 

posted @ 2021-05-24 02:01  初吻给了烟灬  阅读(240)  评论(0编辑  收藏  举报