WM_PAINT message of duilib CPaintManagerUI
Some time ago, I studied duilib's plotting mechanism. After a while, I felt I forgot a lot. I wrote a blog and recorded it so that I could not read the source code later. Simply go through the blog.
WM_PAINT is divided into two parts: the first part is the control layout, and the second part is the interface update.
Control Layout
Containers are at the top of duilib, which mainly contain various controls. Of course, containers can also be nested.
If the upper-level containers need to be laid out, update the upper-level container location, that is, the setpos function.
The responsibility of the setpos function of the container is to maintain the position of the sub-control and prepare for future closer controls.
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); } } }
Interface update
After the layout is complete, the interface is refreshed. The refreshing interface is similar to the layout. The DoPaint function is used, and the subclass of the container maintenance period is updated.
Here we will not describe it much. The DoPaint function prototype is like this:
void CContainerUI::DoPaint(HDC hDC, const RECT& rcPaint)
The first is the dual-buffer handle (if dual-buffer is enabled), followed by a parent control area.
Anyone familiar with the mfc dialog box knows that there is an OnPaint function, where we plot.
This DoPaint function is similar to the OnPaint function. We can perform some plotting operations.
Duilib controls are also drawn on this hdc.
Write a gif control in MFC. The following steps are taken:
1. inherit from cwnd to write a Control
2. Use the settimer function to add a timer.
3. Add the InvaldateRect function to the timer.
4. Draw the current frame in the OnPaint Function
Imitating the operations we use in mfc, we can perform some animation operations in duilib.