zoukankan      html  css  js  c++  java
  • 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;

    签名:GreenLeaf1976
  • 相关阅读:
    恢复更新
    Sun与Google结为战略合作伙伴, 可能联合Sun推出Web Office
    Outlook数据文件备份和按年存档的办法
    新装的几个软件试用体会(WPS 2005,Opera,QQ 2005 Beta3)
    关于VBA和Excel,GIS软件
    人格测试
    Taking a serious look at grids
    iPod、iMac 5、iTunes 6
    如此“自助”
    UCGIS优先研究领域介绍
  • 原文地址:https://www.cnblogs.com/greenleaf1976/p/14802791.html
Copyright © 2011-2022 走看看