界面消息传递机制, 通过宏定义点击事件处理方法。
来看一下 主要消息的处理宏展开是什么情况 wndProc-----> HandleMessage--->func1....funcn
----->CpaintManagerUI:MessageHandleer
----->CwindowWnd::HandleMessage:
(1)声明了几个函数参数
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) \
{ \
LRESULT lResult = 0; \
BOOL bHandled = FALSE; \
(uMsg); \
(wParam); \
(lParam);
(2)是自己感兴趣的消息的时候就使用 func执行处理并返回
#define UILIB_MESSAGE_HANDLER(msg, func) \
if(uMsg == msg) \
{ \
bHandled = TRUE; \
lResult = func(uMsg, wParam, lParam, bHandled); \
if(bHandled) \
return lResult; \
}
(3)使用两级处理 painterManager处理 , 最后执行 CWindWnd默认处理
#define UILIB_END_MSG_MAP()
\
if( bHandled ) \
return lResult; \
if( m_pm.MessageHandler(uMsg, wParam, lParam, lResult) ) \
return lResult;\
return DuiLib::CWindowWnd::HandleMessage(uMsg, wParam, lParam);\
}
再来看一下对 CPaintManagerUI::MessageHandler的处理。主要是定义 消息名字对应的消息处理函数。
typedef struct tagTNotifyUI
{
CDuiString sType;
CDuiString sVirtualWnd;
CControlUI* pSender; // 发送者 的消息名字
DWORD dwTimestamp;
POINT ptMouse;
WPARAM wParam;
LPARAM lParam;
} TNotifyUI;
(1)控件的Notify
#define UILIB_BEGIN_NOTIFY_MSG(clsName) \
void Notify(DuiLib::TNotifyUI& ui_msg) \
{\
(ui_msg);
(2)定义notif的处理函数。比较的是消息的类型
#define UILIB_CONTRL_MSG_NOTIFY(notify_name,func) \
if( ui_msg.sType == notify_name) \
return func(ui_msg);
// UILIB_CONTRL_MSG_NOTIFY(L"click",OnClick)
(3)结束 Notify函数
#define UILIB_END_NOTIFY_MSG() }
最后需要定义notify处理函数发生在特定控件上的处理函数,可以说是notify的相应链条的处理。
(1)
#define UILIB_BEGIN_IMPL_MSG_NOTIFY(func) \
void func(DuiLib::TNotifyUI& ui_msg)\
{
(2)比较消息中的发送者的名字是否与传递的控件名字相同
#define UILIB_CONTRL_MSG_HANDLER(msg_name,func) \
if( ui_msg.pSender->GetName() == msg_name) \
return func(ui_msg);
// UILIB_CONTRL_MSG_HANDLER(msg_name,func)
// UILIB_CONTRL_MSG_HANDLER(msg_name,func)
#define UILIB_END_IMPL_MSG_NOTIFY() }
实例:
UILIB_BEGIN_MSG_MAP(CCheckEodPwdDlg)
UILIB_MESSAGE_HANDLER(WM_CREATE,OnCreate)
UILIB_MESSAGE_HANDLER(WM_NCACTIVATE,OnNcActivate)
UILIB_MESSAGE_HANDLER(WM_NCCALCSIZE,OnNcCalcSize)
UILIB_MESSAGE_HANDLER(WM_NCPAINT,OnNcPaint)
UILIB_MESSAGE_HANDLER(WM_NCHITTEST,OnNcHitTest)
UILIB_MESSAGE_HANDLER(WM_SIZE,OnSize)
UILIB_MESSAGE_HANDLER(WM_KEYDOWN,OnKeyDown)
UILIB_MESSAGE_HANDLER(WM_CHECKEODPWD_EXIT,OnCheckEodPwdExit)
UILIB_MESSAGE_HANDLER(WM_CHECKEODPWD_SHOW,OnCheckEodPwdShow)
UILIB_END_MSG_MAP()
UILIB_BEGIN_NOTIFY_MSG(CCheckEodPwdDlg)
UILIB_CONTRL_MSG_NOTIFY(L"click",OnClick)
UILIB_CONTRL_MSG_NOTIFY(L"return",OnReturn)
UILIB_END_NOTIFY_MSG()
UILIB_BEGIN_IMPL_MSG_NOTIFY(OnClick)
UILIB_CONTRL_MSG_HANDLER(L"ButtonUIClose",OnClickCloseBtn)
UILIB_CONTRL_MSG_HANDLER(L"ButtonUIOK",OnClickOKBtn)
UILIB_CONTRL_MSG_HANDLER(L"ButtonUICancel",OnClickCancelBtn)
UILIB_END_IMPL_MSG_NOTIFY()
UILIB_BEGIN_IMPL_MSG_NOTIFY(OnReturn)
UILIB_CONTRL_MSG_HANDLER(L"EditUIPassWord",OnEditReturn)
UILIB_END_IMPL_MSG_NOTIFY()
宏展开后的代码:
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT lResult = 0; BOOL bHandled = 0; (uMsg); (wParam); (lParam);
if(uMsg == 0x0001) { bHandled = 1; lResult = OnCreate(uMsg, wParam, lParam, bHandled); if(bHandled) return lResult; }
if(uMsg == 0x0086) { bHandled = 1; lResult = OnNcActivate(uMsg, wParam, lParam, bHandled); if(bHandled) return lResult; }
if(uMsg == 0x0083) { bHandled = 1; lResult = OnNcCalcSize(uMsg, wParam, lParam, bHandled); if(bHandled) return lResult; }
if(uMsg == 0x0085) { bHandled = 1; lResult = OnNcPaint(uMsg, wParam, lParam, bHandled); if(bHandled) return lResult; }
if(uMsg == 0x0084) { bHandled = 1; lResult = OnNcHitTest(uMsg, wParam, lParam, bHandled); if(bHandled) return lResult; }
if(uMsg == 0x0005) { bHandled = 1; lResult = OnSize(uMsg, wParam, lParam, bHandled); if(bHandled) return lResult; }
if(uMsg == 0x0100) { bHandled = 1; lResult = OnKeyDown(uMsg, wParam, lParam, bHandled); if(bHandled) return lResult; }
if(uMsg == 0x0400 + 200) { bHandled = 1; lResult = OnCheckEodPwdExit(uMsg, wParam, lParam, bHandled); if(bHandled) return lResult; }
if(uMsg == 0x0400 + 201) { bHandled = 1; lResult = OnCheckEodPwdShow(uMsg, wParam, lParam, bHandled); if(bHandled) return lResult; }
if( bHandled ) return lResult; if( m_pm.MessageHandler(uMsg, wParam, lParam, lResult) ) return lResult; return DuiLib::CWindowWnd::HandleMessage(uMsg, wParam, lParam);}
void Notify(DuiLib::TNotifyUI& ui_msg) { (ui_msg);
if( ui_msg.sType == L"click") return OnClick(ui_msg);
if( ui_msg.sType == L"return") return OnReturn(ui_msg);
}
void OnClick(DuiLib::TNotifyUI& ui_msg) {
if( ui_msg.pSender->GetName() == L"ButtonUIClose") return OnClickCloseBtn(ui_msg);
if( ui_msg.pSender->GetName() == L"ButtonUIOK") return OnClickOKBtn(ui_msg);
if( ui_msg.pSender->GetName() == L"ButtonUICancel") return OnClickCancelBtn(ui_msg);
}
void OnReturn(DuiLib::TNotifyUI& ui_msg) {
if( ui_msg.pSender->GetName() == L"EditUIPassWord") return OnEditReturn(ui_msg);
}
那么到现在就可以完全理解了 duilib消息处理宏。
(1)处理常见的 WM_xxxx 使用 UILIB_MESSAGE_HANDLER(msg, func)
(2)处理控件类型的 使用 UILIB_CONTRL_MSG_NOTIFY(notify_name,func)---消息类型 , 此类型处理函数。
(3)处理xml中定义的空间的 函数使用 UILIB_CONTRL_MSG_HANDLER(msg_name,func)
整理下 notify的事件类型: duilib UIDefine.h中定义。
//定义所有消息类型
//////////////////////////////////////////////////////////////////////////
#define DUI_MSGTYPE_MENU (_T("menu"))
#define DUI_MSGTYPE_LINK (_T("link"))
#define DUI_MSGTYPE_TIMER (_T("timer"))
#define DUI_MSGTYPE_CLICK (_T("click"))
#define DUI_MSGTYPE_RETURN (_T("return"))
#define DUI_MSGTYPE_SCROLL (_T("scroll"))
#define DUI_MSGTYPE_DROPDOWN (_T("dropdown"))
#define DUI_MSGTYPE_SETFOCUS (_T("setfocus"))
#define DUI_MSGTYPE_KILLFOCUS (_T("killfocus"))
#define DUI_MSGTYPE_ITEMCLICK (_T("itemclick"))
#define DUI_MSGTYPE_TABSELECT (_T("tabselect"))
#define DUI_MSGTYPE_ITEMSELECT (_T("itemselect"))
#define DUI_MSGTYPE_ITEMEXPAND (_T("itemexpand"))
#define DUI_MSGTYPE_WINDOWINIT (_T("windowinit"))
#define DUI_MSGTYPE_BUTTONDOWN (_T("buttondown"))
#define DUI_MSGTYPE_MOUSEENTER (_T("mouseenter"))
#define DUI_MSGTYPE_MOUSELEAVE (_T("mouseleave"))
#define DUI_MSGTYPE_TEXTCHANGED (_T("textchanged"))
#define DUI_MSGTYPE_HEADERCLICK (_T("headerclick"))
#define DUI_MSGTYPE_ITEMDBCLICK (_T("itemdbclick"))
#define DUI_MSGTYPE_SHOWACTIVEX (_T("showactivex"))
#define DUI_MSGTYPE_ITEMCOLLAPSE (_T("itemcollapse"))
#define DUI_MSGTYPE_ITEMACTIVATE (_T("itemactivate"))
#define DUI_MSGTYPE_VALUECHANGED (_T("valuechanged"))
#define DUI_MSGTYPE_SELECTCHANGED (_T("selectchanged"))
最精简的就是 实现
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
void Notify(DuiLib::TNotifyUI& ui_msg)
而不用实现宏,duilib源码demo中可窥探出来