Fly Pigeon Biography Source Analysis two message mechanism

Source: Internet
Author: User
Tags bool inheritance

http://blog.csdn.net/mxway/article/details/40225725



This article is an analysis of the basis of the 2.06 source code in the Flying Pigeon biography.

The message of flying pigeon biography can be broadly divided into three categories: Ordinary window class (followed by Tmainwin for analysis) message, dialog Class (followed by Tsenddlg as an example for analysis) message, dialog box control (following the example of Teditsub for analysis) message. These three types of messages first, the three types of window set the message handler function is Tapp::winproc, in the Tapp::winproc function and then distributed to the respective message handler function


Figure 1: Message processing

First look at the inheritance of the three types of Windows


Figure 2:tmainwin Inheritance relationship of class


Figure 3:tsenddlg Inheritance Relationship


Figure 4:teditsub Inheritance Relationship

As you can see from the three graphs above, twin is the root class of all window classes. That is, in the Fly Pigeon book source, all the windows need to inherit the twin class. Flying Pigeon Biography All messages are in the WinProc function passed Tapp::winproc to Twin::winproc or its subclasses.

Twin::winproc part of the source code is as follows:[CPP] View Plain copy Lresult twin::winproc (Uint umsg, wparam wparam, lparam lparam)    {       BOOL    done = FALSE;        LRESULT result = 0;           switch (umsg)        {       case wm_create :           done = evcreate (LParam);           break;            case WM_MOUSEMOVE:           done =  Evmousemove (UINT) wparam, makepoints (lParam));            break;       case WM_LBUTTONUP:        Case wm_rbuttonup:       case WM_NCLBUTTONUP:   &NBSP;&NBSP;&NBSP;&NBSP;CASE&NBSP;WM _ncrbuttonup:       case WM_LBUTTONDOWN:        case wm_rbuttondown:       case WM_NCLBUTTONDOWN:        case WM_NCRBUTTONDOWN:   &NBSP;&NBSP;&NBSP;&NBSP;CASE&NBSP;WM_LBUTTONDBLCLK:        case WM_RBUTTONDBLCLK:       case  wm_nclbuttondblclk:       case WM_NCRBUTTONDBLCLK:            done = eventbutton (Umsg, wparam, makepoints (LParam));            break;       default:            if  (umsg >= wm_user & & umsg < 0x7fff | | &NBSP;UMSG&NBSP;&GT;=&NBSP;0XC000&NBSP;&AMP;&AMP;&NBSP;UMSG&NBSP;&LT;=&NBSP;0XFFFF)                 result = done = eventuser (UMSG ,  wparam, lparam);           break;       }       return  done ? result :  defwindowproc (Umsg, wparam, lparam);  }   from the above can be seen twin wm_ Create message to evcreate function processing, wm_mousemove message to Evmousemove processing, the mouse key or double-click and other events referred to Eventbutton processing, for user-defined events to Eventuser processing.

First, the Tmainwin message processing

In the previous article Flying Pigeon Book program started process mentioned Tmsgapp::initwindow, in this method has the following code

[CPP] view plain copy void tmsgapp::initwindow (void)    {        wc.lpfnWndProc      = TApp::WinProc;            ...       wc.lpszClassName     = class_name;           ...        mainwnd = new tmainwin (nicaddr, port_no);        mainwnd->create (class_name, ip_msg, ws_overlappedwindow |  (IsNewShell ()  ?  ws_minimize : 0);  }   This is the function that creates the main window of the Flying Pigeon book and sets the message response function of the main window to Tapp:winproc. Message processing function comes out, then the message loop and message distribution processing where. Go back to the previous article on the program initiation process of flying pigeon biography. Call Tapp::initapp in the Tapp::run function, and then call the Tmsgapp::initwindow function for the reason of the virtual function. After calling the Tmsgapp::initwindow and then returning to the Tapp::run method to continue with the following code, the code behind Tapp::run is the message loop and distribution. The following is the source code for the Tapp:run function

[CPP] View plain copy int tapp::run (void)    {       MSG      msg;          initapp ();        Initwindow ();          while  (:: GetMessage (&msg, null,  0, 0)        {            if  (Preprocmsg (&msg))                 continue;              :: TranslateMessage (&msg);           ::D ispatchmessage (& msg);       }          return   msg.wparam;  }   Tmainwin's Message handler function and message distribution are all set, and the message handler we set is Tapp::winproc. So Tapp::winproc is how to identify the window that is Tmainwin and put the message atThe Tmainwin function to go to the. First look at the source of Tapp::winproc

[CPP] View Plain copy Lresult callback tapp::winproc (hwnd hwnd, uint umsg, wparam  Wparam, lparam lparam)    {       TWin *win =  Searchwnd (hWnd);          if  (win)             return  win->winproc (Umsg, wparam, lparam);          if  ((win = prewnd)  != null)         {           preWnd = NULL;            addwinbywnd (win, hwnd);            return  win->winproc (Umsg, wparam, lparam);        }          return  defwindowproc (hwnd, Umsg, wparam, lparam);  }   flies all the windows that need to be processed are added to the Wndarray member variable of the Tapp. The search method is returned from the Wndarray found in the twin object found in the window handle as an HWND. Now find the object of Tmainwin win, call Win->winproc (Umsg,wparam,lparam). Because the Tmainwin inherits the Twin class, the WinProc of the twin class is a virtual function, so win->winproc is equivalent to the Tmainwin method of calling WinProc, and this Tmainwin message is Tapp: The WinProc is then returned to the Tmainwin class for processing. Note: In order to simplify the problem, if (Win=prewnd)!=null) This code is not analyzed, this code is actually the Tmainwin window first message processing of the special judgment.

Second, TSENDDLG message processing

The dialog is divided into modal dialogs and non-modal dialog boxes. The Create modal dialog box uses the Createdialog () of the win API, and the DialogBox (). As can be seen from Figure 2 and Figure 3, Tmainwin and Tdlg inherit the twin class, so how to call the CREATE function is a normal window or create a dialog box.

[CPP] View Plain copy bool twin::create (Lpcstr classname, lpcstr title, dword style,  dword exstyle, hmenu hmenu)    {       if  ( Classname == null)            className =  TAPP::d efaultclass;          tapp::addwin (this);          if  (Hwnd = ::createwindowex (exstyle, classname, title,  Style, rect.left, rect.top, rect.right, rect.bottom, parent ? parent-> Hwnd : null, hmenu, tapp::hi, null)  == null)             return  tapp::D Elwin (this), false;        else           return  TRUE;  }   
[CPP] View Plain copy bool tdlg::create (hinstance hinstance)    {        Tapp::addwin (This);          if  ((Hwnd = ::createdialog ( hinstance ? hinstance : tapp::hi, resid ?  (LPCSTR) resId : resName , parent ? parent->hwnd : null,  (Dlgproc) tapp::winproc))  == NULL)            return  tapp::D Elwin (this), FALSE;        else           return   TRUE;  }   Twin Create is a virtual function, Tdlg inherits twin and writes the CREATE function. The object that creates the Tdlg will then call the Createdialog Create dialog box, and for other inherited twin, the class that does not override the CREATE function is called twin create creates a normal window. The message handler function for the dialog box set in Createdialog in Tdlg::create is the Tapp::winproc method, which is called before Tapp::addwin (this) Adds the created dialog object to the Wndarray member variable of Tapp. Similar to the message processing of the Tmainwin window, the Message for the dialog box is preceded by Tapp::winproc. It is then passed to the Tdlg for processing.There is also a very important question: the dialog box has Wm_initdialog and so on the message is ordinary window does not have, how to deal with these messages. Through the above analysis we know that by overriding the WinProc virtual function of the twin class.
[CPP] View Plain copy Lresult tdlg::winproc (Uint umsg, wparam wparam, lparam lparam)    {       LRESULT result = 0;          switch  (umsg)        {        case WM_INITDIALOG:           return   Evcreate (lParam);                    ...       case WM_ENDSESSION:            evendsession (BOOL) wparam,  (BOOL) lParam);            return  0;                    ...            } &nBsp }   Three, teditsub window message processing

In the Tsenddlg dialog box, there is a text box control that has a function of selecting the contents of the text box when you double-click it in the text box. The Tsenddlg dialog box only has message handling for the dialog box, so how the message for the text box in the dialog box is handled

The following code is in the Evcreate function of Tsenddlg

[CPP] view plain copy BOOL tsenddlg::evcreate (LPARAM LPARAM) {... editsub.createbywnd (getdlgit           EM (send_edit));   ...   } Teditsub inherits the Tsubclass class and does not rewrite the Createbywnd

[CPP] view plain copy BOOL Tsubclass::createbywnd (HWND _hwnd) {Tapp::addwinbywnd (this, _hwnd); return (Oldproc = (WNDPROC):: SetWindowLong (_hwnd, GWL_WNDPROC, (LONG) tapp::winproc))?   True:false; This function is to set Teditsub's message handler function to Tapp::winproc. Similar to the process of the previous two windows, the Teditsub message is first uploaded to the Tapp::winproc and then processed in the Teditsub window class. Note: Using the SetWindowLong method to set Gwl_wndproc to Tapp::winproc, there are no messages processed in the Tapp::winproc (actually the message handler function of the Teditsub window class). You must use the CallWindowProc function to call SetWindowLong before the message handler function, and if you do not use CallWindowProc, even defwindowproc with the win API will appear as if the text box cannot be displayed.

The Eventbutton function is overridden in teditsub.

[CPP]

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.