SendMessage, PostMessage principle

Source: Internet
Author: User

This paper explains the implementation principle of the two functions of SendMessage and PostMessage, and is divided into three steps, which are suitable for beginners, intermediate and senior programmers to understand, and three steps are as follows:

1, SendMessage, postmessage operation mechanism.

2, SendMessage, postmessage operation inside.

3, SendMessage, PostMessage's internal realization.

Note: Before you understand this article, you must first understand the message loop mechanism of Windows.

1 , SendMessage, postmessage operation mechanism

Let's first look at the simplest.

SendMessage can be understood as, the SendMessage function sends a message, waits for the message processing to complete, SendMessage returns. A little bit deeper, after waiting for the window handler function to return, SendMessage returns.

PostMessage can be understood as, the PostMessage function sends the message, does not wait for the message processing to complete, returns immediately. A little bit deeper, postmessage just send a message, the message is not sent to do not care, as long as the message is sent back immediately.

For programmers who write general Windows programs, this is enough to understand. But SendMessage, PostMessage really is a send message wait, a send message do not wait? Specific details, which will be discussed in the 2nd below.

2 , SendMessage, PostMessage's Running insider

When writing general Windows programs, as mentioned in the 1th is enough to deal with, in fact, we can look at MSDN to determine the SendMessage, PostMessage running inside.

In MSDN, SendMessage is interpreted as: the SendMessage function sends the specified message to a window or windows. It calls the window procedure for the specified window and does not return until the window procedure have processed the ME Ssage.

Translated into Chinese: the SendMessage function sends the specified message to the window. It invokes a window handler for a particular window and does not return immediately until the window handler processes the message.

And look at PostMessage's explanation: the PostMessage function places (posts) a message in the message queue associated with the thre Ad that created the specified window and returns without waiting for the thread to process the message.

The PostMessage function puts a message in the thread associated with the message queue that created the window and immediately returns without waiting for the thread to process the message.

After reading the MSDN explanation carefully, we learned that SendMessage did send a message and then waited for the processing to complete the return, but the method of sending the message was to call the message handler function (i.e. the WndProc function) directly, according to the function call rule, The SendMessage will not return until the message processing function returns. While PostMessage did not send a message, postmessage the message into the message queue, and then immediately return, as to when the message was processed, PostMessage completely unaware, at this time only the message loop knows when the message was PostMessage was processed.

So far we have brushed aside the suspicion that SendMessage just called our message handler, and PostMessage just put the message in the message queue. The next section will go deeper into these two functions to see how Microsoft actually implements the two functions.

3 , SendMessage, PostMessage's internal implementation

The workings and mechanisms of windows are often something we are interested in, and these things are not documented, so we can only use the tools provided by Microsoft to do our own research.

First, in the basic Win32 Engineering code, we can directly see the message handler function, message loop, so to establish a basic Win32 project (this article uses VS2005), in order to see more information, we need to set up, Let VS2005 load Microsoft's symbol (PDB) file [1]. For convenience, removed some extra code, added two menus, the IDs are: Idm_sendmessage, idm_postmessage. The necessary code after simplification is listed below.

Message loop:

Ln000:while (GetMessage (&msg, NULL, 0, 0))

ln001:{

Ln002:translatemessage (&MSG);

Ln003:dispatchmessage (&MSG);

LN004:}

Message handler functions:

Ln100:lresult CALLBACK WndProc (HWND hwnd, UINT message, WPARAM WPARAM, LPARAM LPARAM)

ln101:{

Ln102:int Wmid, wmevent;

Ln103:switch (Message)

Ln104: {

Ln105:case Wm_command:

Ln106:wmid = LoWord (WParam);

Ln107:wmevent = HiWord (WParam);

Ln108:switch (Wmid)

LN109: {

Ln110:case Idm_exit:

Ln111:destroywindow (HWND);

Ln112:break;

Ln113:case Idm_sendmessage:

Ln114:sendmessage (hWnd, wm_sendmessage, 0, 0);

Ln115:break;

Ln116:case Idm_postmessage:

Ln117:postmessage (hWnd, wm_postmessage, 0, 0);

Ln118:break;

Ln119:default:

Ln120:return DefWindowProc (hWnd, message, WParam, LParam);

Ln121:}

Ln122:break;

Ln123:

Ln124:case Wm_sendmessage:

Ln125:messagebox (HWnd, L "SendMessage", L "Prompt", MB_OK);

Ln126:break;

Ln127:

Ln128:case Wm_postmessage:

Ln129:messagebox (HWnd, L "PostMessage", L "Prompt", MB_OK);

Ln130:break;

Ln131:

Ln132:case Wm_destroy:

Ln133:postquitmessage (0);

Ln134:

Ln135:default:

Ln136:return DefWindowProc (hWnd, message, WParam, LParam);

Ln137:}

Ln138:return 0;

Ln139:}

The following step-by-step analysis of the internal situation of these two functions, first discusses SendMessage.

The first step, at the DispatchMessage (Ln003) function at the next breakpoint, F5 debugging, when the program runs to a breakpoint, view the CallStack window, you can have the following results:

#003: Myproj.exe!wwinmain (hinstance__ * hinstance=0x00400000, hinstance__ * hprevinstance=0x00000000, wchar_t * lpcmdline=0x000208e0, int ncmdshow=0x00000001) line + C + +

#002: Myproj.exe!__tmaincrtstartup () line 589 + 0x35 bytes C

#001: Myproj.exe!wwinmaincrtstartup () line 414 C

#000: [email protected] () + 0x23 bytes

We can see that the process first calls the BaseProcessStart function in Kernel32.dll, then calls the Startup Code of the function wWinMainCRTStartup, and then calls the _tmaincrtstartup function, Finally, we call our wWinMain function, and our program is up and running.

The second step, remove the breakpoint at the first step, at the WndProc (Ln101) function at the entrance of the next breakpoint, F5 continue to run, run to the new breakpoint, view the CallStack window, you can have the following results:

#008: myproj.exe! WndProc (hwnd__ * hwnd=0x00050860, unsigned int message=0x00000101, unsigned int wparam=0x00000074, long lparam= 0XC03F0001) Line 122 C + +

#007: [email protected] () + 0x28 bytes

#006: [email protected] () + 0xb7 bytes

#005: [email protected] () + 0xdc bytes

#004: [email protected] () + 0xf bytes

#003: Myproj.exe!wwinmain (hinstance__ * hinstance=0x00400000, hinstance__ * hprevinstance=0x00000000, wchar_t * LPCMDLINE=0X000208E0, #000: int ncmdshow=0x00000001) line + 0xc bytes C + +

#002: Myproj.exe!__tmaincrtstartup () line 589 + 0x35 bytes C

#001: Myproj.exe!wwinmaincrtstartup () line 414 C

#000: [email protected] () + 0x23 bytes

#000 ~ #003 is the same as the first step, no longer explained. In #004, #005, you can see that the function runs inside the DispatchMessage, DispatchMessageW, dispatchmessageworker are functions everywhere in user32.dll, and the function front strings are equal, This conjecture should be the internal processing of dispatchmessage. #008 is our message handler function, so we infer that #006, #007 is the code that is prepared to invoke our message handler function.

The third step, remove the breakpoint under the second step, in Ln003, Ln114, Ln115, Ln125, respectively, the next breakpoint, select the corresponding item in the menu, so that the program runs to LN114,F10 next, you can see and not run to break (Ln115), jump directly to the Ln125 place , so the current SendMessage is already waiting, view callstack window, can have the following results:

#013: myproj.exe! WndProc (hwnd__ * hwnd=0x00050860, unsigned int message=0x00000500, unsigned int wparam=0x00000000, long lparam= 0x00000000) line 147 C + +

#012: [email protected] () + 0x28 bytes

#011: [email protected] () + 0xb7 bytes

#010: [email protected] () + 0xc8 bytes

#009: [email protected] () + 0x49 bytes

#008: myproj.exe! WndProc (hwnd__ * hwnd=0x00050860, unsigned int message=0x00000111, unsigned int wparam=0x00008003, long lparam= 0x00000000) line 136 + 0x15 bytes C + +

#007: User32.dll[email protected] () + 0x28 bytes

#006: [email protected] () + 0xb7 bytes

#005: [email protected] () + 0xdc bytes

#004: [email protected] () + 0xf bytes

#003: Myproj.exe!wwinmain (hinstance__ * hinstance=0x00400000, hinstance__ * hprevinstance=0x00000000, wchar_t * LPCMDLINE=0X000208E0, #000: int ncmdshow=0x00000001) line + 0xc bytes C + +

#002: Myproj.exe!__tmaincrtstartup () line 589 + 0x35 bytes C

#001: Myproj.exe!wwinmaincrtstartup () line 414 C

#000: [email protected] () + 0x23 bytes

#000 ~ #008 The same as above, no longer explained. In #009, #010, you can see that the function is called inside the SendMessage, and this conjecture should be the internal processing of SendMessage. #011, #012 is the same as the #006 in the second step, the #007, in the second, the two functions are the code prepared to invoke the message handler function, and #013 is our message handler, so the two lines of code are functionally equal.

At this point, we have proved that SendMessage really calls the message handler function directly, and SendMessage waits before the message handler returns. In all operations, the Ln003 breakpoint does not go, proving that SendMessage will not put the message in the message queue (in PostMessage analysis, this breakpoint will run to, and then be described).

Fourth step, F5 continue to run, this time pop-up dialog box, click OK in the dialog box, run to the breakpoint Ln115. To view the CallStack window, you can get the following results:

#008: myproj.exe! WndProc (hwnd__ * hwnd=0x00050860, unsigned int message=0x00000111, unsigned int wparam=0x00008003, long lparam= 0x00000000) Line 137 C + +

#007: [email protected] () + 0x28 bytes

#006: [email protected] () + 0xb7 bytes

#005: [email protected] () + 0xdc bytes

#004: [email protected] () + 0xf bytes

#003: Myproj.exe!wwinmain (hinstance__ * hinstance=0x00400000, hinstance__ * hprevinstance=0x00000000, wchar_t * lpcmdline=0x000208e0, int ncmdshow=0x00000001) line + 0xc bytes C + +

#002: Myproj.exe!__tmaincrtstartup () line 589 + 0x35 bytes C

#001: Myproj.exe!wwinmaincrtstartup () line 414 C

#000: [email protected] () + 0x23 bytes

#000 ~008 is exactly the same as the second step, when SendMessage has returned, and the stack that was called is emptied.

At this point, we thoroughly brushed off the SendMessage of the cloud, understand the SendMessage function of the operating mechanism, the SendMessage internal call Sendmessagew, SendMessageWorker function to do internal processing, Then call UserCallWinProcCheckWow, InternalCallWinProc to invoke the message handler function in our code, and after the message handler function is complete, the SendMessage function returns.

SendMessage After discussion, now discuss PostMessage, remove all breakpoints above, and turn off debugging.

The first step, the next breakpoint at the DispatchMessage (Ln003) function, F5 debugging, where the result is the same as SendMessage, no longer explained.

The second step, remove the breakpoint at the first step, at the WndProc (Ln101) function at the entrance of the next breakpoint, F5 continue to run, here the result is like SendMessage, no longer explained.

The third step, remove the breakpoint under the second step, in Ln003, Ln117, Ln118, Ln129, respectively, the next breakpoint, select the corresponding item in the menu, so that the program runs to LN117,F10 next, you can see that has been run to the Break,postmessage function returned, at this time There is no change in callstack.

Fourth step, F5 continue to run, at this time the program runs to Ln003,callstack with the first step just up the same.

Fifth step, F5 continue to run (because there are multiple messages, may have to press several times), let the program run to Ln129, at this time callstack with the second step the same, in order to facilitate the explanation, again listed as follows:

#008: myproj.exe! WndProc (hwnd__ * hwnd=0x00070874, unsigned int message=0x00000501, unsigned int wparam=0x00000000, long lparam= 0x00000000) Line 151 C + +

#007: [email protected] () + 0x28 bytes

#006: [email protected] () + 0xb7 bytes

#005: [email protected] () + 0xdc bytes

#004: [email protected] () + 0xf bytes

#003: Myproj.exe!wwinmain (hinstance__ * hinstance=0x00400000, hinstance__ * hprevinstance=0x00000000, wchar_t * lpcmdline=0x000208e0, int ncmdshow=0x00000001) line + 0xc bytes C + +

#002: Myproj.exe!__tmaincrtstartup () line 589 + 0x35 bytes C

#001: Myproj.exe!wwinmaincrtstartup () line 414 C

#000: [email protected] () + 0x23 bytes

As you can see, this call is called from the message loop, DispatchMessageW, Dispatchmessageworker is the internal processing of dispatchmessage, UserCallWinProcCheckWow, InternalCallWinProc is the code that is prepared to invoke our message handler function.

At this point, we once again thoroughly removed the PostMessage of doubt, understand the PostMessage function of the operation mechanism, summarized as, PostMessage put the message into the message queue, their own immediate return, the message loop GetMessage (PeekMessage Also, in this case, the demo) processes the messages we send and then follows the normal message processing method.

SendMessage, PostMessage principle

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.