PostMessage and SendMessage's respective problems

Source: Internet
Author: User

Deep analysis of SendMessage, PostMessage

This article will use the C + + language, in conjunction with the MFC framework to give the use of PostMessage, SendMessage, etc. and the consequences of improper use (the discussion is for the custom message). If there is any mistake, please correct me.

The students who have written the Windows program know the difference between PostMessage and SendMessage, and the PostMessage function call returns immediately after sending, not waiting for the message processing to complete. SendMessage, however, keeps the calling thread in a block state until the message processing is complete.

The difference between these two functions leads to the following ideas:

The idea 1:postmessage immediately returns, in the program, the processing interface display (such as processing progress bar, scroll bar, etc.) using PostMessage, does not affect the user experience of the program.

Idea 2: In the program full use PostMessage, give up SendMessage, the advantage: PostMessage is returned immediately, can not affect the normal process of the program, even if the message processing function is stuck, also does not affect the main thread running.

At first, "learning" came to these ideas, but after a period of time, it was not advisable to discover both of these ideas.

Analysis Idea 1:

This can be divided into two points:

1) post message in the main thread to process the progress bar display (with wm_my_test parameters wparam, lparam to handle the display of the progress bar)

Code: Code_1

#define WM_MY_TEST (wm_user + 100)

void Cmydlg::onbnclickedok ()

{

int nParam1 = 0;

int nParam2 = 0;

for (int nIndex = 0; nIndex <; nindex++)

{

Do other things

...

nparam1++;

nparam2++;

PostMessage (Wm_my_test, (WPARAM) &nparam1, (LPARAM) &nparam2);

}

OnOK ();

}

LRESULT cmydlg::onmytest (WPARAM WPARAM, LPARAM LPARAM)

{

static int ntimes = 0;

CString Stroutput;

int* pParam1 = (int*) WParam;

int* pParam2 = (int*) LParam;

ntimes++;

Stroutput.format (_t ("%s%d%s%d%s%d"),

_t ("Param1 ="), *pparam1,

_t ("Param2 ="), *PPARAM2,

_t ("RealTimes ="), ntimes);

OutputDebugString (Stroutput);

return 0;

}

Code_1 will run the result:

Param1 = 0 Param2 = 0 RealTimes = 1

Param1 = 0 Param2 = 0 RealTimes = 2

Param1 = 0 Param2 = 0 RealTimes = 3

...

Param1 = 0 Param2 = 0 RealTimes = 1000

The result is far less than we expected, performance for postmessage multiple send, 2~1000 message parameters are all washed away. With PPARAM1, pParam2 to deal with the progress of the bar, the consequences can be imagined (progress bar did not move at all). If you change the above postmessage to SendMessage, the result is as follows:

Param1 = 1 PARAM2 = 1 RealTimes = 1

PARAM1 = 2 Param2 = 2 RealTimes = 2

Param1 = 3 Param2 = 3 RealTimes = 3

...

Param1 = Param2 = RealTimes = 1000

Visible, stable output of the required content, can be well controlled.

In this case (when the post message is in the main thread), not only does the user experience improve, but it is even worse.

It is not possible to use postmessage frequently to send the same message unless the last message sent is guaranteed to be processed (how is this guaranteed??? ), which is not as straightforward as using SendMessage.

Of course the Onmytest function might be this:

LRESULT cmydlg::onmytest (WPARAM WPARAM, LPARAM LPARAM)

{

static int ntimes = 0;

CString Stroutput;

int* pParam1 = (int*) WParam;

int* pParam2 = (int*) LParam;

ntimes++;

Stroutput.format (_t ("%s%d%s%d%s%d"),

_t ("Param1 ="), *pparam1,

_t ("Param2 ="), *PPARAM2,

_t ("RealTimes ="), ntimes);

OutputDebugString (Stroutput);

Massive access to network, disk and other low-speed operations

return 0;

}

In this case, if you use SendMessage, the user experience will be greatly reduced, even causing the program to become unresponsive. So someone proposed to use postmessage, so that the program will not be unresponsive, the maximum display is not correct. At first glance, the proposal seems pretty good, at least the program is working properly. However, why do these network access, disk read and write operations be put into the code of the interface? Interface, code separation is reasonable, so it can be concluded that access to the network, disk read and write operations should not be put here to deal with.

2) post message in the non-main thread to process the progress bar display (with wm_my_test parameters wparam, lparam to handle the display of the progress bar)

Code: code_2

DWORD WINAPI ThreadProc (LPVOID lpparam)

{

CMyDlg *pthis = (CMyDlg *) Lpparam;

int nParam1 = 0;

int nParam2 = 0;

for (int nIndex = 0; nIndex <; nindex++)

{

nparam1++;

nparam2++;

Pthis->postmessage (Wm_my_test, (WPARAM) & (NPARAM1), (LPARAM) & (NPARAM2));

}

return 0;

}

void Cmydlg::onbnclickedok ()

{

HANDLE hthread = CreateThread (NULL,

0,

ThreadProc,

(void*) This,

0,

NULL);

OnOK ();

}

LRESULT cmydlg::onmytest (WPARAM WPARAM, LPARAM LPARAM)

{

static int ntimes = 0;

CString Stroutput;

int* pParam1 = (int*) WParam;

int* pParam2 = (int*) LParam;

ntimes++;

Stroutput.format (_t ("%s%d%s%d%s%d"),

_t ("Param1 ="), *pparam1,

_t ("Param2 ="), *PPARAM2,

_t ("RealTimes ="), ntimes);

OutputDebugString (Stroutput);

return 0;

}

Results of code_2 Operation:

(The program crashes directly)

The thread function does not wait for the return of the Wm_my_test, the Loop 1000 times after the direct exit, which causes the stack on the variable nParam1, NPARAM2 is released, and then onmytest processing, NPARAM1, NPARAM2 address is invalid, resulting in a crash. SendMessage does not appear in this case.

modifying programs

Code: code_2 (2)

DWORD WINAPI ThreadProc (LPVOID lpparam)

{

Cqwerdlg *pthis = (Cqwerdlg *) Lpparam;

int *nparam1 = NULL;

int *nparam2 = NULL;

nParam1 = new int;

NPARAM2 = new int;

for (int nIndex = 0; nIndex <; nindex++)

{

*nparam1 = NIndex;

*NPARAM2 = NIndex;

Pthis->postmessage (Wm_my_test, (WPARAM) nParam1, (LPARAM) nParam2);

}

return 0;

}

Because the heap memory is not released, the program does not crash and runs on my machine as a result:

Param1 = Param2 = RealTimes = 1

PARAM1 = 117 Param2 = 117 RealTimes = 2

PARAM1 = 162 Param2 = 162 RealTimes = 3

Param1 = 218 Param2 = 218 RealTimes = 4

Param1 = 272 Param2 = 272 RealTimes = 5

PARAM1 = 312 Param2 = 312 RealTimes = 6

Param1 = 353 Param2 = 353 RealTimes = 7

Param1 = 391 Param2 = 391 RealTimes = 8

Param1 = 431 PARAM2 = 431 RealTimes = 9

Program execution is very unstable, each structure is different, of course, the data can not be used. When you put two new int into the For loop, the execution result is stable, but the code is obscure. There is no benefit in using postmessage here, so it is recommended to use SendMessage.

Analysis Idea 2:

1) It is known that a thread has processed a, and because of other needs, this thread also needs to process B (after a has been completed). A new add-on code is required to implement the previous code:

Code: Code_3

DWORD WINAPI ThreadProc (LPVOID lpparam)

{

HWND hwnd = (HWND) Lpparam;

Do some things

::P ostmessage (hWnd, wm_must_do_thing_a, 0, 0);

return 0;

}

LRESULT Cmydlg::onmustdothinga (WPARAM WPARAM, LPARAM LPARAM)

{

Do some things for A

Do some things for B//convoluted, this is a processing function!!!

}

We can add a message, Wm_must_do_thing_b, and then send it with PostMessage, oh, no, B. After a is complete, the only way to deal with this is to add a to the message handler of a, which leads to a convoluted code. This is not true if PostMessage is SendMessage in the original thread function.

If a, B is not associated with two operations, in order to expand later, also should not use PostMessage, in this case, should create more than one thread for processing.

2) For more important operations that need to be handled (these can lead to card death):

LRESULT cmydlg::ondothing (WPARAM WPARAM, LPARAM LPARAM)

{

Things to do. It could get stuck here, but it has to be handled.

}

In this case, it is recommended to use SendMessageTimeout, and the program discards the operation to continue when the message is still not completed after waiting for some time.

3) for all non-trivial operations:

These operations include: Clean disk temporary files and so on, these operations are not properly handled, the program does not care, in this case, you can use PostMessage,

In the end, we have the following conclusions:

1, PostMessage can not send the same message frequently, unless the last Post message processing is guaranteed to complete.

2. If you use SendMessage to cause the application user experience to degrade, you should check the message handler function instead of simply changing to PostMessage.

3. If the message is a program that must be processed, you cannot use PostMessage.

4. If the message is a program that must be processed and may cause the program to die, use SendMessageTimeout.

5. If the message is irrelevant, you can suggest using PostMessage.

6. For Windows-specific messages such as Wm_hotkey, you can only use PostMessage (not described in this article).

Reference: http://blog.csdn.net/xt_xiaotian/article/details/2778689

PostMessage and SendMessage's respective problems

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.