分享

Sendmessage和Postmessage简介

 贫穷的小悍马 2013-06-17

SendMessage函数功能描述:将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口过程,直到窗口过程处理完消息后才返回。

Postmessage函数则是将消息放入消息队列里,并立即返回。

PostThreadMessage函数: 

1 BOOL PostThreadMessage( DWORD idThread,
2 UINT Msg,
3 WPARAM wParam,
4 LPARAM lParam
5 );

它可以用于线程之间的异步通讯,因为它不用等待调用者返回。

常见问题

1)使用SendMessage来实现剪切、复制和粘贴

1 SendMessage(hwnd, WM_COPY, 0, 0);
2 SendMessage(hwnd, WM_CUT, 0, 0);
3 SendMessage(hwnd, WM_PASTE, 0, 0);

2)SendMessage与PostMessage的区别

PostMessage将消息放入消息队列后马上返回,而SendMessage直到窗口过程处理完消息后才返回。

3)SendMessage发送WM_COPYDATA消息在进程间传送数据

WM_COPYDATA消息主要目的是允许在进程间传递少量只读数据。SDK文档推荐用户使用SendMessage()函数,接收方在数据复制完成前不返回,这样发送方就不可能删除和修改数据。

例如:

1 std:string strData = "VC知识库 VCKBASE.COM";
2 COPYDATASTRUCT cds;
3 cds.dwData = 0;
4 cds.cbData = strData.Length();
5 cds.lpData = strData.c_str();
6 ::SendMessage(hwnd, WM_COPYDATA, NULL, (LPARAM)&cds);

3、PostThreadMessage有时会失败,报1444错误(Invalid thread identifier. ),其实这不一定是线程不存在的原因,也有可能是线程不存在消息队列(message queue)造成的。事实上,并不是每个thread都有message queue,那如何让thread具有呢? 答案是,至少调用message相关的function一次,比如GetMessage,PeekMessage。

4、如果是postthreadmessage动态分配的memory给另外一个thread,要注意内存的正确释放。并且PostThreadMessage不能够post WM_COPYDATE之类的同步消息,否则会报错!

5、最好不要使用PostThreadMessage post message给一个窗口,使用PostMessage替代。

example:

1 #include <windows.h>
2 #include <cstdio>
3 #include <process.h>
4 #define MY_MSG WM_USER+100
5 const int MAX_INFO_SIZE = 20;
6 HANDLE hStartEvent; // thread start event
7 // thread function
8 unsigned __stdcall fun(void *param)
9 {
10 printf("thread fun start
11
12
13 \n");
14 MSG msg;
15 PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
16 if(!SetEvent(hStartEvent)) //set thread start event
17 {
18 printf("set start event failed,errno:%d\n",::GetLastError());
19 return 1;
20 }
21
22 while(true)
23 {
24 if(GetMessage(&msg,0,0,0)) //get msg from message queue
25 {
26 switch(msg.message)
27 {
28 case MY_MSG:
29 char * pInfo = (char *)msg.wParam;
30 printf("recv %s\n",pInfo);
31 delete[] pInfo;
32 break;
33 }
34 }
35 };
36 return 0;
37 }
38 int main()
39 {
40 HANDLE hThread;
41 unsigned nThreadID;
42 hStartEvent = ::CreateEvent(0,FALSE,FALSE,0); //create thread start event
43 if(hStartEvent == 0)
44 {
45 printf("create start event failed,errno:%d\n",::GetLastError());
46 return 1;
47 }
48 //start thread
49 hThread = (HANDLE)_beginthreadex( NULL, 0, &fun, NULL, 0, &nThreadID );
50 if(hThread == 0)
51 {
52 printf("start thread failed,errno:%d\n",::GetLastError());
53 CloseHandle(hStartEvent);
54 return 1;
55 }
56 //wait thread start event to avoid PostThreadMessage return errno:1444
57 ::WaitForSingleObject(hStartEvent,INFINITE);
58 CloseHandle(hStartEvent);
59 int count = 0;
60 while(true)
61 {
62 char* pInfo = new char[MAX_INFO_SIZE]; //create dynamic msg
63 sprintf(pInfo,"msg_%d",++count);
64 if(!PostThreadMessage(nThreadID,MY_MSG,(WPARAM)pInfo,0))//post thread msg
65 {
66 printf("post message failed,errno:%d\n",::GetLastError());
67 delete[] pInfo;
68 }
69 ::Sleep(1000);
70 }
71 CloseHandle(hThread);
72 return 0;
73 }

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多