duilib 消息循环机制

1 消息处理

​ 在duilib中我们一般会创建一个继承WindowImplBase的窗口,然后重写Notify函数,在Notify函数中处理控件消息,比如button的消息类型就是click,代码如下所示:

class MyWnd :public DuiLib::WindowImplBase{
   
    ...
    virtual void Notify(DuiLib::TNotifyUI& msg) override;
};
void MyWnd::Notify(DuiLib::TNotifyUI& msg)
{
   
     if (msg.sType == _T("click")){
   }
}

​ 那么内部是怎么调用notify这个函数进行消息通知的呢?

2 Notify调用过程

​ 以button的点击消息为例,在notify函数中打上断点,点击按钮,堆栈信息如下:
在这里插入图片描述

​ 通过堆栈信息,我们就可以很清晰的看到消息传递过程,从下往上看。

2.1 MessageLoop

​ 在使用duilib中,我们会使用DuiLib::CPaintManagerUI::MessageLoop()来接收系统消息,代码实现如下:

void CPaintManagerUI::MessageLoop()
{
   
    MSG msg = {
    0 };
    while( ::GetMessage(&msg, NULL, 0, 0) ) {
   
        if( !CPaintManagerUI::TranslateMessage(&msg) ) {
   
            ::TranslateMessage(&msg);
            try{
   
                ::DispatchMessage(&msg);
            } catch(...) {
   
                DUITRACE(_T("EXCEPTION: %s(%d)\n"), __FILET__, __LINE__);
#ifdef _DEBUG
                throw "CPaintManagerUI::MessageLoop";
#endif
            }
        }
    }
}

​ 基本流程和win32程序差不多。通常我们写win32程序的时候,会通过GetMessage获取消息队列所有的消息,再通过TranslateMessage转义消息,DispatchMessage分发消息,最后通过注册一个回调函数来处理消息。

​ 通过堆栈信息显示停留在堆栈显示停留在 ::DispatchMessage(&msg)这一行,那么duilib肯定也注册了一个回调函数来处理系统消息,通过堆栈可以发现是__WndProc

2.2 __WndProc

​ __WndProc的实现思路就是先获取窗口指针,然后调用窗口各自的HandleMessage函数处理消息,代码如下:

LRESULT CALLBACK CWindowWnd::__WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   
    CWindowWnd* pThis = NULL;
    if( uMsg == WM_NCCREATE ) {
   
        LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
        pThis = static_cast<CWindowWnd*>(lpcs->lpCreateParams);
        pThis->m_hWnd = hWnd;
        ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LPARAM>(pThis));
    } 
    else {
   
        pThis = reinterpret_cast<CWindowWnd*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
        if( uMsg == WM_NCDESTROY && pThis != NULL ) {
   
            LRESULT lRes = ::CallWindowProc(pThis->m_OldWndProc, hWnd, uMsg, wParam, lParam)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值