MFC中的部分函數

(轉載,原文鏈接http://www.xuebuyuan.com/1829252.html

GetMessage:

BOOL GetMessage(      

    LPMSG lpMsg,
    HWND hWnd,
    UINT wMsgFilterMin,
    UINT wMsgFilterMax
);

The GetMessage function retrieves a message from the calling thread's message queue. The function dispatches incoming sent messages until a posted message is available for retrieval.

Unlike GetMessage, the
PeekMessage function does not wait for a message to be posted before returning.

peekMessage:

   函數功能:該函數爲一個消息檢查線程消息隊列,並將該消息(如果存在)放於指定的結構。
  
函數原型:BOOL PeekMessage(LPMSG IpMsg,HWND hWnd,UINT wMSGfilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);

參數:

lpMsg:接收消息信息的MSG結構指針。
  
  hWnd:其消息被檢查的窗口的句柄。
  
  wMsgFilterMin:指定被檢查的消息範圍裏的第一個消息。
  
  wMsgFilterMax:指定被檢查的消息範圍裏的最後一個消息。
  
  wRemoveMsg:確定消息如何被處理。此參數可取下列值之一:
  
  PM_NOREMOVE:PeekMessage處理後,消息不從隊列裏除掉。
  
  PM_REMOVE:PeekMessage處理後,消息從隊列裏除掉。
  
  可將PM_NOYIELD隨意組合到PM_NOREMOVE或PM_REMOVE。此標誌使系統不釋放等待調用程序空閒的線程。
  
  缺省地,處理所有類型的消息。若只處理某些消息,指定一個或多個下列值:
  
  PM_QS_INPUT:Windows NT5.0和Windows 98:處理鼠標和鍵盤消息。
  
  PM_QS_PAINT:Windows NT 5.0和Windows 98:處理畫圖消息。
  
  PM_QS_POSTMESSAGE:Windows NT 5.0和Windows 98:處理所有被寄送的消息,包括計時器和熱鍵。
  
  PM_QS_SENDMESSAGE:Windows NT 5.0和Windows 98:處理所有發送消息。
  
  返回值:如果消息可得到,返回非零值;如果沒有消息可得到,返回值是零。
  
  備註:和函數GetMessage不一樣的是,函數PeekMesssge在返回前不等待消息被放到隊列裏。
PeekMesssge只得到那些與參數hWnd標識的窗口相聯繫的消息或被lsChild確定爲其子窗口相聯繫的消息,並且該消息要在由參數wMsgFiterMin和wMsgFiherMax確定的範圍內。如果hWnd爲NULL,則PeekMessage接收屬於當前調用線程的窗口的消息(PeekMessage不接收屬於其他線程的窗口的消息)。如果hWnd爲C1,PeekMessage只返回hWnd值爲NULL的消息,該消息由函數PostThreadMessage寄送。如果wMsgFilterMin和wMsgFilterMax都爲零,GetMessage返回所有可得的消息(即,無範圍過濾)。
  
  常數WM_KEYFIRST和WMKEYLAST可作爲過濾值取得所有鍵盤消息;常數WM_MOUSEFIRST和WM_MOUSELAST可用來接收所有的鼠標消息。
  
  PeekMessage通常不從隊列裏清除WM_PANT消息。該消息將保留在隊列裏直到處理完畢。但如果WM_PAINT消息有一個空更新區,PeekMessage將從隊列裏清除WM_PAINT消息。
  
  Windows CE:有一個NULL更新區的WM_PAINT消息不從隊列裏清除。

TranslateMessage函數

TranslateMessage是用來把虛擬鍵消息轉換爲字符消息。由於Windows對所有鍵盤編碼都是採用虛擬鍵的定義,這樣當按鍵按下時,並不得字符消息,需要鍵盤映射轉換爲字符的消息。
TranslateMessage函數用於將虛擬鍵消息轉換爲字符消息。字符消息被投遞到調用線程的消息隊列中,當下一次調用GetMessage函數時被取出。當我們敲擊鍵盤上的某個字符鍵時,系統將產生WM_KEYDOWN和WM_KEYUP消息。這兩個消息的附加參數(wParam和lParam)包含的是虛擬鍵代碼和掃描碼等信息,而我們在程序中往往需要得到某個字符的ASCII碼,TranslateMessage這個函數就可以將WM_KEYDOWN和WM_ KEYUP消息的組合轉換爲一條WM_CHAR消息(該消息的wParam附加參數包含了字符的ASCII碼),並將轉換後的新消息投遞到調用線程的消息隊列中。注意,TranslateMessage函數並不會修改原有的消息,它只是產生新的消息並投遞到消息隊列中。
也就是說TranslateMessage會發現消息裏是否有字符鍵的消息,如果有字符鍵的消息,就會產生WM_CHAR消息,如果沒有就會產生什麼消息。

函數TranslateMessage聲明如下:
WINUSERAPI
BOOL
WINAPI
TranslateMessage(
__in CONST MSG *lpMsg);
lpMsg是檢查需要轉換的消息。

DispatchMessage函數

前面已經介紹從系統隊列裏獲取一條消息,然後經過快捷鍵的函數檢查,又通過字符消息函數的轉換,最後要做的事情就是調用DispatchMessage函數,它的意思就是說要把這條消息發送到窗口裏的消息處理函數WindowProc。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

DispatchMessage
windows消息處理機制是這樣的: 首先系統(也就是windows)把來自硬件(鼠標,鍵盤等消息)和來自應用程序的消息 放到一個系統消息隊列中去. 

而應用程序需要有自己的消息隊列,也就是線程消息隊列。每一個線程有自己的消息隊列,對於多線程的應用程序就有和線程數目相等的線程消息隊列. 
winsows消息隊列把得到的消息發送到線程消息隊列, 線程消息隊列每次取出一條消息發送到指定窗口,不斷循環直到程序退出.這個循環就是靠消息環(while(GetMessage()) TranslateMessage();DispatchMessage(); 實現的。

GetMessage()只是從線程消息中取出一條消息,而DispatchMessage 則把取出的消息發送到目的窗口。

如果收到WM_CLOSE消息則結束循環,發送postqiutmessage(0),處理WM_DESTROY銷燬窗口!  

其實問題的關鍵在於DispatchMessage到底幹了什麼 
如果只是去調用相應的窗口,那自己寫個switch不就可以了 
DispatchMessage與switch不同之處在於DispatchMessage會 
先調用windows,進入管態(大概是range 0),然後再由windows調用 
窗口的函數。 
爲什麼這麼麻煩? 
因爲這樣windows就可以知道你的程序運行到什麼情況了, 
windows來調用你的窗口,這樣你的窗口返回的時候windows就知道 
你已經處理過一個消息了,如果沒有新的消息進入消息隊列 
windows就不再會給你的進程分配時間片 
如果是你自己寫switch的話,windows就不可能這樣靈活的分配時間 
資源利用率就會降低 
那麼還要消息循環幹什麼,windows直接把消息發給窗口不就可以了嗎? 
因爲你要在消息循環裏把KEY_DOWN和KEY_UP組合成WM_CHAR, 
還可以直接屏蔽掉許多對你來說無用的消息,加快速度  

GetMessage:從線程的消息隊列取出一個消息   
    TranslateMessage:     將msg結構傳給Windows,進行一些轉換,比如A鍵按下,轉換成WM_CHAR消息等   
    DispatchMessage():再將msg結構傳給Windows,Windows將該消息發給窗口過程,由窗口過程處理.

TranslateMessage是對一些鍵盤事件做預處理。
GetMessage是從系統爲每個應用程序自動分配的消息對列的頭部得到一個消息。   
   
    TranslateMessage是翻譯需要翻譯的消息   
    
DispatchMessage()則會把翻譯好的消息發送到系統的消息處理函數中,而這個函數又會把這個消息傳遞到註冊窗體時用戶指定的消息處理函數中。
翻譯消息不是簡單的轉換,一個消息被翻譯後,可能會產生幾個消息。




+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TranslateMessage函數將虛擬鍵消息轉換爲字符消息。字符消息被寄送到調用線程的消息隊列裏,當下一次線程調用函數GetMessage或PeekMessage時被讀出。
TranslateMessage是用來把虛擬鍵消息轉換爲字符消息。由於Windows對所有鍵盤編碼都是採用虛擬鍵的定義,這樣當按鍵按下時,並不得字符消息,需要鍵盤映射轉換爲字符的消息。
TranslateMessage函數用於將虛擬鍵消息轉換爲字符消息。字符消息被投遞到調用線程的消息隊列中,當下一次調用GetMessage函數時被取出。當我們敲擊鍵盤上的某個字符鍵時,系統將產生WM_KEYDOWN和WM_KEYUP消息。這兩個消息的附加參數(wParam和lParam)包含的是虛擬鍵代碼和掃描碼等信息,而我們在程序中往往需要得到某個字符的ASCII碼,TranslateMessage這個函數就可以將WM_KEYDOWN和WM_ KEYUP消息的組合轉換爲一條WM_CHAR消息(該消息的wParam附加參數包含了字符的ASCII碼),並將轉換後的新消息投遞到調用線程的消息隊列中。注意,TranslateMessage函數並不會修改原有的消息,它只是產生新的消息並投遞到消息隊列中。
也就是說TranslateMessage會發現消息裏是否有字符鍵的消息,如果有字符鍵的消息,就會產生WM_CHAR消息,如果沒有就會產生什麼消息。
 

消息循環中的TranslateMessage函數和DispatchMessage函數

TranslateMessage函數

函數功能描述:將虛擬鍵消息轉換爲字符消息。字符消息被送到調用線程的消息隊列中,在下一次線程調用函數GetMessage或PeekMessage時被讀出。

.函數原型:
    BOOL TranslateMessage(  CONST MSG *lpMsg );
.參數:
    lpMsg 
        指向一個含有用GetMessage或PeekMessage函數從調用線程的消息隊列中取得消息信息的MSG結構的指針。
.返回值:
    如果消息被轉換(即,字符消息被送到線程的消息隊列中),返回非零值。
    如果消息是 WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, 或 WM_SYSKEYUP,返回非零值,不考慮轉換。
    如果消息沒有轉換(即,字符消息沒被送到線程的消息隊列中),返回值是零。
.備註:
    TranslateMessage函數不修改由參數lpMsg指向的消息。
    消息WM_KEYDOWN和WM_KEYUP組合產生一個WM_CHAR或WM_DEADCHAR消息。消息WM_SYSKEYDOWN和WM_SYSKEYUP組合產生一個WM_SYSCHAR或 WM_SYSDEADCHAR 消息。
    TtanslateMessage僅爲那些由鍵盤驅動器映射爲ASCII字符的鍵產生WM_CHAR消息。
    如果應用程序爲其它用途而處理虛擬鍵消息,不應調用TranslateMessage函數。例如,如果TranslateAccelerator函數返回一個非零值,則應用程序將不調用TranslateMessage函數。
    Windows CE:Windows CE不支持掃描碼或擴展鍵標誌,因此,它不支持由TranslateMessage函數產生的WM_CHAR消息中的lKeyData參數(lParam)16-24的取值。
    TranslateMessage函數只能用於轉換由GetMessage或PeekMessage函數接收到的消息。
 

 

DispatchMessage函數

函數功能:該函數調度一個消息給窗口程序。通常調度從GetMessage取得的消息。消息被調度到的窗口程序即是MainProc()函數。

  函數原型:LONG DispatchMessage(CONST MSG*lpmsg);

  參數:

  lpmsg:指向含有消息的MSG結構的指針。

  返回值:返回值是窗口程序返回的值。儘管返回值的含義依賴於被調度的消息,但返回值通常被忽略。

  備註:MSG結構必須包含有效的消息值。如果參數lpmsg指向一個WM_TIMER消息,並且WM_TIMER消息的參數IParam不爲NULL,則調用IPa1ram指向的函數,而不是調用窗口程序。

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

總結:TranslateMessage函數將鍵盤消息轉化,DispatchMessage函數將消息傳給窗體函數去處理.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

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

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

參數

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

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

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

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

返回值:如果函數調用成功,返回非零值。如 果函數調用失敗,返回值是零。若想獲得更多的錯誤信息,請調用GetLastError函數。如果idThread不是一個有效的線程標識符或由 idThread確定的線程沒有消息隊列,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傳遞的消息如果要包含信 息,要注意在結束的時候釋放消息中的信息。(2.如果是post動態分配的memory給另外一個thread,要注意內存的正確釋放。

在消息中附加信息方法如下

/*構造信息如下*/
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 配置

++++++++++++++++++++++++++++++++++++++++++///////////////////////////+++++++++++++++++++++++++++++++++++++

PostThreadMessage的原型是這樣的

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

PostThreadMessage可以用於線程之間的異步通訊,因爲它不用等待調用者返回,這也許是線程通訊中最簡單的一種方法了。

但是要注意以下問題
1 .PostThreadMessage有時會失敗,報1444錯誤(Invalid thread identifier. )其實這不一定是線程不存在的原因,也有可能是線程不存在消息隊列(message queue)造成的。事實上,並不是每個thread都有message queue,那如何讓thread具有呢?答案是,至少調用message相關的function一次,比如GetMessage,PeekMessage。

2.如果是post動態分配的memory給另外一個thread,要注意內存的正確釋放。

3.PostThreadMessage不能夠post WM_COPYDATE之類的同步消息,否則會報錯

4.最好不要使用PostThreadMessage post message給一個窗口,使用PostMessage替代。

下面是我寫的一個比較嚴整的例子,僅供參考。

#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;
}

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

PeekMessage

Windows CE 5.0

This function checks a thread message queue for a message and places the message (if any) in the specified structure.

BOOL PeekMessage(
  LPMSG lpMsg, 
  HWND hWnd, 
  UINT wMsgFilterMin, 
  UINT wMsgFilterMax, 
  UINT wRemoveMsg 
); 

Parameters

lpMsg
[in] Pointer to an MSG structure that receives message information.
hWnd
[in] Handle to the window whose messages are to be examined.
wMsgFilterMin
[in] Specifies the value of the first message in the range of messages to be examined.
wMsgFilterMax
[in] Specifies the value of the last message in the range of messages to be examined.
wRemoveMsg
[in] Specifies how messages are handled. This parameter can be one of the following values.

Value Description
PM_NOREMOVE Messages are not removed from the queue after processing by PeekMessage.
PM_REMOVE Messages are removed from the queue after processing by PeekMessage. An exception is WM_PAINT messages, which are not removed from the queue.

You can optionally combine the value PM_NOYIELD with either PM_NOREMOVE or PM_REMOVE. This flag prevents the system from releasing any thread that is waiting for the caller to go idle.

Return Values

Nonzero indicates success. Zero indicates failure.

Remarks

Unlike the GetMessage function, the PeekMessage function does not wait for a message to be placed in the queue
before returning.

PeekMessage retrieves only messages associated with the window identified by the hWnd parameter or any of its children as specified by the IsChild function,
and within the range of message values given by the wMsgFilterMin and wMsgFilterMax parameters. If hWnd is NULL, PeekMessage retrieves messages for any window that belongs to the current thread making the call. (PeekMessage does
not retrieve messages for windows that belong to other threads.) If hWnd is –1, PeekMessage only returns messages with a hWnd value of NULL, as posted by thePostThreadMessage function.
If wMsgFilterMin and wMsgFilterMax are both zero, PeekMessage returns all available messages (that is, no range filtering is performed).

The WM_KEYFIRST and WM_KEYLAST constants can be used as filter values to retrieve all keyboard messages; the WM_MOUSEFIRST and WM_MOUSELAST constants can be used to retrieve all mouse messages.

The PeekMessage function does not remove WM_PAINT messages from the queue. WM_PAINT messages remain in the queue until they are processed.

Requirements

OS Versions: Windows CE 1.0 and later.
Header: Winuser.h.
Link Library: Coredll.lib.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

PeekMessage&GetMessage

 

PeekMessage與GetMessage的對比

 

相同點:

PeekMessage函數與GetMessage函數都用於查看應用程序消息隊列,有消息時將隊列中的消息派發出去。

不同點:

無論應用程序消息隊列是否有消息,PeekMessage函數都立即返回,程序得以繼續執行後面的語句(無消息則執行其它指令,有消息時一般要將消息派發出去,再執行其它指令)。

GetMessage函數只有在消息隊列中有消息時返回,隊列中無消息就會一直等,直至下一個消息出現時才返回。在等的這段時間,應用程序不能執行任何指令。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章