Abstract:Message-driven mechanism is fundamental to the Windows operating system, and Message Processing in modal dialogs is different from the special form of Message Processing in general. By analyzing the principles of this message mechanism, it can be used to handle similar program design requirements.
In Windows, user-oriented GUI can be divided into two forms: Dialog Box form and document/view form. The dialog box can be displayed in a modal dialog box or a non-modal dialog box to meet different user interaction requirements. Since the dialog box and the document/view framework structure have their own characteristics, can you use the document/view framework structure as a dialog box or implement the special functions in the document/view Framework Structure in the dialog box, the answer is yes.
Next, we will discuss the message encapsulation, transmission, and processing mechanisms in the implementation process of the modal dialog box starting from the message-driven mechanism of the Windows operating system, finally, the instances applied to the document/view framework structure are displayed in the form of a modal mode to verify and practice the content.
I. Windows Message Mechanism
Windows is an object-oriented architecture. Both the Windows environment and applications interact through messages. After the windows application starts to run, Windows creates a "message queue" for the program to store messages sent to different Windows that may be created by the program. The message structure (MSG) in the message queue is:
Typedef struct tagmsg { Hwnd; Uint message; Wparam; Lparam; DWORD time; Point pt; } MSG; |
The first member variable is used to identify the window handle for receiving messages, and the second parameter is the message id, such as wm_paint. The specific meanings of the third and fourth parameters are related to the message value, all are message parameters. The first four parameters are very important and frequently used. The last two parameters indicate the time and cursor position (screen coordinates) of the sent message respectively ). There are two ways to send messages to an application: one is to mail messages (post) by the system) "to the" message queue "of the application this is the" Incoming message "function of Win32 API: postmessage (). This function is returned without waiting for the message to be processed; the other is the window function that the system sends the message to the application when calling the window function directly, the function corresponding to "do not enter the queue message" is sendmessage (). It must wait until the message is processed.
For every running Windows application, the system creates a "message queue" for it, that is, an application queue, which is used to store messages in various Windows that may be created by the program. The application contains a piece of code called "message loop", which is used to retrieve these messages from the message queue and distribute them to corresponding window functions.
The message loop code is a program segment similar to the following in the main function winmain () in the application:
While (getmessage (& MSG, null )) {File: // get a message from the Message Queue Translatemessage (& MSG ); File: // retrieve and generate the character message wm_char Dispatchmessage (& MSG ); File: // send the message to the corresponding Window Function } |
It can be seen that the so-called "message loop" is actually a program loop.
Every window created by a Windows application registers a corresponding window function at the system core. The window function code form is a huge switch statement, it is used to process messages sent by messages cyclically to this window. Window functions are called directly by windows in the form of message-driven, rather than by applications, after processing the message, the window function returns the control to Windows.
Ii. Message Processing in the modal dialog box
As we can see above, Windows is a huge message-driven structure, with users sending messages and System Response Processing. The non-modal dialog box responds to a message. The system processes a message and returns control to Windows after processing. The document/view framework structure is similar to this one. After the modal dialog box is created, an external message is suspended, but the message in the response dialog box is all filtered out until wm_destroy or wm_close is received by the system, the system returns control to the thread before the modal dialog box is created. The thread before the modal dialog box is created will execute the following code.
Let's take a look at the domodal implementation code in the following dialog box:
{ ... ... // Disable parent window (before the create dialog box) Hwnd hwndparent = premodal (); Afxunhookwindowcreate (); Bool benableparent = false; If (hwndparent! = NULL &: isw.wenabled (hwndparent )) { : Enablewindow (hwndparent, false ); Benableparent = true; } Try { // Create Modal Dialog Box Afxhookwindowcreate (this ); If (createdlgindirect (lpdialogtemplate, cwnd: fromhandle (hwndparent), hinst )) { If (m_nflags & wf_continuemodal) { // Enters the pattern Loop DWORD dwflags = mlf_showonidle; If (getstyle () & ds_noidlemsg) dwflags | = mlf_noidlemsg; Verify (runmodalloop (dwflags) = m_nmodalresult ); } } } Catch_all (E) { Delete_exception (E ); M_nmodalresult =-1; } End_catch_all File: // enable parent window If (benableparent) : Enablewindow (hwndparent, true ); If (hwndparent! = NULL &: getactivewindow () = m_hwnd) : Setactivewindow (hwndparent ); // Delete dialog box Destroywindow (); Postmodal (); ... ... } |
We can see that there is no new thread in this implementation code. The system performs a message loop in runmodalloop. When m_nflags is wf_continuemodal, the system continues the mode. The runmodalloop () function is actually a for (;) loop to control the re-dispatch of Windows messages. Until continuemodal () returns false, while when endmodalloop () is called, continuemodal () returns false. At this time, it indicates the end of the modal display. Therefore, the runmodalloop () and endmodalloop () functions are the core components for message processing in the modal dialog box.
3. display the application to the document/View frame structure instance in the form of a modal
(1) create a project file: modeframe, and select MFC Appwizard (exe ).
(2) Step 2 select single document ).
(3) the remaining steps are default values.
(4) use classwizard to add a new class csubmodeframe and use cframewnd as the base class.
(5) Add the implementation function domode () of csubmodeframe ();
Int csubmodeframe: domodal () { Hwnd hwndparent = m_hwndprt; Crect RC (0, 0, 400,400 ); Cwnd * pparent = cwnd: fromhandle (hwndparent ); DWORD dwstyle = ws_thickframe | ws_minimizebox | ws_maximizebox | ws_popup | ws_thickframe | ws_visible | ws_sysmenu | ws_caption; If (! Create (null, "Modal document/Try frame", dwstyle, RC, pparent, null) return false; Bool benableparent = false; If (hwndparent! = NULL &: isw.wenabled (hwndparent )) { : Enablewindow (hwndparent, false ); : Enablewindow (m_hwnd, true ); Benableparent = true; } Centerwindow (); Try { // Enter modal Loop DWORD dwflags = mlf_showonidle; If (getstyle () & ds_noidlemsg) dwflags | = mlf_noidlemsg; Verify (runmodalloop (dwflags) = m_nmodalresult ); } Catch_all (E) { Delete_exception (E ); M_nmodalresult =-1; } End_catch_all If (benableparent) : Enablewindow (hwndparent, true ); If (hwndparent! = NULL &: getactivewindow () = m_hwnd) : Setactivewindow (hwndparent ); // Destroy modal window Destroywindow (); Return m_nmodalresult; } |
(6) Add the implementation function endmode () of csubmodeframe ()
Void csubframe: endmodal (){ Assert (: iswindow (m_hwnd )); If (m_nflags & (wf_modalloop | wf_continuemodal )){ Endmodalloop (1 ); } } |
(7) Add the cmodeframeview implementation function onlbuttondblclk ()
In message processing of this function: The csubmodeframe class can be processed as in the displayed dialog box.
Csubmodeframe submodeframe; If (submodeframe. domode () {MessageBox ("Mode OK ");} |
(8) Compile and run the project. Double-click the view to display the modal sub-document/view framework structure.
Conclusion:Through the above analysis and examples, we can see that we have thoroughly studied and understood the message processing mechanism of windows, and can use messages to customize and process windows events without sticking to the original system mode. It is necessary to conduct in-depth windows programming.