当前位置: 首页 > 工具软件 > DuiVision > 使用案例 >

DuiVision开发教程(5)-事件处理类编写

阎成天
2023-12-01

使用DuiVision开发的界面程序中,除了界面的描述之外,最主要的工作就是业务逻辑的处理,为了将业务逻辑和界面展示能够更好的分离,DuiVision中定义了事件处理基类,所有的业务逻辑都应该写在派生的事件处理类中,并把事件处理对象注册到相应的对话框或控件上,这样对应的子控件有事件需要处理的时候,就会自动调用注册的事件处理对象的相应函数。事件处理类只要在处理函数中根据控件的ID或名字决定该做什么事情,写相应的处理代码就可以。事件处理类中同时提供了一些函数方便根据ID或名字获取到对应的控件对象,并对控件进行操作,例如改变控件文字、获取控件的某个状态等。

事件处理基类是CDuiHandler,这个类的定义如下,提供了获取控件对象、设置控件的一些参数的函数,方便在事件处理类中对控件的操作:

class CDuiHandler
{
public:
    CDuiHandler(void);
    virtual ~CDuiHandler(void);

    void SetDuiObject(CDuiObject* pDuiObject);
    CControlBase* GetControl(UINT uControlID);
    CControlBase* GetControl(CString strControlName);
    CDlgBase* GetControlDialog(UINT uControlID);

    void SetVisible(CString strControlName, BOOL bIsVisible);
    void SetDisable(CString strControlName, BOOL bIsDisable);
    void SetTitle(CString strControlName, CString strTitle);
    CString GetTitle(CString strControlName);

    virtual void OnInit();
    virtual LRESULT OnDuiMessage(UINT uID, CString strName, UINT Msg, WPARAM wParam, LPARAM lParam);
    virtual void OnTimer(UINT uTimerID, CString strTimerName);

protected:
    CDuiObject* m_pDuiObject;           // 关联的DUI对象
};

下面这段代码是在派生的事件处理类的OnDuiMessage函数中判断如果点击了某个按钮,就修改一个进度条进度的代码:

    if(strName == _T("button_normal_3"))
    {
        CDuiProgress* pControl = (CDuiProgress*)GetControl(_T("progress"));
        if(pControl && (Msg == BUTTOM_UP))
        {
            static int g_nProgress = 0;
            g_nProgress += 10;
            if(g_nProgress > 100)
            {
                g_nProgress = 0;
            }
            pControl->SetProgress(g_nProgress);
        }
    }

为了简化事件处理类的编写,使事件处理的代码看起来更清晰一些,DuiHandler.h中定义了一些事件处理函数的消息映射宏,如下表所示:

参数说明
DUI_DECLARE_MESSAGE_BEGIN类名事件处理类的消息映射宏开始
DUI_DECLARE_MESSAGE_END事件处理类的消息映射宏结束
DUI_CONTROL_ID_MESSAGE控件ID、处理函数根据控件ID,执行相应的处理函数
DUI_CONTROL_IDMSG_MESSAGE控件ID、消息、处理函数根据控件ID和消息,执行相应的处理函数
DUI_CONTROL_NAME_MESSAGE控件名、处理函数根据控件名,执行相应的处理函数
DUI_CONTROL_NAMEMSG_MESSAGE控件名、消息、处理函数根据控件名和消息,执行相应的处理函数

实际定义的样例如下:

// 消息处理定义
DUI_DECLARE_MESSAGE_BEGIN(CDuiHandlerMain)
    DUI_CONTROL_ID_MESSAGE(APP_IPC, OnDuiMsgInterprocess)
    DUI_CONTROL_NAME_MESSAGE(NAME_SKIN_WND, OnDuiMsgSkin)
    DUI_CONTROL_NAMEMSG_MESSAGE(NAME_TRAY_ICON, MSG_TRAY_DBCLICK, OnDuiMsgTrayIconDClick)
    DUI_CONTROL_NAMEMSG_MESSAGE(L"notify_button_1", BUTTOM_UP, OnDuiMsgNotifyButton1)
    DUI_CONTROL_NAMEMSG_MESSAGE(L"notify_button_2", BUTTOM_UP, OnDuiMsgNotifyButton2)
    DUI_CONTROL_NAMEMSG_MESSAGE(L"notify_button_3", BUTTOM_UP, OnDuiMsgNotifyButton3)
    DUI_CONTROL_NAMEMSG_MESSAGE(L"listctrl_1", BUTTOM_DOWN, OnDuiMsgListCtrl1Click)
    DUI_CONTROL_NAMEMSG_MESSAGE(L"listctrl_2", BUTTOM_DOWN, OnDuiMsgListCtrl2Click)
DUI_DECLARE_MESSAGE_END()

在编写自己的Handler事件处理类时候可以参考样例,定义消息映射宏,每个需要处理的消息定义一行内容,定义出哪个控件的什么消息需要处理,由哪个函数处理,消息处理函数必须按照固定的参数格式来编写,消息处理函数的样例如下:

// 显示信息对话框消息处理
LRESULT CDuiHandlerMain::OnDuiMsgMsgBoxButton1(UINT uID, CString strName, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    DuiSystem::DuiMessageBox(NULL, _T("演示对话框!"));
    return TRUE;
}

每个消息处理函数必须按照以上样例中的参数格式,函数的返回值表示此消息是否不再需要向下传递继续处理了,如果返回TRUE,则消息处理结束,如果返回FALSE,则此消息还可以继续被后面定义的其他函数处理。
使用以上的宏定义,会自动在进入消息处理函数时候记录日志,日志内容类似于下面这样:

DEBUG 2014-09-07 22:43:31[98544] : CDuiHandlerMain::OnDuiMessage:uID=1109, name=menu_1, msg=1, wParam=0, lParam=0

DuiVision开源代码下载地址(github):https://github.com/blueantst/DuiVision
蓝蚂蚁工作室主页:http://www.blueantstudio.net
DuiVision QQ群:325880743
微信公众号:blueantstudio 或搜索 蓝蚂蚁工作室

 类似资料: