duilib CPaintManagerUI的WM_PAINT消息

前段时间研究duilib绘图机制,由于忙了一段时间,感觉又忘记了不少,写个博客,记录一下,免得以后又看源码。直接翻博客就行了。


WM_PAINT 分为两部分,第一部分为:  控件 布局, 第二部分为:界面更新。

控件布局

duilib里面最上层的 是容器 , 容器里面主要包含各种控件,当然也可以嵌套容器。

如果最上层的容器需要布局,那就更新最上层容器 位置,即setpos函数。

容器的setpos函数 一个责任那就是维护子控件的位置,为以后更近控件做准备。


            if( m_bUpdateNeeded ) 
			{
                m_bUpdateNeeded = false;
                RECT rcClient = { 0 };
                ::GetClientRect(m_hWndPaint, &rcClient);
                if( !::IsRectEmpty(&rcClient) ) 
				{
                    if( m_pRoot->IsUpdateNeeded() ) 
					{
                        m_pRoot->SetPos(rcClient);
                        if( m_hDcOffscreen != NULL ) ::DeleteDC(m_hDcOffscreen);
                        if( m_hDcBackground != NULL ) ::DeleteDC(m_hDcBackground);
                        if( m_hbmpOffscreen != NULL ) ::DeleteObject(m_hbmpOffscreen);
                        if( m_hbmpBackground != NULL ) ::DeleteObject(m_hbmpBackground);
                        m_hDcOffscreen = NULL;
                        m_hDcBackground = NULL;
                        m_hbmpOffscreen = NULL;
                        m_hbmpBackground = NULL;
                    }
                    else 
					{
                        CControlUI* pControl = NULL;
                        while( pControl = m_pRoot->FindControl(__FindControlFromUpdate, NULL, UIFIND_VISIBLE | UIFIND_ME_FIRST) ) 
						{
                            pControl->SetPos( pControl->GetPos() );
                        }
                    }
                    // We'll want to notify the window when it is first initialized
                    // with the correct layout. The window form would take the time
                    // to submit swipes/animations.
                    if( m_bFirstLayout ) 
					{
                        m_bFirstLayout = false;
                        SendNotify(m_pRoot, DUI_MSGTYPE_WINDOWINIT,  0, 0, false);
                    }
                }
            }



界面更新

布局完成之后就是刷新界面,刷新界面机制和布局一样,使用的是DoPaint函数,同样容器维护期子类的更新。

这里就不在多描述了,DoPaint函数原型是这样的:

void CContainerUI::DoPaint(HDC hDC, const RECT& rcPaint)

第一个是 双缓冲句柄(如果开启双缓冲的话),后面有个是父控件的区域。

熟悉mfc对话框的都知道有一个OnPaint函数,我们绘图就是在这里面进行的。

这个DoPaint函数和OnPaint函数函数类似,我们可以进行一些 绘图操作。

duilib的控件也是在这个hdc上面绘图。

在MFC里面,写一个gif控件 ,分下面几个步骤

1.继承cwnd 写一个控件控件

2使用settimer函数添加一个定时器

3.定时器里面添加 InvaldateRect函数

4.在OnPaint函数里面 绘制当前帧


模仿我们在mfc里面的使用操作,我们可以再duilib里面做一些动画操作。










你可能感兴趣的:(duilib CPaintManagerUI的WM_PAINT消息)