PostThreadMessage

函數功能:該函數將一個消息放入 (寄送)到指定線程的消息隊列裏,不等待線程處理消息就返回。
windows

函數原型:BOOL PostThreadMessage(DWORD idThread,UINT Msg,WPARAM wParam,LPARAM IParam);多線程

參數函數

idThread:其消息將被寄送的線程的 線程標識符。若是線程沒有消息隊列,此函數將失敗。當線程第一次調用一個Win 32 USER或GDI函數時,系統建立線程的消息隊列。要獲得更多的信息,參見備註。post

Msg:指定將被寄送的消息的類型。spa

wParam:指定附加的消息特定信息。線程

IParam:指定附加的消息特定信息。code

返回值:若是函數調用成功,返回非零值。如 果函數調用失敗,返回值是零。若想得到更多的錯誤信息,請調用GetLastError函數。若是idThread不是一個有效的線程標識符或由 idThread肯定的線程沒有消息隊orm

列,GetLastError返回 ERROR_INVALID_THREAD。對象

備註:消息將寄送到的線程必須建立消息隊 列,不然調用PostThreadMessage會失敗。用下列方法之一來處理這種狀況:隊列

調用PostThreadMessage。 若是失敗,調用Sleep,再調用PostThreadMessage,反覆執行,直到PostThreadMessage成功。

建立一個事件對象,再建立線程。在調用 PostThreadMessage以前,用函數WaitForSingleObject來等特事件被設置爲被告知狀態。消息將寄送到的線程調用 PeekMessage(£msg,NULL,WM_USER,WM_USER,PM_NOREMOVE)來強制系統建立消息隊列。設置事件,表示線程已 準備好接收寄送的消息。

消息將寄送到的線程經過調用 GetMesssge或PeekMesssge來取得消息。返回的MSG結構中的hwnd成員爲NULL。

速查:Windows NT:3.1及以上版本;Windows:95及以上版本;Windows CE:1.0及以上版本:頭文件:winuser.h;輸入庫:user32.lib;Unicode:在Windows NT環境下以Unicode和ANSI方式實現。

 

---------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------

 

window線程間傳送消息仔細的看了一遍,以爲之前的理解 很不深入。說一說對PostThreadMessage的 理解。

PostThreadMessage是一個線程體發送一個消息 到指定的線程ID,其 原型以下:

BOOL PostThreadMessage(          
                    DWORD idThread,
                    UINT Msg,   
                    WPARAM wParam,    
                    LPARAM lParam
);

       這個函數既能夠發送消息給工 做線程,也能夠發送給UI線 程。接受PostThreadMessage的 線程必須已經有了一個message queue, 不然調用PostThreadMessage會 失敗。由於此緣由使用GetLastError會 獲得錯誤碼爲1444, 這種狀況常常出現,解決方法有以下兩種:

1.         調 用PostThreadMessage, 若是失敗,就Sleep一 段時間再次調用PostThreadMessage直 到調用成功;

2.         創 建一個Event對 象,讓PostThreadMessage等 待接受的線程建立一個message queue。 能夠經過調用PeekMessage強 制系統建立一個message queue。 示例代碼以下:

 

假設mainAPP是發送線程ThreadA是接受線程

/*mainAPP.cpp*/
……
hStartEvent = ::CreateEvent(0,FALSE,FALSE,0); //create thread start event
if(hStartEvent == 0)
{
          printf("create start event failed,errno:%d\n",::GetLastError());
          return 1;
}
::WaitForSingleObject(hStartEvent,INFINITE);
CloseHandle(hStartEvent);
if(!PostThreadMessage(threadaID, WM_MESSAGE_A,0,0))
{
          _tprintf(_T("post error! %d\n"), GetLastError());
          return 1;
}
……

ThreadA是接受線程

/* ThreadA */
MSG msg;
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
if(!SetEvent(hStartEvent))
{
          printf("set event error,%d\n",GetLastError());
          return 1;
}
while(true){
          if(GetMessage(&msg, 0,0,0)) {
                    switch(msg.message){
                              case WM_MESSAGE_A:
                               ……
                               break;
                              }
                    }
          }
}

PostThreadMessage傳遞的消息若是要包含信 息,要注意在結束的時候釋放消息中的信息。在消息中附加信息方法以下

/*構造信息以下*/
char* pInfo = new char[MAX_INFO_SIZE]; //create dynamic msg
sprintf(pInfo,"msg_%d",++count);
PostThreadMessage(nThreadID,MY_MSG,(WPARAM)pInfo,0)//post thread msg
 
/*解釋信息以下*/
if(GetMessage(&msg,0,0,0)) //get msg from message queue
{
             switch(msg.message)
             {
             case MY_MSG:
             char * pInfo = (char *)msg.wParam;
             printf("recv %s\n",pInfo);
            delete[] pInfo; //這裏釋放了資源
             break;
             }
}

作了一個簡單的消息通訊實驗,讓主 線程中等待用戶輸入,產生不一樣的消息,並把這些消息post給 子線程,子線程根據產生的消息作出不一樣的反映。這些子線程能夠是工做線程也能夠是UI線程。

#include <windows.h>
#include
<cstdio>
#include
<process.h>

#define MY_MSG WM_USER+100
const int MAX_INFO_SIZE = 20;

HANDLE hStartEvent;
// thread start event

// thread function
unsigned __stdcall fun(void *param)
{
     printf(
"thread fun start\n");

     MSG msg;
     PeekMessage(
&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);

    
if(!SetEvent(hStartEvent)) //set thread start event
     {
         printf(
"set start event failed,errno:%d\n",::GetLastError());
        
return 1;
     }
    
    
while(true)
     {
        
if(GetMessage(&msg,0,0,0)) //get msg from message queue
         {
            
switch(msg.message)
             {
            
case MY_MSG:
                
char * pInfo = (char *)msg.wParam;
                 printf(
"recv %s\n",pInfo);
                 delete[] pInfo;
                
break;
             }
         }
     };
    
return 0;
}

int main()
{
     HANDLE hThread;
     unsigned nThreadID;

     hStartEvent
= ::CreateEvent(0,FALSE,FALSE,0); //create thread start event
    if(hStartEvent == 0)
     {
         printf(
"create start event failed,errno:%d\n",::GetLastError());
        
return 1;
     }

    
//start thread
     hThread = (HANDLE)_beginthreadex( NULL, 0, &fun, NULL, 0, &nThreadID );
    
if(hThread == 0)
     {
         printf(
"start thread failed,errno:%d\n",::GetLastError());
         CloseHandle(hStartEvent);
        
return 1;
     }

    
//wait thread start event to avoid PostThreadMessage return errno:1444
     ::WaitForSingleObject(hStartEvent,INFINITE);
     CloseHandle(hStartEvent);

    
int count = 0;
    
while(true)
     {
        
char* pInfo = new char[MAX_INFO_SIZE]; //create dynamic msg
         sprintf(pInfo,"msg_%d",++count);
        
if(!PostThreadMessage(nThreadID,MY_MSG,(WPARAM)pInfo,0))//post thread msg
         {
             printf(
"post message failed,errno:%d\n",::GetLastError());
             delete[] pInfo;
         }
         ::Sleep(
1000);
     }

     CloseHandle(hThread);
    
return 0;
}
要把SETTING 改成多線程的 Project->Settings->click C/C tab, 在Category 中選Code Generation, 而後在Use run-time libray 中選一個 Multithread 配置
相關文章
相關標籤/搜索