Turn: windows message passing mechanism

     Windows is a message (Message) drive system. Windows provides a message between applications, means of communication between the application and Windows systems. Application wants to achieve the functions triggered by the message, and the message on the response and processing to complete. It must be noted that the message is not to seize the property, regardless of the priority of the event, always in accordance with party has arrived, followed by treatment (except for some of the system messages), this may cause some real-time external events that lack of timely treatment.

      Windows-based applications generally include window (Window), which is mainly to provide users with a visual interactive mode, the window is always created within a thread (Thread). Windows system to manage through message interaction mechanism, the message (Message) is transmitted, stored, processed, a thread maintains its own set of message queue (Message Queue), in order to maintain exclusivity between threads. Characteristics FIFO queue simply, this mechanism may be implemented in an asynchronous demand response process.

table of Contents:

1 message

2, the message type

3, the message queue (Message Queues)

4, the message queue (Queued Messages) and non-queue messages (Non-Queued Messages)

5 、PostMessage(PostThreadMessage), SendMessage

6 、GetMessage, PeekMessage

7 、TranslateMessage, TranslateAccelerator

8, (deadlock message (Message Deadlocks)

9、BroadcastSystemMessage

10, the message processing

11, MFC message maps

12, message reflection

1 message

    Messaging system for a win32 program is very important, it is a source of power running. A message is a 32-bit system-defined, his only defines an event, send a notice to Windows, an application to tell what happened. For example, clicking the mouse, to change the window size by pressing a key on the keyboard

It will make Windows sends a message to the application.

    A message type as the recording itself is passed to the application, this record contains the messages and other information. For example, clicking the mouse message generated by

He said that this record contains the coordinates of the mouse click. The record type is called MSG, MSG containing from windows application message queue message information, it

Windows, the following statement:
typedef struct tagMsg
{
the HWND HWND; // accept the message window handle
UINT message; // message identifier is constant, that is, we usually refer to a message number
WPARAM wParam; // 32 bit message specific additional information message depends on the exact meaning value
LPARAM lParam; // additional information specific to the 32-bit message, the message depends on the exact meaning of the value
DWORD time; // time of message creation
POINT pt; // message created when the mouse / cursor position in the screen coordinate system
} MSG;
    message may be generated by the system or application. The system generates a message when entering the event. For example, when the user keystrokes, move the mouse or click the control. The system also generates a message in response to changes brought about by the application, such as applications change system font size changing window. The application can generate messages to make the form to perform tasks, or communication with other applications in a window.
2, message type
1) defining message system (System-Defined Messages)
        previously defined in the SDK good messages, non-user-defined, in the range [0x0000, 0x03ff] between, it can be divided into the following three categories:
1> Window message (Windows message)
       and about the inner workings of the window, such as creating a window, draw a window, the window is destroyed and so on. May be general window, you can also Dialog, and other controls.
Such as: the WM_CREATE, WM_PAINT, WM_MOUSEMOVE, the WM_CTLCOLOR, WM_HSCROLL ...
2> command message (Command Message)
        processing user when relevant, such as clicking a menu item or toolbar or control, it will generate a command message request.
WM_COMMAND, LOWORD (wParam) is the ID menu items, toolbar buttons or controls. If control, HIWORD (wParam) indicates that the control message type
3> control notification (Notify Message)
        controls the notification message, this is the most flexible message format, the Message, wParam, lParam are: WM_NOTIFY, control ID, a pointer NMHDR of . NMHDR contain content controls the notification, which could be extended.
2) program defines message (Application-Defined Messages)
        message a user-defined, range for which the following provisions:
of WM_USER:. 0x0400-0x7FFF (EX of WM_USER + 10)
WM_APP (the winver> 4.0): 0x8000-0xBFFF (ex.WM_APP +4)
the RegisterWindowMessage: 0xC000-0xFFFF
. 3, the message queue (the message queues)
 the Windows there are two types of message queues
1) system message queue (system message queue)
        This is only a Queue system, device driver (mouse, keyboard) input using the operating system is converted into the message queue exists, then the system will put this message where the target window thread message queue (thread-specific message queue) waiting to be processed
2) the message queue thread (thread-specific message queue)
        each GUI thread will maintain such a thread message queue. (This queue is created only when the thread calls GDI functions, the default is not created). Then thread message queue messages will be sent to the appropriate window procedure (WndProc) processing.
Note: thread message queue WM_PAINT, WM_TIMER message only if no other time in the Queue will be processed, WM_PAINT messages will be combined to Improve efficiency. All other messages are processed first in first out (FIFO) manner.
4, the message queue (Queued Messages) and non-queue messages (Non-Queued Messages)

1) a message queue (Queued Messages)
        messages are initially stored in the message queue, the message loop will take from the message queue and distributed to each of the processing window, such as a mouse, keyboard message.
2) a non-message queue (NonQueued Messages)
        message system message queue and a bypass queue thread message sent to the window procedure to be treated, such as: WM_ACTIVATE, WM_SETFOCUS, WM_SETCURSOR, WM_WINDOWPOSCHANGED
Note: postMessage message queue message is sent, it will message Post the message queue; SendMessage message sent by a non-message queue, is sent directly to the window procedure.

Message queues and the difference between non-queue messages
        from the message transmitting route of view, the message can be divided into two kinds: non-queue message and message queues. It can be divided into the message queue by the system message queue and a thread message queue. System message queue maintained by Windows, thread message queue maintained by each GUI thread themselves, to avoid non-GUI ready to create a message queue, all threads generated and no message queue, only when the thread first call GDI functions The system was to create a message queue thread. Queue message to the system message queue, and then to the thread message queue; nonqueued message directly to the destination window procedure.
     For the message queue, the message is the most common trigger of the keyboard and mouse, for example WM_MOUSERMOVE, WM_CHAR other news, there are some other messages, such as: WM_PAINT, WM_TIMER and WM_QUIT. When the mouse, keyboard events are triggered on the mouse or keyboard driver will convert these to the corresponding event message, and then transported to the system message queue, to be processed by the Windows system. Windows system will at the appropriate time, remove a message from the system message queue, we are talking about MSG message structure determines that the message is to be sent to the window, and then sent out a message thread to create a window based on the previous corresponding queue , the following thing to worry about in relation to the message queue by a thread, Windows began to go do your own thing. Thread sees its own message queue have messages to take out from the queue, is sent to the appropriate window procedure to handle the operating system.
     In general, the system will always end in a message Post a message queue. This ensures that the window in FIFO order acceptance message. However, an exception is WM_PAINT, a plurality of the same window are combined into a WM_PAINT message is WM_PAINT, merge all the ineffective area to an invalid region. The combined WM_PAIN purpose is to reduce the number of times to refresh the window.

      Non-bypass system will queue messages queues and message queues, sending a message directly to the window procedure. Non-system sends a message notification window queue, the system sends a message notification window. For example, when the user activates a window system sends WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR. These messages inform the window it was activated. Non queue message may be generated when the system call by the application program. For example, when a program calls SetWindowPos WM_WINDOWPOSCHANGED message transmission system. Some functions are also sending non-queue messages, for example, here we have to talk about the function.

. 5, the PostMessage (PostThreadMessage), the SendMessage
        the PostMessage: put the message thread message specified window is located immediately after the return queue. PostThreadMessage: return immediately after the message is placed in the specified thread's message queue.
        SendMessage: direct the message to the window procedure, the process was finished to return.

The difference between PostMessage (asynchronous) and SendMessage (synchronous) of

a, PostMessage is asynchronous, SendMessage is synchronous.

         PostMessage only the message in a queue, whether the message is not to be treated returns, the message may not be processed;

        SendMessage messages waiting to be finished before the return process, if the message is not processed, the thread sending the message will remain in the blocked state waiting for return messages.

b, in the same thread:

          SendMessage sends a message, called by the module USER32.DLL target window message handler, and returns the results, SendMessage sent message in the same thread does not enter the inside thread message queue; PostMessage sent first message into the message queue, then message dispatch loop to the target window (DispatchMessage).

c, different threads:

             SendMessage message sent to the target window message queue, and then sends the message thread USER32. Monitor and wait for a message in the DLL module processing results until it returns to the processing of the target window, SendMessage need to do a lot of work before returning, such as in response to another thread SendMessage to send it (). PostMessge () to another thread The best time to use PostThreadMessage instead. The PostMessage () HWND of parameters may be NULL, corresponding to PostThreadMessage () + GetCrrentThreadId.

d, the system processes the message.

       Processing system only (Marshal) system messages (0 - WM_USER), require the user to user message transmission processing (user-defined).

        When the message transmission system using PostMessage, SendNotifyMessage, SendMessageCallback other asynchronous function, parameter pointers may not be used, because the sender does not wait for the return message processing, the receiver has not been processed, a pointer is likely to be released, or the content is changed .

e, in the Windows 2000 / XP, each message queue can hold up to a certain number of messages, it will not be processed more than would be lost. The default is 10000;: [HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Windows] USERPostMessageLimit

6, GetMessage, PeekMessage
PeekMessage immediately return a message can be left
GetMessage returns will delete a message in the news

The main difference PeekMessage and GetMessage function are:
        The main function GetMessage A is "removed" message from the message queue, the message is removed later, it is deleted from the message queue; PeekMessage and the main function is to "peek" message. If there is a message, it returns true, otherwise false. May also be used PeekMessage message from the message queue in which to use its parameters (UINT wRemoveMsg), if set to PM_REMOVE, were taken out and deleted the message from the message queue; PM_NOREMOVE If set, the message will not remove the message queue.
        . b If GetMessage not get messages from the message queue, the operating system thread will be suspended until the thread when the OS rescheduled, two different properties: using GetMessage threads will be suspended, using threads PeekMessage get control of the CPU, running for some time.
        c, GetMessage every time wait for a message, the message does not return until getting; PeekMessage only the query message queue, the message is not returned immediately, the return value from the message to determine whether to take.
We can also say, PeekMessage is a function of having a thread asynchronous behavior, regardless of whether there is a message in the message queue, the function will return immediately. The GetMessage function is a thread synchronization behavior has, if there is no message queue messages, the function would have been to wait until the return message queue when there is at least one message.
If there is no message in the message queue, PeekMessage always return, which is equivalent to performing a loop, if the message queue has been empty, it enters an infinite loop. GetMessage is not possible because the message queue is empty and enter an infinite loop.

contact:

        Windows inside of, and the GetMessage PeekMessage performed with the same code, are made PeekMessage and Getmessage message to the message queue system, and placed in the assigned structure.

the difference:

PeekMessage: returns TRUE if there is a message, no message return FALSE

GetMessage: message and returns the message has not WM_QUIT TRUE, FALSE if there is WM_QUIT message and returns, when no message is not returned.

GetMessage: After obtaining the message, delete the message other than WM_PAINT message.

PeekMessage: After obtaining the message, whether to delete the message parameters according to wRemoveMsg judgment. PM_REMOVE delete, PM_NOREMOVE not deleted.

The PeekMessage function normally does not remove WM_PAINT messages from the queue. WM_PAINT messages remain in the queue until they are processed. However, if a WM_PAINT message has a null update region, PeekMessage does remove it from the queue.

You can not delete from the message queue by PeekMessage WM_PAINT message, remove WM_PAINT messages from the queue may fail to make the window display area region becomes effective (refresh the window), if the queue contains WM_PAINT message program would have been a while loop.

. 7, TranslateMessage, the TranslateAccelerator
         TranslateMessage: message to a virtual-key message is converted into characters (character message), and placed in the current thread's message queue, takes out the message processing loop.
        TranslateAccelerator: shortcut key mapped to the corresponding menu command. WM_KEYDOWN or WM_SYSKEYDOWN it will be converted into the corresponding shortcut key table or WM_SYSCOMMAND WM_COMMAND message, then the converted WM_SYSCOMMAND WM_COMMAND or sent directly to the window procedure, after the process will return.

8, (deadlock message (Message Deadlocks)
Suppose thread A and B, there are the following steps
        1) to the SendMessage Thread A Thread B, A thread B waiting message returned after treatment
        2) Thread A Thread B received a hair to the message, and processed in the process, B also SendMessgae to thread a, and then wait for a return from a. Because at this time, the thread A thread is waiting for return from B, B can not process the message sent, resulting in the thread A, B wait for each other to form a deadlock. Multiple threads may be formed in an annular deadlock.
You can use SendNotifyMessage or SendMessageTimeout to avoid deadlock.

9, BroadcastSystemMessage
        we generally come into contact message is sent to the window, in fact, the recipient of the message can be varied, which may be an application (Applications), the drive can be installed (installable drivers), network devices ( network drivers), the system-level device driver (system-level device drivers) and the like,
BroadcastSystemMessage the API can send a message to the above system components.

10, the message processing
        Next we talk about the process the message, first we look at the VC message pump:

while(GetMessage(&msg, NULL, 0, 0))
{
       if(!TranslateAccelerator(msg.hWnd, hAccelTable, &msg))
{
            TranslateMessage(&msg);
            DispatchMessage(&msg);
       }
}

TranslateMessage (translated message):

        To the virtual key messages into character messages. Because Windows are based on the definition of virtual keys on the keyboard all the coding, so that when the button is pressed, and not character message, keyboard mapping needs to be converted into character messages.

TranslateMessage function

        Used to convert virtual key messages into character messages. Character message is delivered to the calling thread's message queue, the lower is extracted once GetMessage function call. When we tap a character key on your keyboard, the system will generate and WM_KEYUP WM_KEYDOWN messages. Additional parameters of these two messages (wParam and lParam) contains the virtual key code and scan code and other information, and we often need to get ASCII code of a character in the program, TranslateMessage this function can be WM_KEYDOWN messages and WM_ KEYUP the combination is converted to a WM_CHAR message (the message contains an additional parameter wParam ASCII character code), and deliver the converted new message to the calling thread's message queue. Note that, TranslateMessage function does not modify the original message, it just generates a new message and delivered to the message queue.

That TranslateMessage will find whether there is a message in the message character keys, character keys if there is a message, it will have WM_CHAR message, if not it will have any news.

The DispatchMessage (assignment message):

TranslateMessage transmits the converted message to the message processing function of the window, this window function has been specified at the time of registration.
        First, GetMessage get a message from the main thread's message queue before the process of return and copy it to the MSG structure, if there is no message in the queue, the GetMessage function will wait for the arrival of a message in the future. If you will be a window handle GetMessage passed as the second parameter, only the specified window messages can be obtained from the queue. GetMessage can also filter messages from the message queue only accepts messages in the message queue in the scope. This time is necessary to use GetMessage / PeekMessage specify a message filter. This filter is a message identifier range or a window handle, or both simultaneously specified. When you are looking for an application message into a message queue it is useful. WM_KEYFIRST and WM_KEYLAST constants for accepting all keyboard messages. WM_MOUSEFIRST and WM_MOUSELAST constants for accepting all mouse messages.
TranslateAccelerator then determines whether the message is not a message key and a message accelerator, if so, the function will convert the message into a number of accelerator keys passed to the callback message window. After processing the accelerator, the function will convert the two buttons TranslateMessage WM_KEYDOWN and WM_KEYUP messages the WM_CHAR into one, but it needs to be noted that the message WM_KEYDOWN, WM_KEYUP will still be passed to the callback window.    
After processing, DispatchMessage function will send the message to the specified callback function of the message window has been set. If the message is the WM_QUIT, the GetMessage returns 0 to exit the loop. An application can use PostQuitMessage to end its own message loop. In the WM_DESTROY typically called the main window.
11, MFC message maps
         When programming using the MFC, and the nature of message transmission and processing same Win32, however, it is encapsulated message processing, message processing simplifies the complexity of the programming of the programmer, it is to process messages by the message mapping mechanism, programmers do not have to design and implement your own window procedure.
To put it plainly, the essence of MFC message mapping mechanism is a tremendous message and its handler correspondence table. Message mapping is basically divided into two parts:
a header in a macro DECLARE_MESSAGE_MAP (.h) file in the (), which at the end of the class, is a public attribute; is the corresponding part in the implementation (.cpp) adds a message map, as follows:
BEGIN_MASSAGE_MAP (current class, the current class is the base class)
// {{AFX_MSG_MAP (the CMainFrame)
entry in the message
//}} AFX_MSG_MAP
END_MESSAGE_MAP ()
, but not enough to merely these two a completion message, if the message is a work, there must be the following three parts to cooperate:
1, adding the corresponding functions declared in the class definition;
2, adding the corresponding mapping message in the message entry in the mapping table class;
3 , adding the corresponding function implemented in the class's body;
adding a message
(1), added by using class Wizard automatic
        View menu selection - & gt; Class Wizard activate Class Wizard, select Message Map tab, select the message we want to add the class Class name from the combo box. In the Object IDs list box, select the name of the class. In this case, Messages list box displays the class member functions and can reload the window message. Overload can be displayed in the upper member function list, to the actual case letters to represent imaginary member function. Other news for the window, in capital letters appear. Select the message we want to add, click Add Funtion button, Class Wizard automatically the message added.
Sometimes, the message we want to add is not found in the Message list, we can use the Class Wizard on the Class Info tab to expand the message list. On this page, locate the Message Filter combo box, list box options homepage Messages can be changed by it.
(2), manually add a message
 if the message Messages list box does not have what we want, we need to add manual:
        1) Add the declaration in .h file handler class, followed by the //}} AFX_MSG line after adding the statement, pay attention, be sure to start with afx_msg.
Typically, the best place to add a handler declaration is the following source code table Class Wizard maintained outside the parentheses {} in its domain mark it. Anything these brackets are likely to be destroyed Class Wizard.
        2) Next, find the line //}} AFX_MSG_MAP user class file .cpp, was added immediately after its entry in the message. Similarly, on the outside {} {}.
        3) Finally, add the entity message handling function in the file.
To be able to use Class Wizard to add a message, try using Class Wizard Add to reduce our workload; the message can not be used for Class Wizard and add a custom message needs to be added manually. Overall, MFC's news programming for the user, relatively simple, is no longer used in this example demonstrates.
        12, message reflection mechanism
What message reflection?
         The parent window control notification messages sent to it, reflected back control processing (ie let the control processes this message), this notification messages to make their own control mechanisms to deal called message reflection mechanism.
        Through previous study we know, under normal circumstances, control sends a notification message to the parent window, these notification messages are processed by the parent window. In this way, the parent window (usually a dialog) will handle the messages, in other words, the message processing controls must be in the parent window class body, every time we add a child control, it is necessary in the parent window class copy the code. Clearly, this is inconvenient for maintenance and portable code, and that a clear departure from the principles of programming in C ++ objects.
        Beginning with version 4.0, MFC provides a message reflection mechanism (Message Reflection), control notification messages can be reflected back to the control. Specifically, the reflection message, if the control has the message handler, then the message is processed by the control themselves, if the control does not process the message, then the message frame will continue to the parent window, the parent window to continue this process the message. Visible, the new message reflection mechanism does not destroy the original notification message handling mechanism.
Message reflection mechanism for the control provides the opportunity to deal with the notification message, which is very useful. If a conventional manner, by the parent window to process the message, the increased dependency on the parent window of the control object, which is clearly contrary to the principles of object-oriented. If the message is processed by the control yourself, you control object so that greater independence, which greatly facilitates maintenance and portable code.
        Example M8: simple demonstration of MFC message reflection mechanism. (See accompanying source projects M8)
     Open VC ++ 6.0, create a new project based on M8 dialog.
In this project, a new CMyEdit class, base class CEdit. Next, three variables in the class, as follows:
Private:
the CBrush m_brBkgnd;
the COLORREF m_clrBkgnd;
the COLORREF m_clrText;
in CMyEdit :: CMyEdit (), the initial values for these three variables:
{
m_clrBkgnd the RGB = (255, 255 , 0);
m_clrText = RGB (0, 0, 0);
m_brBkgnd.CreateSolidBrush (RGB (150, 150, 150));
}
open ClassWizard, class called CMyEdit, Messages at selected "= WM_CTLCOLOR", you find, WM_CTLCOLOR equal sign in front of a message, which indicates that the message is a message reflecting, i.e., the equal sign in front of the message is the message to be reflected.
Message reflectance function codes are as follows:
HBRUSH CMyEdit :: CtlColor is (the CDC the pDC *, UINT nCtlColor)
{
    // the TODO: Change Attributes the any of the DC here Wallpaper The
    pDC- & gt; SetTextColor (m_clrText); // Set the text color
    pDC- & gt; SetBkColor (m_clrBkgnd); // set the background color
     // Note that before we overwrite the contents of the function, the function returns NULL, NULL that is return;
    // function returns NULL will CtlColor function performs the parent window without performing CtlColor function controls
    // So, let us function bACKGROUND return brush without returning NULL, the purpose is to achieve a reflective message
    return m_brBkgnd; // returns the background brush
}
add a IDD_M8_DIALOG Edit control in the dialog box, using the Edit control ClassWizard to add a variable of type CMyEdit m_edit1, the Edit controls and CMyEdit associate.
----------------

Published 69 original articles · won praise 10 · views 30000 +

Guess you like

Origin blog.csdn.net/u010096608/article/details/103226541