Turn
Look at the Cwindowwnd class and the Cpaintmanagerui class is how to carry out the message distribution bar.
1. First look at the Messageloop function of the Cpaintmanagerui class:
- void Cpaintmanagerui::messageloop ()
- {
- msg msg = {0};
- While (:: GetMessage (&msg, NULL, 0, 0)) { //Get message
- if (! Cpaintmanagerui::translatemessage (&msg)) { //message filtering
- :: TranslateMessage (&MSG);
- ::D ispatchmessage (&msg); //Distributed to the window's Message processing window. That is, call the __wndproc function of the Cwindowwnd class or the __controlproc function.
- }
- }
- }
The message is first received by the Cpaintmanagerui class's TranslateMessage message.
2. Call Cwindowwnd::create to create the window. Complete the following actions:
1) If you want the control of the window under the sub-class (that is, the control of the system, not the Duilib simulation control), set the __controlproc function as the message callback function.
2) do not subclass, just register the window class. This setting __wndproc the callback function for the window message processing.
3) Create a window with the CreateWindowEx API function.
First of all, I would like to look at the standard window creation process first, without looking at the sub-class related. The message will be distributed to __wndproc after the operation.
3. Look at the definition of the __wndproc function:
- LRESULT CALLBACK Cwindowwnd::__wndproc (hwnd hwnd, UINT umsg, WPARAM WPARAM, LPARAM LPARAM)
- {
- cwindowwnd* pThis = NULL;
- if (umsg = = wm_nccreate) { //To bind the class to a window in this message
- Lpcreatestruct lpcs = reinterpret_cast<lpcreatestruct> (lParam); //From the last parameter of the CreateWindowEx function (that is, the Cwindowwnd object pointer)
- PThis = static_cast<cwindowwnd*> (lpcs->lpcreateparams);
- Pthis->m_hwnd = hWnd;
- :: Setwindowlongptr (HWnd, Gwlp_userdata, reinterpret_cast<lparam> (pThis)); //Set to the user data in the window
- }
- 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); //Receive the last message that the window can handle and the finishing touches.
- :: Setwindowlongptr (Pthis->m_hwnd, Gwlp_userdata, 0L); //Cancels the binding relationship of the class object to the window
- if (pthis->m_bsubclassed) Pthis->unsubclass ();
- Pthis->m_hwnd = NULL;
- Pthis->onfinalmessage (HWND);
- return lres;
- }
- }
- if (pThis! = NULL) {
- return Pthis->handlemessage (umsg, WParam, LParam); //Call the message handler function of the inheriting class here
- }
- else {
- return::D efwindowproc (HWnd, umsg, WParam, LParam); //Unbound class object, the default window message handler function is called
- }
- }
The message is received by __wndproc the second time and then passed to the Handlermessage function of the Cwindowwnd class.
3. See the implementation of the Cwindowwnd class's inheritance class for handlermessage virtual functions.
- LRESULT cmainwnd::handlemessage ( UINT umsg, WPARAM WPARAM, LPARAM LPARAM)
- {
- LRESULT lres = 0; //Message processing return value.
- BOOL bhandled = TRUE; //Whether the message continues to pass.
- switch (umsg)
- {
- Case wm_create:lres = Oninitresource (bhandled); Break ; //Perform initialization work. For example, the most important XML load parsing work.
- Default:
- bhandled = FALSE;
- }
- if (bhandled)
- {
- return lres;
- }
- if (m_pm. MessageHandler (umsg, WParam, LParam, lres)) //pass to Cpaintmanagerui::messagehandler function for specific control processing work
- {
- return lres;
- }
- return Cwindowwnd::handlemessage (umsg, WParam, LParam); //Not processed call the default message handler for the Cwindowwnd class.
- }
Here is the user to press the message for specific processing. The MessageHandler function is then uploaded to the Cpaintmanagerui class object. The unhandled message will be returned to the default message handler for the Cwindowwnd class.
4. The contents of the TranslateMessage, MessageHandler function of the Cpaintmanagerui class.
- BOOL cpaintmanagerui::translatemessage (const lpmsg PMSG)
- {
- HWND hwndparent =:: GetParent (Pmsg->hwnd); //Gets the parent window of the message receiving window
- UINT Ustyle = Getwindowstyle (Pmsg->hwnd); //Get the style of the window
- LRESULT lres = 0;
- For ( int i = 0; i < m_apremessages.getsize (); i++) { //This m_apremessage holds the Cpaintmanagerui class object.
- cpaintmanagerui* PT = static_cast<cpaintmanagerui*> (m_apremessages[i]);
- if (Pmsg->hwnd = = Pt->getpaintwindow () //message belongs to the current Cpaintmanagerui bound window
- || (hwndparent = = Pt->getpaintwindow () && ((Ustyle & ws_child)! = 0))) //message is a message for the window in the current window (such as an ActiveX control)
- {
- if (Pt->premessagehandler (Pmsg->message, Pmsg->wparam, Pmsg->lparam, lres)) return TRUE; //The Premessagehandler filter function is called at this time.
- }
- }
- return FALSE;
- }
M_apremessage is a static member variable that is added to this variable at Cpaintmanagerui::init window with such binding.
5. Cpaintmanagerui::P Remessagehandler message Filter function.
- BOOL Cpaintmanagerui::P remessagehandler (UINT umsg, WPARAM WPARAM, LPARAM LPARAM, lresult&/ * lres*/)
- {
- //Traverse the current message filter list. The M_apremessagefilter element is the Imessagefilterui interface. Only one virtual function MessageHandler.
- //The user can add an inherited class variable for this interface to the M_apremessagefilters list. (Call addmessagefilter function Implementation)
- For ( int i = 0; i < m_apremessagefilters.getsize (); i++)
- {
- BOOL bhandled = FALSE;
- LRESULT LRESULT = static_cast<imessagefilterui*> (m_apremessagefilters[i])->messagehandler (UMSG, WParam, LParam, bhandled);
- if (bhandled) {
- return TRUE;
- }
- }
- //The following is a filter for several key messages.
- //Wm_keydown Check if the Vk_tab key is being moved for the control focus.
- //Wm_syschar Gets the control that matches the character accelerator key in wparam and activates it.
- //Wm_syskeydown Generate control events (simulated with Teventui)
- }
5. Cpaintmanagerui::messagehandler function.
1) Iterate through the Imessagefilterui interface in the M_amessagefilters list and invoke the MessageHandler function to perform the related message filtering function again. (similar to the m_apremessagefilters above)
2) The WM_PAINT message of the window will be processed here. Displays the appearance and status of all controls.
3) handle mouse events to implement control activation and related events.
4) Processing Wm_timer messages, all controls to use Cpaintmanagerui SetTimer, KillTimer and other functions to implement the timer function.
5) Processing custom messages for the Cpaintmanagerui class, Wm_app + 1 and +2,
Wm_app + 1 is used for control delay destroying control object
Wm_app + 2 destroys processing of asynchronous messages.
(Asynchronous control messages use the Cpaintmanagerui::sendnotify function to add a message object to the M_aasyncnotify list, and then postmessage the function Wm_app + 2)
5) Processing of other basic window related messages.
Cpaintmanagerui the event function of the Ccontrolui class in the form of teventui structure, the Duilib internal events are posted.
Duilib Library Analysis: Message flow Analysis