2013 duilib入门简明教程 -- 事件处理和消息响应 (17)
界面的显示方面就都讲完啦,下面来介绍下控件的响应。
前面的教程只讲了按钮和Tab的响应,即在Notify函数里处理。其实duilib还提供了另外一种响应的方法,即消息映射DUI_BEGIN_MESSAGE_MAP,可以将DUI_MSGTYPE_CLICK消息映射到指定的函数(比如OnClick),这和在Notify判断msg.sType是一样的效果,具体请参见duilib的RichListDemo。
先看看下面几段代码:
DUI_BEGIN_MESSAGE_MAP(CPage1, CNotifyPump)
DUI_ON_MSGTYPE(DUI_MSGTYPE_CLICK,OnClick)
DUI_ON_MSGTYPE(DUI_MSGTYPE_SELECTCHANGED,OnSelectChanged)
DUI_ON_MSGTYPE(DUI_MSGTYPE_ITEMCLICK,OnItemClick)
DUI_END_MESSAGE_MAP()
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT lRes = 0; BOOL bHandled = TRUE; switch (uMsg) { case WM_KEYDOWN: lRes = OnKeyDown(uMsg, wParam, lParam, bHandled); break; case WM_LBUTTONDOWN: lRes = OnLButtonDown(uMsg, wParam, lParam, bHandled); break; case WM_MOUSEMOVE: lRes = OnMouseMove(uMsg, wParam, lParam, bHandled); break; default: bHandled = FALSE; break; } if (bHandled) return lRes; return CWindowWnd::HandleMessage(uMsg, wParam, lParam); }
void Notify(TNotifyUI& msg) { if( msg.sType == _T("windowinit") ) { } else if( msg.sType == _T("click") ) { } }
我们再来看看MFC的两段代码:
BEGIN_MESSAGE_MAP(CMFCDlg, CDialog) ON_BN_CLICKED(IDC_BUTTON_ADD_FILES, &CMFCDlg::OnBnClickedButtonAddFiles) ON_BN_CLICKED(IDC_BUTTON_CLEAR_FILES, &CMFCDlg::OnBnClickedButtonClearFiles) ON_BN_CLICKED(IDC_BUTTON_DELETE_FILES, &CMFCDlg::OnBnClickedButtonDeleteFiles) END_MESSAGE_MAP()
LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) { LRESULT lRes = 0; switch (uMsg) { case WM_KEYDOWN: lRes = OnKeyDown(uMsg, wParam, lParam, bHandled); break; case WM_LBUTTONDOWN: lRes = OnLButtonDown(uMsg, wParam, lParam, bHandled); break; case WM_MOUSEMOVE: lRes = OnMouseMove(uMsg, wParam, lParam, bHandled); break; default: break; } return CDialog::DefWindowProc(uMsg, wParam, lParam); }
很明显,duilib参考了MFC、ATL/WTL的消息机制:
1、DUI_BEGIN_MESSAGE_MAP类似于MFC的BEGIN_MESSAGE_MAP。
2、HandleMessage类似于MFC的DefWindowProc。
不过需要注意参数bHandled,这个参数是模仿ATL的。bHandled在ATL中的作用如下:
在消息响应函数调用前被ATL设置为TRUE,如果在你的消息响应处理完之后需要ATL调用默认的WindowProc()处理该消息,你可以将bHandled设置为FALSE。这与MFC不同, MFC是显式地调用基类的响应函数来实现的默认的消息处理的。
3、不过duilib还提供了另外一个函数,即Notify函数,Notify用于处理duilib自己定义的一套消息,其消息类型请参见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"))
到这里,duilib的消息机制就很明朗啦,只要熟悉windows消息机制的,稍微看看Demo就懂啦;不熟悉windows消息机制的,一时半会就说不清楚啦,还请先学习好 【2013 duilib入门简明教程 -- VS环境配置(2)】中推荐的资料吧~O(∩_∩)O~