您的位置:首页 > 产品设计 > UI/UE

Duilib学习笔记《05》— 消息响应处理

2014-12-28 10:10 337 查看
Duilib学习笔记《04》中已经知道了如何将窗体显示出来,而如何处理窗体上的事件、消息呢?


一. 系统消息

窗体显示的时候我们就已经说了,窗体是继承CWindowWnd类的,对于窗体的部分消息的处理,需要重载该类的LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); 函数。在显示窗体部分我们创建窗体WM_CREATE消息以及屏蔽标题栏WM_NCACTIVATE、WM_NCCALCSIZE、WM_NCPAINT等消息 都是在HandleMessage中进行处理:

1
LRESULT

CMainWndDlg::HandleMessage(
UINT

uMsg,
WPARAM

wParam,
LPARAM

lParam )
2
{
3
LRESULT

lRes = 0;
4
BOOL

bHandled = TRUE;
5
6
switch
(
uMsg )
7
{
8
case


WM_CREATE:lRes = OnCreate(uMsg, wParam, lParam, bHandled);
break
;
9
case


WM_NCACTIVATE:lRes = OnNcActivate(uMsg, wParam, lParam, bHandled);
break
;
10
case


WM_NCCALCSIZE:lRes = OnNcCalcSize(uMsg, wParam, lParam, bHandled);
break
;
11
case


WM_NCPAINT: lRes = OnNcPaint(uMsg, wParam, lParam, bHandled);
break
;
12
case


WM_NCHITTEST: lRes = OnNcHitTest(uMsg, wParam, lParam, bHandled);
break
;
13
case


WM_CLOSE: lRes = OnClose(uMsg, wParam, lParam, bHandled);
break
;
14
case


WM_DESTROY: lRes = OnDestroy(uMsg, wParam, lParam, bHandled);
break
;
15
case


WM_SIZE: lRes = OnSize(uMsg, wParam, lParam, bHandled);
break
;
16
case

WM_GETMINMAXINFO: lRes = OnGetMinMaxInfo(uMsg, wParam, lParam, bHandled);

break
;
17
case


WM_SYSCOMMAND:lRes = OnSysCommand(uMsg, wParam, lParam, bHandled);
break
;
18
case


WM_KEYDOWN: PostQuitMessage(0);
break
;
19
default
:
20
bHandled
= FALSE;
21
}
22
23
if
(
bHandled )
return

lRes;
24
if
(
m_PaintManager.MessageHandler(uMsg, wParam, lParam, lRes) )
return

lRes;
25
26
return

CWindowWnd::HandleMessage(uMsg, wParam, lParam);
27
}
如同代码中所示,如果消息不需要框架再处理了则直接返回。如果还需要框架处理该消息,则交由父类的HandleMessge中去处理。

二. 事件消息

对于系统消息我们直接重载了HandleMessage来处理,而对于鼠标点击一类的消息呢?为此,我们的窗体除了要继承CWindowWnd外,还需要继承INotifyUI,同样的重载INotifyUI类中的void Notify(TNotifyUI& msg); 函数,由该函数来处理控件操作产生的消息。但仅仅只是继承重载了还不够,我们怎么才能确保事件消息能正常传递呢?因此,在窗体创建OnCreate的时候,我们还需要添加如下m_PaintManager.AddNotifier(this); 这样,控件消息就可以传达大duilib的消息循环中,我们也就可以通过Notify函数对消息进行处理:

1
void

CMainWndDlg::Notify( TNotifyUI& msg )
2
{
3
if
(
msg.sType == _T(
"windowinit"
)
) {
4
OnWindowInit();
5
}
6
else

if
(
msg.sType == _T(
"click"
)
) {
7
if
(
msg.pSender == m_pCloseBtn ) {
8
PostQuitMessage(0);
9
return
;
10
}
11
else

if
(
msg.pSender == m_pMinBtn ) {
12
SendMessage(WM_SYSCOMMAND,
SC_MINIMIZE, 0);
return
;}
13
else

if
(
msg.pSender == m_pMaxBtn ) {
14
SendMessage(WM_SYSCOMMAND,
SC_MAXIMIZE, 0);
return
;}
15
else

if
(
msg.pSender == m_pRestoreBtn ) {
16
SendMessage(WM_SYSCOMMAND,
SC_RESTORE, 0);
return
;}
17
18
//
按钮消息
19
OnLBtnClick(msg.pSender);
20
}
21
else

if
(msg.sType==_T(
"selectchanged"
))
22
{
23
CDuiString
name = msg.pSender->GetName();
24
CTabLayoutUI*
pTabSwitch =
static_cast
<CTabLayoutUI*>(m_PaintManager.FindControl(_T(
"tab_switch"
)));
25
CTabLayoutUI*
pDemoListSwitch =
static_cast
<CTabLayoutUI*>(m_PaintManager.FindControl(_T(
"demo_list_tab_switch"
)));
26
27
if
(name.CompareNoCase(_T(
"demo_tab"
))
== 0)
28
pTabSwitch->SelectItem(0);
29
else

if
(name.CompareNoCase(_T(
"web_tab"
))
== 0) 
30
pTabSwitch->SelectItem(1);
31
32
if
(name.CompareNoCase(_T(
"demo_list_basic_ctrl"
))
== 0)
33
pDemoListSwitch->SelectItem(0);
34
else

if
(name.CompareNoCase(_T(
"demo_list_rich_ctrl"
))
== 0)
35
pDemoListSwitch->SelectItem(1);
36
}
37
}
在Notify函数中针对消息的不同进行不同的操作处理,比如click、selectchanged等等。对于这类duilib针对相关操作自定义的消息类型可以在duilib工程中的UIDefine.h文件中查看:

1
//定义所有消息类型
2
//////////////////////////////////////////////////////////////////////////
3
4
#define
DUI_MSGTYPE_MENU (_T("menu"))
5
#define
DUI_MSGTYPE_LINK (_T("link"))
6
7
#define
DUI_MSGTYPE_TIMER (_T("timer"))
8
#define
DUI_MSGTYPE_CLICK (_T("click"))
9
10
#define
DUI_MSGTYPE_RETURN (_T("return"))
11
#define
DUI_MSGTYPE_SCROLL (_T("scroll"))
12
13
#define
DUI_MSGTYPE_DROPDOWN (_T("dropdown"))
14
#define
DUI_MSGTYPE_SETFOCUS (_T("setfocus"))
15
16
#define
DUI_MSGTYPE_KILLFOCUS (_T("killfocus"))
17
#define
DUI_MSGTYPE_ITEMCLICK (_T("itemclick"))
18
#define
DUI_MSGTYPE_TABSELECT (_T("tabselect"))
19
20
#define
DUI_MSGTYPE_ITEMSELECT (_T("itemselect"))
21
#define
DUI_MSGTYPE_ITEMEXPAND (_T("itemexpand"))
22
#define
DUI_MSGTYPE_WINDOWINIT (_T("windowinit"))
23
#define
DUI_MSGTYPE_BUTTONDOWN (_T("buttondown"))
24
#define
DUI_MSGTYPE_MOUSEENTER (_T("mouseenter"))
25
#define
DUI_MSGTYPE_MOUSELEAVE (_T("mouseleave"))
26
27
#define
DUI_MSGTYPE_TEXTCHANGED(_T("textchanged"))
28
#define
DUI_MSGTYPE_HEADERCLICK(_T("headerclick"))
29
#define
DUI_MSGTYPE_ITEMDBCLICK(_T("itemdbclick"))
30
#define
DUI_MSGTYPE_SHOWACTIVEX(_T("showactivex"))
31
32
#define
DUI_MSGTYPE_ITEMCOLLAPSE (_T("itemcollapse"))
33
#define
DUI_MSGTYPE_ITEMACTIVATE (_T("itemactivate"))
34
#define
DUI_MSGTYPE_VALUECHANGED (_T("valuechanged"))
35
36
#define
DUI_MSGTYPE_SELECTCHANGED (_T("selectchanged"))
37
38
//////////////////////////////////////////////////////////////////////////

三. 消息过滤

在实际中,我们有时候可能需要根据需要对部分消息进行分类处理。比如键盘按键消息等等。对于这类情况,我们的窗体需要继承IMessageFilterUI类,重载LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam,
bool& bHandled)函数,同时在窗体OnCreate创建的时候添加m_pm_.AddPreMessageFilter(this)消息通知即可。

0

>> 本文固定链接: http://www.who1753.com/duilib-study-05.html

>> 转载请注明: who1753 2014年01月17日 于 WHO1753 发表
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: