Windows消息機制

消息是指什麼?
     消息系統對於一個win32程序來講十分重要,它是一個程序運行的動力源泉。一個消息,是系統定義的一個32位的值,他惟一的定義了一個事件,向 Windows發出一個通知,告訴應用程序某個事情發生了。例如,單擊鼠標、改變窗口尺寸、按下鍵盤上的一個鍵都會使Windows發送一個消息給應用程序。
    消息自己是做爲一個記錄傳遞給應用程序的,這個記錄中包含了消息的類型以及其餘信息。例如,對於單擊鼠標所產生的消息來講,這個記錄中包含了單擊鼠標時的座標。這個記錄類型叫作MSG,MSG含有來自windows應用程序消息隊列的消息信息,它在Windows中聲明以下:html

typedef struct tagMsg
{
       HWND    hwnd;       //接受該消息的窗口句柄
       UINT    message;    //消息常量標識符,也就是咱們一般所說的消息號
       WPARAM  wParam;     //32位消息的特定附加信息,確切含義依賴於消息值
       LPARAM  lParam;     //32位消息的特定附加信息,確切含義依賴於消息值
       DWORD   time;       //消息建立時的時間
       POINT   pt;         //消息建立時的鼠標/光標在屏幕座標系中的位置
}MSG;


    消息能夠由系統或者應用程序產生。系統在發生輸入事件時產生消息。舉個例子, 當用戶敲鍵, 移動鼠標或者單擊控件。系統也產生消息以響應由應用程序帶來的變化, 好比應用程序改變系統字體改變窗體大小。應用程序能夠產生消息使窗體執行任務,或者與其餘應用程序中的窗口通信。編程

消息中有什麼?
   
咱們給出了上面的註釋,是否是會對消息結構有了一個比較清楚的認識?若是尚未,那麼咱們再試着給出下面的解釋:
     hwnd 32位的窗口句柄。窗口能夠是任何類型的屏幕對象,由於Win32可以維護大多數可視對象的句柄(窗口、對話框、按鈕、編輯框等)。
     message用於區別其餘消息的常量值,這些常量能夠是Windows單元中預約義的常量,也能夠是自定義的常量。消息標識符以常量命名的方式指出消息的含義。當窗口過程接收到消息以後,他就會使用消息標識符來決定如何處理消息。例如、WM_PAINT告訴窗口過程窗體客戶區被改變了須要重繪。符號常量指定系統消息屬於的類別,其前綴指明瞭處理解釋消息的窗體的類型。
     wParam 一般是一個與消息有關的常量值,也多是窗口或控件的句柄。
     lParam 一般是一個指向內存中數據的指針。因爲WParam、lParam和Pointer都是32位的,所以,它們之間能夠相互轉換。windows

消息標識符的值
     系統保留消息標識符的值在0x0000在0x03ff(WM_USER-1)範圍。這些值被系統定義消息使用。應用程序不能使用這些值給本身的消息。應用程序消息從WM_USER(0X0400)到0X7FFF,或0XC000到0XFFFF;WM_USER到 0X7FFF範圍的消息由應用程序本身使用;0XC000到0XFFFF範圍的消息用來和其餘應用程序通訊,咱們順便說一下具備標誌性的消息值:
     WM_NULL---0x0000    空消息。
     0x0001----0x0087    主要是窗口消息。
     0x00A0----0x00A9    非客戶區消息 
     0x0100----0x0108    鍵盤消息
     0x0111----0x0126    菜單消息
     0x0132----0x0138    顏色控制消息
     0x0200----0x020A    鼠標消息
     0x0211----0x0213    菜單循環消息
     0x0220----0x0230    多文檔消息
     0x03E0----0x03E8    DDE消息
     0x0400              WM_USER
     0x8000              WM_APP
     0x0400----0x7FFF    應用程序自定義私有消息數組

消息有哪幾種?
   
其實,windows中的消息雖然不少,可是種類並不繁雜,大致上有3種:窗口消息、命令消息和控件通知消息。
     窗口消息大概是系統中最爲常見的消息,它是指由操做系統和控制其餘窗口的窗口所使用的消息。例如CreateWindow、DestroyWindow和MoveWindow等都會激發窗口消息,還有咱們在上面談到的單擊鼠標所產生的消息也是一種窗口消息。
     命令消息,這是一種特殊的窗口消息,他用來處理從一個窗口發送到另外一個窗口的用戶請求,例如按下一個按鈕,他就會向主窗口發送一個命令消息。
     控件通知消息,是指這樣一種消息,一個窗口內的子控件發生了一些事情,須要通知父窗口。通知消息只適用於標準的窗口控件如按鈕、列表框、組合框、編輯框,以及Windows公共控件如樹狀視圖、列表視圖等。例如,單擊或雙擊一個控件、在控件中選擇部分文本、操做控件的滾動條都會產生通知消息。她相似於命令消息,當用戶與控件窗口交互時,那麼控件通知消息就會從控件窗口發送到它的主窗口。可是這種消息的存在並非爲了處理用戶命令,而是爲了讓主窗口可以改變控件,例如加載、顯示數據。例如按下一個按鈕,他向父窗口發送的消息也能夠看做是一個控件通知消息;單擊鼠標所產生的消息能夠由主窗口直接處理,而後交給控件窗口處理。
    其中窗口消息及控件通知消息主要由窗口類即直接或間接由CWND類派生類處理。相對窗口消息及控件通知消息而言,命令消息的處理對象範圍就廣得多,它不只能夠由窗口類處理,還能夠由文檔類,文檔模板類及應用類所處理。
    因爲控件通知消息很重要的,人們用的也比較多,可是具體的含義每每令初學者暈頭轉向,因此我決定把常見的幾個列出來供你們參考:
按扭控件
BN_CLICKED        用戶單擊了按鈕
 BN_DISABLE 按鈕被禁止
 BN_DOUBLECLICKED  用戶雙擊了按鈕
 BN_HILITE  用/戶加亮了按鈕
 BN_PAINT  按鈕應當重畫
 BN_UNHILITE 加亮應當去掉

組合框控件
 CBN_CLOSEUP 組合框的列表框被關閉
 CBN_DBLCLK 用戶雙擊了一個字符串
 CBN_DROPDOWN 組合框的列表框被拉出
 CBN_EDITCHANGE 用戶修改了編輯框中的文本
 CBN_EDITUPDATE 編輯框內的文本即將更新
 CBN_ERRSPACE 組合框內存不足
 CBN_KILLFOCUS 組合框失去輸入焦點
 CBN_SELCHANGE 在組合框中選擇了一項
 CBN_SELENDCANCEL 用戶的選擇應當被取消
 CBN_SELENDOK 用戶的選擇是合法的
 CBN_SETFOCUS 組合框得到輸入焦點

編輯框控件
 EN_CHANGE 編輯框中的文本己更新
 EN_ERRSPACE 編輯框內存不足
 EN_HSCROLL 用戶點擊了水平滾動條
 EN_KILLFOCUS 編輯框正在失去輸入焦點
 EN_MAXTEXT 插入的內容被截斷
 EN_SETFOCUS 編輯框得到輸入焦點
 EN_UPDATE 編輯框中的文本將要更新
 EN_VSCROLL 用戶點擊了垂直滾動條消息含義

列表框控件
 LBN_DBLCLK 用戶雙擊了一項
 LBN_ERRSPACE 列表框內存不夠
 LBN_KILLFOCUS 列表框正在失去輸入焦點
 LBN_SELCANCEL 選擇被取消
 LBN_SELCHANGE 選擇了另外一項
 LBN_SETFOCUS 列表框得到輸入焦點服務器

隊列消息和非隊列消息
   
從消息的發送途徑來看,消息能夠分紅2種:隊列消息和非隊列消息。消息隊列由能夠分紅系統消息隊列和線程消息隊列。系統消息隊列由Windows維護,線程消息隊列則由每一個GUI線程本身進行維護,爲避免給non-GUI現成建立消息隊列,全部線程產生時並無消息隊列,僅當線程第一次調用GDI函數時系統纔給線程建立一個消息隊列。隊列消息送到系統消息隊列,而後到線程消息隊列;非隊列消息直接送給目的窗口過程。
     對於隊列消息,最多見的是鼠標和鍵盤觸發的消息,例如WM_MOUSERMOVE,WM_CHAR等消息,還有一些其它的消息,例如:WM_PAINT、 WM_TIMER和WM_QUIT。當鼠標、鍵盤事件被觸發後,相應的鼠標或鍵盤驅動程序就會把這些事件轉換成相應的消息,而後輸送到系統消息隊列,由 Windows系統去進行處理。Windows系統則在適當的時機,從系統消息隊列中取出一個消息,根據前面咱們所說的MSG消息結構肯定消息是要被送往那個窗口,而後把取出的消息送往建立窗口的線程的相應隊列,下面的事情就該由線程消息隊列操心了,Windows開始忙本身的事情去了。線程看到本身的消息隊列中有消息,就從隊列中取出來,經過操做系統發送到合適的窗口過程去處理。
     通常來說,系統老是將消息Post在消息隊列的末尾。這樣保證窗口以先進先出的順序接受消息。然而,WM_PAINT是一個例外,同一個窗口的多個 WM_PAINT被合併成一個 WM_PAINT 消息, 合併全部的無效區域到一個無效區域。合併WM_PAIN的目的是爲了減小刷新窗口的次數。



    非隊列消息將會繞過系統隊列和消息隊列,直接將消息發送到窗口過程,。系統發送非隊列消息通知窗口,系統發送消息通知窗口。例如,當用戶激活一個窗口系統發送WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR。這些消息通知窗口它被激活了。非隊列消息也能夠由當應用程序調用系統函數產生。例如,當程序調用SetWindowPos系統發送WM_WINDOWPOSCHANGED消息。一些函數也發送非隊列消息,例以下面咱們要談到的函數。
     
消息的發送
     瞭解了上面的這些基礎理論以後,咱們就能夠進行一下簡單的消息發送與接收。
     把一個消息發送到窗口有3種方式:發送、寄送和廣播。
     發送消息的函數有SendMessage、SendMessageCallback、SendNotifyMessage、 SendMessageTimeout;寄送消息的函數主要有PostMessage、PostThreadMessage、 PostQuitMessage;廣播消息的函數我知道的只有BroadcastSystemMessage、 BroadcastSystemMessageEx。
     SendMessage的原型以下:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam),這個函數主要是向一個或多個窗口發送一條消息,一直等到消息被處理以後纔會返回。不過須要注意的是,若是接收消息的窗口是同一個應用程序的一部分,那麼這個窗口的窗口函數就被做爲一個子程序立刻被調用;若是接收消息的窗口是被另外的線程所建立的,那麼窗口系統就切換到相應的線程而且調用相應的窗口函數,這條消息不會被放進目標應用程序隊列中。函數的返回值是由接收消息的窗口的窗口函數返回,返回的值取決於被髮送的消息。
     PostMessage的原型以下:BOOL PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam),該函數把一條消息放置到建立hWnd窗口的線程的消息隊列中,該函數不等消息被處理就立刻將控制返回。須要注意的是,若是hWnd參數爲 HWND_BROADCAST,那麼,消息將被寄送給系統中的全部的重疊窗口和彈出窗口,可是子窗口不會收到該消息;若是hWnd參數爲NULL,則該函數相似於將dwThreadID參數設置成當前線程的標誌來調用PostThreadMEssage函數。
  從上面的這2個具備表明性的函數,咱們能夠看出消息的發送方式和寄送方式的區別所在:被髮送的消息是否會被當即處理,函數是否當即返回。被髮送的消息會被當即處理,處理完畢後函數纔會返回;被寄送的消息不會被當即處理,他被放到一個先進先出的隊列中,一直等到應用程序空線的時候纔會被處理,不過函數放置消息後當即返回。

  實際上,發送消息到一個窗口處理過程和直接調用窗口處理過程之間並無太大的區別,他們直接的惟一區別就在於你能夠要求操做系統截獲全部被髮送的消息,可是不可以截獲對窗口處理過程的直接調用。
  以寄送方式發送的消息一般是與用戶輸入事件相對應的,由於這些事件不是十分緊迫,能夠進行緩慢的緩衝處理,例如鼠標、鍵盤消息會被寄送,而按鈕等消息則會被髮送。
  廣播消息用得比較少,BroadcastSystemMessage函數原型以下:
      long BroadcastSystemMessage(DWORD dwFlags,LPDWORD lpdwRecipients,UINT uiMessage,WPARAM wParam,LPARAM lParam);該函數能夠向指定的接收者發送一條消息,這些接收者能夠是應用程序、可安裝的驅動程序、網絡驅動程序、系統級別的設備驅動消息和他們的任意組合。須要注意的是,若是dwFlags參數是BSF_QUERY而且至少一個接收者返回了BROADCAST_QUERY_DENY,則返回值爲0,若是沒有指定BSF_QUERY,則函數將消息發送給全部接收者,而且忽略其返回值。網絡

消息的接收
 
消息的接收主要有3個函數:GetMessage、PeekMessage、WaitMessage。
  GetMessage原型以下:BOOL GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax);該函數用來獲取與hWnd參數所指定的窗口相關的且wMsgFilterMin和wMsgFilterMax參數所給出的消息值範圍內的消息。須要注意的是,若是hWnd爲NULL,則GetMessage獲取屬於調用該函數應用程序的任一窗口的消息,若是 wMsgFilterMin和wMsgFilterMax都是0,則GetMessage就返回全部可獲得的消息。函數獲取以後將刪除消息隊列中的除 WM_PAINT消息以外的其餘消息,至於WM_PAINT則只有在其處理以後才被刪除。
   PeekMessage原型以下:BOOL PeekMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);該函數用於查看應用程序的消息隊列,若是其中有消息就將其放入lpMsg所指的結構中,不過,與GetMessage不一樣的是,PeekMessage函數不會等到有消息放入隊列時才返回。一樣,若是hWnd爲NULL,則PeekMessage獲取屬於調用該函數應用程序的任一窗口的消息,若是hWnd=-1,那麼函數只返回把hWnd參數爲NULL的PostAppMessage函數送去的消息。若是 wMsgFilterMin和wMsgFilterMax都是0,則PeekMessage就返回全部可獲得的消息。函數獲取以後將視最後一個參數來決定是否刪除消息隊列中的除 WM_PAINT消息以外的其餘消息,至於WM_PAINT則只有在其處理以後才被刪除。
   WaitMessage原型以下:BOOL WaitMessage();當一個應用程序無事可作時,該函數就將控制權交給另外的應用程序,同時將該應用程序掛起,直到一個新的消息被放入應用程序的隊列之中才返回。併發

消息的處理
  接下來咱們談一下消息的處理,首先咱們來看一下VC中的消息泵:框架

while(GetMessage(&msg, NULL, 0, 0))
{
       if(!TranslateAccelerator(msg.hWnd, hAccelTable, &msg))
      
            TranslateMessage(&msg);
            DispatchMessage(&msg);
       }
}

 

   首先,GetMessage從進程的主線程的消息隊列中獲取一個消息並將它複製到MSG結構,若是隊列中沒有消息,則GetMessage函數將等待一個消息的到來之後才返回。若是你將一個窗口句柄做爲第二個參數傳入GetMessage,那麼只有指定窗口的的消息能夠從隊列中得到。GetMessage也能夠從消息隊列中過濾消息只接受消息隊列中落在範圍內的消息。這時候就要利用GetMessage/PeekMessage指定一個消息過濾器。這個過濾器是一個消息標識符的範圍或者是一個窗體句柄,或者二者同時指定。當應用程序要查找一個後入消息隊列的消息是頗有用。WM_KEYFIRST 和 WM_KEYLAST 常量用於接受全部的鍵盤消息。 WM_MOUSEFIRST 和 WM_MOUSELAST 常量用於接受全部的鼠標消息。 
 而後TranslateAccelerator判斷該消息是否是一個按鍵消息而且是一個加速鍵消息,若是是,則該函數將把幾個按鍵消息轉換成一個加速鍵消息傳遞給窗口的回調函數。處理了加速鍵以後,函數TranslateMessage將把兩個按鍵消息WM_KEYDOWN和WM_KEYUP轉換成一個 WM_CHAR,不過須要注意的是,消息WM_KEYDOWN,WM_KEYUP仍然將傳遞給窗口的回調函數。     
 處理完以後,DispatchMessage函數將把此消息發送給該消息指定的窗口中已設定的回調函數。若是消息是WM_QUIT,則 GetMessage返回0,從而退出循環體。應用程序可使用PostQuitMessage來結束本身的消息循環。一般在主窗口的 WM_DESTROY消息中調用。
 下面咱們舉一個常見的小例子來講明這個消息泵的運用:函數

if (::PeekMessage(&msg, m_hWnd, WM_KEYFIRST,WM_KEYLAST, PM_REMOVE))
{
          if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE)...
}


  這裏咱們接受全部的鍵盤消息,因此就用WM_KEYFIRST 和 WM_KEYLAST做爲參數。最後一個參數能夠是PM_NOREMOVE 或者 PM_REMOVE,表示消息信息是否應該從消息隊列中刪除。                 
   因此這段小代碼就是判斷是否按下了Esc鍵,若是是就進行處理。post

窗口過程
 窗口過程是一個用於處理全部發送到這個窗口的消息的函數。任何一個窗口類都有一個窗口過程。同一個類的窗口使用一樣的窗口過程來響應消息。系統發送消息給窗口過程將消息數據做爲參數傳遞給他,消息到來以後,按照消息類型排序進行處理,其中的參數則用來區分不一樣的消息,窗口過程使用參數產生合適行爲。
 一個窗口過程不常常忽略消息,若是他不處理,它會將消息傳回到執行默認的處理。窗口過程經過調用DefWindowProc來作這個處理。窗口過程必須 return一個值做爲它的消息處理結果。大多數窗口只處理小部分消息和將其餘的經過DefWindowProc傳遞給系統作默認的處理。窗口過程被全部屬於同一個類的窗口共享,能爲不一樣的窗口處理消息。下面咱們來看一下具體的實例:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 int wmId, wmEvent;
 PAINTSTRUCT ps;
 HDC hdc;
 TCHAR szHello[MAX_LOADSTRING];
 LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

 switch (message) 
 {
  case WM_COMMAND:
         wmId    = LOWORD(wParam); 
         wmEvent = HIWORD(wParam); 
         // Parse the menu selections:
         switch (wmId)
         {
          case IDM_ABOUT:
             DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
             break;
          case IDM_EXIT:
             DestroyWindow(hWnd);
             break;
          default:
             return DefWindowProc(hWnd, message, wParam, lParam);
         }
   break;

  case WM_PAINT:
         hdc = BeginPaint(hWnd, &ps);
         // TODO: Add any drawing code here
         RECT rt;
         GetClientRect(hWnd, &rt);
         DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
         EndPaint(hWnd, &ps);
         break;

  case WM_DESTROY:
         PostQuitMessage(0);
         break;
  default:
         return DefWindowProc(hWnd, message, wParam, lParam);
  }
  return 0;
}

 

消息分流器
  一般的窗口過程是經過一個switch語句來實現的,這個事情很煩,有沒有更簡便的方法呢?有,那就是消息分流器,利用消息分流器,咱們能夠把switch語句分紅更小的函數,每個消息都對應一個小函數,這樣作的好處就是對消息更容易管理。
  之因此被稱爲消息分流器,就是由於它能夠對任何消息進行分流。下面咱們作一個函數就很清楚了:

void MsgCracker(HWND hWnd,int id,HWND hWndCtl,UINT codeNotify)
{
      switch(id)
      {
     case ID_A:
                  if(codeNotify==EN_CHANGE)
                  break;
     case ID_B:
                  if(codeNotify==BN_CLICKED)
                  break;
             .
       }
}


而後咱們修改一下窗口過程:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
       switch(message)
      {
             HANDLE_MSG(hWnd,WM_COMMAND,MsgCracker);
             HANDLE_MSG(hWnd,WM_DESTROY,MsgCracker);
           default:
                    return DefWindowProc(hWnd, message, wParam, lParam);
   }
  return 0;
}


在WindowsX.h中定義了以下的HANDLE_MSG宏:

   #define HANDLE_MSG(hwnd,msg,fn) \
             switch(msg): return HANDLE_##msg((hwnd),(wParam),(lParam),(fn));


實際上,HANDLE_WM_XXXX都是宏,例如:HANDLE_MSG(hWnd,WM_COMMAND,MsgCracker);將被轉換成以下定義:

   #define HANDLE_WM_COMMAND(hwnd,wParam,lParam,fn)\ 
             ((fn)((hwnd),(int)(LOWORD(wParam)),(HWND)(lParam),(UINT)HIWORD(wParam)),0L);


好了,事情到了這一步,應該一切都明朗了。
不過,咱們發如今windowsx.h裏面還有一個宏:FORWARD_WM_XXXX,咱們仍是那WM_COMMAND爲例,進行分析:

   #define FORWARD_WM_COMMAND(hwnd, id, hwndCtl, codeNotify, fn) \
     (void)(fn)((hwnd), WM_COMMAND, MAKEWPARAM((UINT)(id),(UINT)(codeNotify)), (LPARAM)(HWND)(hwndCtl))


因此實際上,FORWARD_WM_XXXX將消息參數進行了從新構造,生成了wParam && lParam,而後調用了咱們定義的函數。

前面,咱們分析了消息的基本理論和基本的函數及用法,接下來,咱們將進一步討論消息傳遞在MFC中的實現。

MFC消息的處理實現方式
  初看MFC中的各類消息,以及在頭腦中根深蒂固的C++的影響,咱們可能很天然的就會想到利用C++的三大特性之一:虛擬機制來實現消息的傳遞,可是通過分析,咱們看到事情並非想咱們想象的那樣,在MFC中消息是經過一種所謂的消息映射機制來處理的。
  爲何呢?在潘愛民老師翻譯的《Visual C++技術內幕》(第4版)中給出了詳細的緣由說明,我再簡要的說一遍。在CWnd類中大約有110個消息,還有其它的MFC的類呢,算起來消息太多了,在C++中對程序中用到的每個派生類都要有一個vtable,每個虛函數在vtable中都要佔用一個4字節大小的入口地址,這樣一來,對於每一個特定類型的窗口或控件,應用程序都須要一個440KB大小的表來支持虛擬消息控件函數。
  若是說上面的窗口或控件能夠勉強實現的話,那麼對於菜單命令消息及按鈕命令消息呢?由於不一樣的應用程序有不一樣的菜單和按鈕,咱們怎麼處理呢?在MFC 庫的這種消息映射系統就避免了使用大的vtable,而且可以在處理常規Windows消息的同時處理各類各樣的應用程序的命令消息。
  說白了,MFC中的消息機制其實質是一張巨大的消息及其處理函數的一一對應表,而後加上分析處理這張表的應用框架內部的一些程序代碼.這樣就能夠避免在SDK編程中用到的繁瑣的CASE語句。

MFC的消息映射的基類CCmdTarget
  若是你想讓你的控件可以進行消息映射,就必須從CCmdTarget類中派生。CCmdTarget類是MFC處理命令消息的基礎、核心。MFC爲該類設計了許多成員函數和一些成員數據,基本上是爲了解決消息映射問題的,全部響應消息或事件的類都從它派生,例如:應用程序類、框架類、文檔類、視圖類和各類各樣的控件類等等,還有不少。
不過這個類裏面有2個函數對消息映射很是重要,一個是靜態成員函數DispatchCmdMsg,另外一個是虛函數OnCmdMsg。
DispatchCmdMsg專門供MFC內部使用,用來分發Windows消息。OnCmdMsg用來傳遞和發送消息、更新用戶界面對象的狀態。
CCmdTarget對OnCmdMsg的默認實現:在當前命令目標(this所指)的類和基類的消息映射數組裏搜索指定命令消息的消息處理函數。
  這裏使用虛擬函數GetMessageMap獲得命令目標類的消息映射入口數組_messageEntries,而後在數組裏匹配命令消息ID相同、控制通知代碼也相同的消息映射條目。其中GetMessageMap是虛擬函數,因此能夠確認當前命令目標的確切類。
若是找到了一個匹配的消息映射條目,則使用DispachCmdMsg調用這個處理函數;
若是沒有找到,則使用_GetBaseMessageMap獲得基類的消息映射數組,查找,直到找到或搜尋了全部的基類(到CCmdTarget)爲止;
若是最後沒有找到,則返回FASLE。
  每一個從CCmdTarget派生的命令目標類均可以覆蓋OnCmdMsg,利用它來肯定是否能夠處理某條命令,若是不能,就經過調用下一命令目標的 OnCmdMsg,把該命令送給下一個命令目標處理。一般,派生類覆蓋OnCmdMsg時,要調用基類的被覆蓋的OnCmdMsg。
  在MFC框架中,一些MFC命令目標類覆蓋了OnCmdMsg,如框架窗口類覆蓋了該函數,實現了MFC的標準命令消息發送路徑。必要的話,應用程序也能夠覆蓋OnCmdMsg,改變一個或多個類中的發送規定,實現與標準框架發送規定不一樣的發送路徑。例如,在如下狀況能夠做這樣的處理:在要打斷髮送順序的類中把命令傳給一個非MFC默認對象;在新的非默認對象中或在可能要傳出命令的命令目標中。

消息映射的內容
    經過ClassWizard爲咱們生成的代碼,咱們能夠看到,消息映射基本上分爲2大部分:
    在頭文件(.h)中有一個宏DECLARE_MESSAGE_MAP(),他被放在了類的末尾,是一個public屬性的;與之對應的是在實現部分(.cpp)增長了一章消息映射表,內容以下:
    BEGIN_MESSAGE_MAP(當前類, 當前類的基類)
       //{{AFX_MSG_MAP(CMainFrame)
         消息的入口項
       //}}AFX_MSG_MAP
   END_MESSAGE_MAP()
   可是僅是這兩項還遠不足以完成一條消息,要是一個消息工做,必須有如下3個部分去協做:
1.在類的定義中加入相應的函數聲明;
2.在類的消息映射表中加入相應的消息映射入口項;
3.在類的實現中加入相應的函數體;

消息的添加
   有了上面的這些只是做爲基礎,咱們接下來就作咱們最熟悉、最經常使用的工做:添加消息。MFC消息的添加主要有2種方法:自動/手動,咱們就以這2種方法爲例,說一下如何添加消息。
   一、利用Class Wizard實現自動添加
      在菜單中選擇View-->Class Wizard,也能夠用單擊鼠標右鍵,選擇Class Wizard,一樣能夠激活Class Wizard。選擇Message Map標籤,從Class name組合框中選取咱們想要添加消息的類。在Object IDs列表框中,選取類的名稱。此時, Messages列表框顯示該類的大多數(若不是所有的話)可重載成員函數和窗口消息。類重載顯示在列表的上部,以實際虛構成員函數的大小寫字母來表示。其餘爲窗口消息,以大寫字母出現,描述了實際窗口所能響應的消息ID。選中咱們向添加的消息,單擊Add Function按鈕,Class Wizard自動將該消息添加進來。
      有時候,咱們想要添加的消息本應該出如今Message列表中,但是就是找不到,怎麼辦?不要着急,咱們能夠利用Class Wizard上Class Info標籤以擴展消息列表。在該頁中,找到Message Filter組合框,經過它能夠改變首頁中Messages列表框中的選項。這裏,咱們選擇Window,從而顯示全部的窗口消息,一把狀況下,你想要添加的消息就能夠在Message列表框中出現了,若是尚未,那就接着往下看:)

   二、手動地添加消息處理函數
    若是在Messages列表框中仍然看不到咱們想要的消息,那麼該消息多是被系統忽略掉或者是你本身建立的,在這種狀況下,就必須本身手工添加。根據咱們前面所說的消息工做的3個部件,咱們一一進行處理:
      1) 在類的. h文件中添加處理函數的聲明,緊接在//}}AFX_MSG行以後加入聲明,注意:必定要以afx_msg開頭。
     一般,添加處理函數聲明的最好的地方是源代碼中Class Wizard維護的表下面,可是在它標記其領域的{{}}括弧外面。這些括弧中的任何東西都將會被Class Wizard銷燬。
      2) 接着,在用戶類的.cpp文件中找到//}}AFX_MSG_MAP行,緊接在它以後加入消息入口項。一樣,也是放在{ {} }的外面
      3) 最後,在該文件中添加消息處理函數的實體。

 

 

消息範圍

說 明

0 ~ WM_USER – 1

系統消息

WM_USER ~ 0x7FFF

自定義窗口類整數消息

WM_APP ~ 0xBFFF

應用程序自定義消息

0xC000 ~ 0xFFFF

應用程序字符串消息

> 0xFFFF

爲之後系統應用保留

表A-2  經常使用Windows消息

消息名稱

說  明

WM_NULL 

0x0000

空消息,此消息將被接收窗口忽略

WM_CREATE 

0x0001

應用程序建立一個窗口

WM_DESTROY

0x0002

一個窗口被銷燬

WM_MOVE

0x0003

移動一個窗口

WM_SIZE

0x0005

改變一個窗口的大小

WM_ACTIVATE

0x0006

一個窗口被激活或失去激活狀態

WM_SETFOCUS

0x0007

得到焦點後

WM_KILLFOCUS

0x0008

失去焦點

WM_ENABLE

0x000A

應用程序Enable狀態改變時產生

WM_SETREDRAW

0x000B

設置窗口是否能重畫

WM_SETTEXT

0x000C

應用程序發送此消息來設置一個窗口的文本

WM_GETTEXT

0x000D

應用程序發送此消息來複制對應窗口的文本到緩衝區

WM_GETTEXTLENGTH

0x000E

獲得與一個窗口有關的文本的長度(不包含空字符)

WM_PAINT

0x000F

要求一個窗口重繪本身

WM_CLOSE

0x0010

當一個窗口或應用程序要關閉時發送一個信號

WM_QUERYENDSESSION

0x0011

用戶選擇結束對話框或應用程序本身調用ExitWindows()函數

WM_QUIT

0x0012

用來結束程序運行或應用程序調用Postquitmessage()函數來產生此消息

WM_QUERYOPEN

0x0013

當用戶窗口恢復之前的大小位置時,把此消息發送給某個圖標

WM_ERASEBKGND

0x0014

當窗口背景必須被擦除時(例如在窗口改變大小時)

WM_SYSCOLORCHANGE

0x0015

當系統顏色改變時,發送此消息給全部頂級窗口

WM_ENDSESSION

0x0016

當系統進程發出WM_QUERYENDSESSION消息後,此消息發送給應用程序

WM_SHOWWINDOW

0x0018

當隱藏或顯示窗口是發送此消息給這個窗口

WM_ACTIVATEAPP

0x001C

當某個窗口將被激活時,將被激活窗口和當前活動(即將失去激活)窗口會收到此消息,發此消息給應用程序哪一個窗口是激活的,哪一個是非激活的

WM_FONTCHANGE

0x001D

當系統的字體資源庫變化時發送此消息給全部頂級窗口

WM_TIMECHANGE

0x001E

當系統的時間變化時發送此消息給全部頂級窗口

WM_CANCELMODE

0x001F

發送此消息來取消某種正在進行的操做

WM_SETCURSOR

0x0020

若是鼠標引發光標在某個窗口中移動且鼠標輸入沒有被捕獲時,發消息給該窗口

WM_MOUSEACTIVATE

0x0021

當光標在某個非激活的窗口中而用戶正按着鼠標的某個鍵發送此消息給當前窗口

WM_CHILDACTIVATE

0x0022

發送此消息給MDI子窗口當用戶點擊此窗口的標題欄,或當窗口被激活、移動、改變大小

WM_QUEUESYNC

0x0023

此消息由基於計算機的訓練程序發送,經過WH_JOURNALPALYBACK的Hook程序分離出用戶輸入消息

WM_GETMINMAXINFO

0x0024

當窗口要將要改變大小或位置時,發送此消息給該窗口

WM_PAINTICON

0x0026

當窗口圖標將要被重繪時,發送此消息給該窗口

WM_ICONERASEBKGND

0x0027

在一個最小化窗口的圖標在重繪前,當圖標背景必須被重繪時,發送此消息給該窗口

WM_NEXTDLGCTL

0x0028

發送此消息給一個對話框程序以更改焦點位置

WM_SPOOLERSTATUS

0x002A

當打印管理列隊增長或減小一條做業時發出此消息

WM_DRAWITEM

0x002B

當Button,ComboBox,Listbox,Menu控件的外觀改變時,發送此消息給這些控件的全部者

WM_MEASUREITEM

0x002C

當Button,ComboBox,list box,ListView,Menu 項被建立時,發送此消息給控件的全部者

WM_DELETEITEM

0x002D

當ListBox 或 ComboBox 被銷燬或當某些項經過發送LB_DELETESTRING、LB_RESETCONTENT、 CB_DELETESTRING、CB_RESETCONTENT 消息被刪除時,發送此消息給控件的全部者

WM_VKEYTOITEM

0x002E

一個具備LBS_WANTKEYBOARDINPUT風格的ListBox控件發送此消息給它的全部者,以此來響應WM_KEYDOWN消息

WM_CHARTOITEM

0x002F

一個具備LBS_WANTKEYBOARDINPUT風格的ListBox控件發送此消息給它的全部者,以此來響應WM_CHAR消息

WM_SETFONT

0x0030

應用程序繪製控件時,發送此消息獲得以何種字體繪製控件中的文本

WM_GETFONT

0x0031

應用程序發送此消息獲得當前控件繪製文本的字體

WM_SETHOTKEY

0x0032

應用程序發送此消息讓一個窗口與一個熱鍵相關聯

WM_GETHOTKEY

0x0033

應用程序發送此消息來判斷熱鍵與某個窗口是否有關聯

WM_QUERYDRAGICON

0x0037

此消息發送給最小化窗口,當此窗口將要被拖放而它的類中沒有定義圖標,應用程序就返回一個圖標或光標的句柄,當用戶拖放圖標時系統顯示這個圖標或光標

WM_COMPAREITEM

0x0039

發送此消息來斷定ComboBox或ListBox新增長的項的相對位置

WM_COMPACTING

0x0041

顯示內存已經不多了

WM_WINDOWPOSCHANGING

0x0046

當調用SetWindowPos()函數改變窗口的大小和位置後,發送此消息給該窗口

WM_POWER

0x0048

當系統將進入掛起狀態時發送此消息給全部進程

WM_COPYDATA

0x004A

當一個應用程序傳遞數據給另外一個應用程序時發送此消息

WM_CANCELJOURNAL

0x004B

當某個用戶取消程序日誌激活狀態,發送此消息給應用程序

WM_NOTIFY

0x004E

當某個控件的某個事件已經發生或這個控件須要獲得一些信息時,發送此消息給它的父窗口

WM_INPUTLANGCHANGEREQUEST

0x0050

當用戶選擇某種輸入語言,或輸入語言的熱鍵改變

WM_INPUTLANGCHANGE

0x0051

當應用程序輸入語言改變後發送此消息給受影響的最頂級窗口

WM_TCARD

0x0052

當應用程序已經初始化Windows幫助例程時發送此消息給應用程序

WM_HELP

0x0053

當用戶按下了F1,若是某個菜單是激活的,就發送此消息給此窗口關聯的菜單,不然就發送給有焦點的窗口,若是當前都沒有焦點,就把此消息發送給當前激活的窗口

WM_USERCHANGED

0x0054

當用戶已經登陸或退出後發送此消息給全部的窗口,當用戶登陸或退出時系統更新用戶的具體設置信息,在用戶更新設置時系統立刻發送此消息

WM_NOTIFYFORMAT

0x0055

公用控件和它們的父窗口經過此消息來判斷在WM_NOTIFY消息中是使用ANSI仍是UNICODE形式的結構,使用此控件能使某個控件與它的父控件進行相互通訊

WM_CONTEXTMENU

0x007B

當用戶在某個窗口中點擊右鍵,則發送此消息給該窗口

WM_STYLECHANGING

0x007C

當將要調用SetWindowLong()函數窗口的一個或多個風格時,發送此消息給該窗口

WM_STYLECHANGED

0x007D

當調用SetWindowLong()函數改變了窗口的一個或多個風格後,發送此消息給該窗口

WM_DISPLAYCHANGE

0x007E

當顯示器的分辨率改變後發送此消息給全部的窗口

WM_GETICON

0x007F

發送此消息給某個窗口,返回與某個窗口有關聯的大圖標或小圖標的句柄

WM_SETICON

0x0080

應用程序發送此消息讓一個新的大圖標或小圖標與某個窗口關聯

WM_NCCREATE

0x0081

當某個窗口第一次被建立時,此消息在WM_CREATE消息被髮送前發送

WM_NCDESTROY

0x0082

此消息通知某個窗口,正在銷燬非客戶區

WM_NCCALCSIZE

0x0083

當計算某個窗口的客戶區大小和位置時發送此消息

WM_NCHITTEST

0x0084

移動鼠標,按住或釋放鼠標時產生此消息

WM_NCPAINT

0x0085

當某個窗口的框架必須被繪製時,應用程序發送此消息給該窗口

WM_NCACTIVATE

0x0086

經過改變某個窗口的非客戶區來表示窗口是處於激活仍是非激活狀態時,此消息被髮送給該窗口

WM_NCMOUSEMOVE

0x00A0

當光標在窗口的非客戶區(窗口標題欄及邊框)內移動時發送此消息給該窗口

WM_NCLBUTTONDOWN

0x00A1

當光標在窗口的非客戶區並按下鼠標左鍵時發送此消息

WM_NCLBUTTONUP

0x00A2

當光標在窗口的非客戶區並釋放鼠標左鍵時發送此消息

WM_NCLBUTTONDBLCLK

0x00A3

當光標在窗口的非客戶區並雙擊鼠標左鍵時發送此消息

WM_NCRBUTTONDOWN

0x00A4

當光標在窗口的非客戶區並按下鼠標右鍵時發送此消息

WM_NCRBUTTONUP

0x00A5

當光標在窗口的非客戶區並釋放鼠標右鍵時發送此消息

WM_NCRBUTTONDBLCLK

0x00A6

當光標在窗口的非客戶區並雙擊鼠標右鍵時發送此消息

WM_NCMBUTTONDOWN

0x00A7

當光標在窗口的非客戶區並按下鼠標中鍵時發送此消息

WM_NCMBUTTONUP

0x00A8

當光標在窗口的非客戶區並釋放鼠標中鍵時發送此消息

WM_NCMBUTTONDBLCL

0x00A9

當光標在窗口的非客戶區並雙擊鼠標中鍵時發送此消息

WM_KEYDOWN

0x0100

按下一個非系統鍵(按下鍵時未按下「ALT」鍵)

WM_KEYUP

0x0101

釋放一個非系統鍵

WM_CHAR

0x0102

按下某鍵,當TranslateMessage()轉發WM_KEYDOWN後發送本消息

WM_DEADCHAR

0x0103

釋放某鍵,當TranslateMessage()轉發WM_KEYUP後發送本消息

WM_SYSKEYDOWN

0x0104

當按住ALT鍵同時按下其餘鍵時發送此消息給擁有鍵盤焦點的窗口

WM_SYSKEYUP

0x0105

當釋放一個鍵同時按住ALT鍵時發送此消息給擁有鍵盤焦點的窗口

WM_SYSCHAR

0x0106

當TranslateMessage()轉發WM_SYSKEYDOWN後發送此消息給擁有鍵盤焦點的窗口

WM_SYSDEADCHAR

0x0107

當TranslateMessage()轉發WM_SYSKEYUP後發送此消息給擁有鍵盤焦點的窗口

WM_INITDIALOG

0x0110

在被顯示前發送此消息對話框,一般用此消息初始化控件和執行其餘任務

WM_COMMAND

0x0111

選擇窗口菜單項或某個控件發送一條消息給它的父窗口或按下一個快捷鍵時產生此消息

WM_SYSCOMMAND

0x0112

選擇窗口菜單項或選擇最大化或最小化時,發送此消息給該窗口

WM_TIMER

0x0113

發生了定時器事件

WM_HSCROLL

0x0114

當窗口水平滾動條產生一個滾動事件時發送此消息給該窗口和滾動條的全部者

WM_VSCROLL

0x0115

當窗口垂直滾動條產生一個滾動事件時發送此消息給該窗口和滾動條的全部者

WM_INITMENU

0x0116

當一個菜單將要被激活時發送此消息,它發生在按下菜單項或按下菜單快捷鍵時,它容許程序在顯示前更改菜單

WM_INITMENUPOPUP

0x0117

當一個下拉菜單或子菜單將要被激活時發送此消息,它容許顯示前在修改菜單而沒必要更改整個菜單

WM_MENUSELECT

0x011F

選擇一條菜單項時發送此消息給菜單的全部者(通常是窗口)

WM_MENUCHAR

0x0120

當菜單已被激活且用戶按下了某個鍵(非快捷鍵),發送此消息給菜單的全部者

WM_ENTERIDLE

0x0121

當一個有模式對話框或菜單進入空閒狀態時發送此消息給它的全部者,空閒狀態指在處理完一條或幾條先前的消息後,消息列隊爲空

WM_MENURBUTTONUP

0x0122

當光標位於菜單項上時,釋放鼠標右鍵產生此消息

WM_MENUDRAG

0x0123

當拖動菜單項時,發送此消息給拖放菜單的全部者

WM_MENUGETOBJECT

0x0124

當光標移入菜單項或者從菜單項中心移到菜單項頂部或底部時,發送此消息給拖放菜單的全部者

WM_UNINITMENUPOPUP

0x0125

當下拉菜單或者子菜單被銷燬時產生此消息

WM_MENUCOMMAND

0x0126

當用戶選擇菜單項時產生此消息

WM_CHANGEUISTATE

0x0127

應用程序發送此消息代表用戶界面(UI)狀態應當被改變

WM_UPDATEUISTATE

0x0128

應用程序發送此消息改變指定窗口及其子窗口的用戶界面(UI)狀態

WM_QUERYUISTATE

0x0129

應用程序發送此消息獲得某個窗口的用戶界面(UI)狀態

WM_CTLCOLORMSGBOX

0x0132

繪製消息框前發送此消息給它的父窗口,經過響應這條消息,父窗口能夠經過使用給定的相關顯示設備的句柄來設置消息框的文本和背景顏色

WM_CTLCOLOREDIT

0x0133

繪製編輯型控件前發送此消息給它的父窗口,可用來設置編輯框的文本和背景顏色

WM_CTLCOLORLISTBOX

0x0134

繪製列表框控件前發送此消息給它的父窗口,可用來設置編輯框的文本和背景顏色

WM_CTLCOLORBTN

0x0135

繪製按鈕控件前發送此消息給它的父窗口,可用來設置編輯框的文本和背景顏色

WM_CTLCOLORDLG

0x0136

繪製對話框前發送此消息給它的父窗口,可用來設置編輯框的文本和背景顏色

WM_CTLCOLORSCROLLBAR

0x0137

繪製滾動條控件前發送此消息給它的父窗口,可用來設置滾動條控件的文本和背景顏色

WM_CTLCOLORSTATIC

0x0138

繪製靜態控件前發送此消息給它的父窗口,可用來設置靜態控件的文本和背景顏色

WM_MOUSEMOVE

0x0200

鼠標移動

WM_LBUTTONDOWN

0x0201

按下鼠標左鍵

WM_LBUTTONUP

0x0202

釋放鼠標左鍵

WM_LBUTTONDBLCLK

0x0203

雙擊鼠標左鍵

WM_RBUTTONDOWN

0x0204

按下鼠標右鍵

WM_RBUTTONUP

0x0205

釋放鼠標右鍵

WM_RBUTTONDBLCLK

0x0206

雙擊鼠標右鍵

WM_MBUTTONDOWN

0x0207

按下鼠標中鍵

WM_MBUTTONUP

0x0208

釋放鼠標中鍵

WM_MBUTTONDBLCLK

0x0209

雙擊鼠標中鍵

WM_MOUSEWHEEL

0x020A

當鼠標滾輪轉動時發送此消息給當前得到焦點的窗口

WM_PARENTNOTIFY

0x0210

當MDI子窗口被建立或被銷燬,或當光標位於子窗口上且用戶按了一下鼠標鍵時,發送此消息給它的父窗口

WM_ENTERMENULOOP

0x0211

發送此消息通知應用程序的主窗口進程已經進入了菜單模式循環

WM_EXITMENULOOP

0x0212

發送此消息通知應用程序的主窗口進程已經退出了菜單模式循環

WM_SIZING

0x0214

調整窗口大小時發送此消息給窗口,經過此消息應用程序能夠監視或修改窗口大小和位置

WM_CAPTURECHANGED

0x0215

當窗口設定爲不捕獲鼠標事件時,發送此消息給該窗口

WM_MOVING

0x0216

移動窗口時發送此消息給窗口,經過此消息應用程序能夠監視或修改窗口大小和位置

WM_POWERBROADCAST

0x0218

發送此消息給應用程序通知它有關電源管理事件

WM_DEVICECHANGE

0x0219

當設備的硬件配置改變時發送此消息給應用程序或設備驅動程序

WM_MDICREATE

0x0220

應用程序發送此消息給多文檔的客戶窗口來建立一個MDI 子窗口

WM_MDIDESTROY

0x0221

應用程序發送此消息給多文檔的客戶窗口來關閉一個MDI 子窗口

WM_MDIACTIVATE

0x0222

應用程序發送此消息給多文檔的客戶窗口通知客戶窗口激活另外一個MDI子窗口,當客戶窗口收到此消息後,它發出WM_MDIACTIVE消息給MDI子窗口(未激活)來激活它

WM_MDIRESTORE

0x0223

應用程序發送此消息給MDI客戶窗口通知子窗口恢復到原來大小

WM_MDINEXT

0x0224

應用程序發送此消息給MDI客戶窗口激活下一個或前一個窗口

WM_MDIMAXIMIZE

0x0225

應用程序發送此消息給MDI客戶窗口以最大化一個MDI子窗口

WM_MDITILE

0x0226

應用程序發送此消息給MDI客戶窗口以平鋪方式從新排列全部MDI子窗口

WM_MDICASCADE

0x0227

應用程序發送此消息給MDI客戶窗口以層疊方式從新排列全部MDI子窗口

WM_MDIICONARRANGE

0x0228

應用程序發送此消息給MDI客戶窗口從新排列全部最小化的MDI子窗口

WM_MDIGETACTIVE

0x0229

應用程序發送此消息給MDI客戶窗口以找到激活的子窗口的句柄

WM_MDISETMENU

0x0230

應用程序發送此消息給MDI客戶窗口用MDI菜單代替子窗口的菜單

WM_ENTERSIZEMOVE

0x0231

當窗口進入移動或改變大小模式循環時,發送此消息給該窗口

WM_EXITSIZEMOVE

0x0232

當窗口退出移動或改變大小模式循環時,發送此消息給該窗口

WM_DROPFILES

0x0233

當用戶在應用程序窗口中拖動某個文件時,產生此消息

WM_MDIREFRESHMENU

0x0234

應用程序發送此消息給MDI客戶窗口以刷新窗口菜單

WM_MOUSEHOVER

0x02A1

當光標在窗口客戶區懸停超過TrackMouseEvent()指定的時間時,發送此消息給該窗口

WM_MOUSELEAVE

0x02A3

當光標離開窗口客戶區超過TrackMouseEvent()指定的時間時,發送此消息給該窗口

WM_CUT

0x0300

應用程序發送此消息給一個編輯框或ComboBox以刪除當前選擇的文本

WM_COPY

0x0301

應用程序發送此消息給一個編輯框或ComboBox以複製當前選擇的文本到剪貼板

WM_PASTE 

0x0302

應用程序發送此消息給一個編輯框或ComboBox以從剪貼板中獲得數據

WM_CLEAR

0x0303

應用程序發送此消息給一個編輯框或ComboBox以清除當前選擇的內容

WM_UNDO

0x0304

應用程序發送此消息給一個編輯框或ComboBox以撤消最後一次操做

WM_DESTROYCLIPBOARD

0x0307

當調用EmptyClipboard()清空剪貼板時,發送此消息給剪貼板全部者

WM_DRAWCLIPBOARD

0x0308

當剪貼板的內容變化時發送此消息給剪貼板觀察鏈中的第一個窗口,它容許用剪貼板觀察窗口來顯示剪貼板的新內容

WM_PAINTCLIPBOARD

0x0309

當剪貼板包含CF_OWNERDIPLAY格式的數據且剪貼板觀察窗口的客戶區須要重繪時,發送此消息給剪貼板全部者

WM_VSCROLLCLIPBOARD

0x030A

當剪貼板包含CF_OWNERDIPLAY格式的數據且剪貼板觀察窗口發生垂直滾動條事件時,剪貼板觀察窗口發送此消息給剪貼板全部者

WM_SIZECLIPBOARD

0x030B

當剪貼板包含CF_OWNERDIPLAY格式的數據且剪貼板觀察窗口的客戶區域的大小已經改變時,剪貼板觀察窗口發送此消息給剪貼板的全部者

WM_ASKCBFORMATNAME

0x030C

剪貼板觀察窗口發送此消息給剪貼板全部者以得到CF_OWNERDISPLAY剪貼板格式的名字

WM_CHANGECBCHAIN

0x030D

當一個窗口從剪貼板觀察鏈中移去時發送此消息給剪貼板觀察鏈中的第一個窗口

WM_HSCROLLCLIPBOARD

0x030E

當剪貼板包含CF_OWNERDIPLAY格式的數據且剪貼板觀察窗口發生水平滾動條事件時,剪貼板觀察窗口發送此消息給剪貼板全部者

WM_QUERYNEWPALETTE

0x030F

發送此消息給將要得到鍵盤焦點的窗口,此消息使窗口在得到焦點時同時有機會實現它的邏輯調色板

WM_PALETTEISCHANGING

0x0310

應用程序將要實現它的邏輯調色板時發送此消息通知全部應用程序

WM_PALETTECHANGED

0x0311

得到焦點的窗口實現它的邏輯調色板後發送此消息給全部頂級並重疊的窗口,以此

來改變系統調色板

WM_HOTKEY

0x0312

當用戶按下由RegisterHotKey()註冊的熱鍵時產生此消息

WM_PRINT

0x0317

應用程序發送此消息給窗口,要求窗口在指定設備環境中繪製本身,通常狀況下是打印機設備環境

WM_PRINTCLIENT

0x0318

應用程序發送此消息給窗口,要求窗口在指定設備環境中繪製窗口客戶區,通常狀況下是打印機設備環境

WM_APP

0x8000

幫助用戶自定義消息,自定義消息能夠爲WM_APP+X,X爲正整數

WM_USER

0x0400

幫助用戶自定義消息,自定義消息能夠爲WM_USER+X,X爲正整數

  表A-3  通知消息-按鈕

消息名稱

說 明

BN_CLICKED

單擊按鈕

BN_DISABLE

按鈕被禁止

BN_DOUBLECLICKED

雙擊按鈕

BN_HILITE

加亮按鈕

BN_PAINT

按鈕應當重畫

BN_UNHILITE

加亮應當去掉

表A-4  通知消息-組合框

消息名稱

說 明

CBN_CLOSEUP

組合框的列表框被關閉

CBN_DBLCLK

用戶雙擊了一個字符串

CBN_DROPDOWN

組合框的列表框被拉下

CBN_EDITCHANGE

用戶修改了組合框中的文本

CBN_EDITUPDATE

組合框內的文本即將更新

CBN_ERRSPACE

組合框內存不足

CBN_KILLFOCUS

組合框失去輸入焦點

CBN_SELCHANGE

在組合框中選擇了一項

CBN_SELENDCANCEL

用戶的選擇將被忽略

CBN_SELENDOK

用戶的選擇將被執行

CBN_SETFOCUS

組合框得到輸入焦點

表A-5  通知消息-編輯框

消息名稱

說 明

EN_CHANGE

編輯框中的文本己更新

EN_ERRSPACE

編輯框內存不足

EN_HSCROLL

用戶點擊了水平滾動條

EN_KILLFOCUS

編輯框失去輸入焦點

EN_MAXTEXT

插入的內容被截斷

EN_SETFOCUS

編輯框得到輸入焦點

EN_UPDATE

編輯框中的文本將要更新

EN_VSCROLL

用戶點擊了垂直滾動條

表A-6  通知消息-列表框

消息名稱

說 明

LBN_DBLCLK

用戶雙擊了一項

LBN_ERRSPACE

列表框內存不足

LBN_KILLFOCUS

列表框正在失去輸入焦點

LBN_SELCANCEL

用戶選擇被取消

LBN_SELCHANGE

用戶選擇將改變

LBN_SETFOCUS

列表框得到輸入焦點

Windows消息大全

  Windows是一消息(Message)驅動式系統,Windows消息提供了應用程序與應用程序之間、應用程序與Windows系統之間進行通信的手段。應用程序要實現的功能由消息來觸發,並靠對消息的響應和處理來完成。Windows系統中有兩種消息隊列,一種是系統消息隊列,另外一種是應用程序消息隊列。計算機的全部輸入設備由 Windows監控,當一個事件發生時,Windows先將輸入的消息放入系統消息隊列中,而後再將輸入的消息拷貝到相應的應用程序隊列中,應用程序中的消息循環從它的消息隊列中檢索每個消息併發送給相應的窗口函數中。一個事件的發生,到達處理它的窗口函數必須經歷上述過程。值得注意的是消息的非搶先性,即不論事件的急與緩,老是按到達的前後排隊(一些系統消息除外),這就使得一些外部實時事件可能得不到及時的處理。

  因爲Windows自己是由消息驅動的,舉一個例子來講明這個問題。打開記事本程序,該程序有一個File菜單,那麼,在運行該應用程序的時候,若是用戶單擊了File菜單裏New命令時,這個動做將被Windows (而不是應用程序自己!)所捕獲,Windows通過分析得知這個動做應該由上面所說的那個應用程序去處理,既然是這樣,Windows就發送了個叫作WM_COMMAND的消息給應用程序,該消息所包含信息告訴應用程序:"用戶單擊了New菜單",應用程序得知這一消息以後,採起相應的動做來響應它,這個過程稱爲消息處理。Windows爲每個應用程序(確切地說是每個線程)維護了相應的消息隊列,應用程序的任務就是不停的從它的消息隊列中獲取消息,分析消息和處理消息,直到一條接到叫作WM_QUIT消息爲止,這個過程一般是由一種叫作消息循環的程序結構來實現的。

  消息自己是做爲一個記錄傳遞給應用程序的,這個記錄中包含了消息的類型以及其餘信息。例如,對於單擊鼠標所產生的消息來講,這個記錄中包含了單擊鼠標時的座標。這個記錄類型叫作T M s g,它在Wi n d o w s單元中是這樣聲明的:

type

TMsg = packedrecord

hwnd: HWND / /窗口句柄

message: UINT / /消息常量標識符

wParam: WPA R AM  // 32位消息的特定附加信息

lParam: LPA R AM  // 32位消息的特定附加信息

time: DWORD / /消息建立時的時間

pt: TPoint / /消息建立時的鼠標位置

end

 

消息中有什麼?

是否以爲一個消息記錄中的信息像希臘語同樣?若是是這樣,那麼看一看下面的解釋:

hwnd 32位的窗口句柄。窗口能夠是任何類型的屏幕對象,由於Win32可以維護大多數可視對象的句柄(窗口、對話框、按鈕、編輯框等)。

message 用於區別其餘消息的常量值,這些常量能夠是Windows單元中預約義的常量,也能夠是自定義的常量。

wParam 一般是一個與消息有關的常量值,也多是窗口或控件的句柄。

lParam 一般是一個指向內存中數據的指針。因爲WParm、lParam和Pointer都是32位的,所以,它們之間能夠相互轉換。

 

WM_NULL = 0

WM_CREATE = 1

應用程序建立一個窗口

WM_DESTROY = 2

一個窗口被銷燬

WM_MOVE = 3

移動一個窗口

WM_SIZE = 5

改變一個窗口的大小

WM_ACTIVATE = 6

一個窗口被激活或失去激活狀態;

WM_SETFOCUS = 7

得到焦點後

WM_KILLFOCUS = 8

失去焦點

WM_ENABLE = 10

改變enable狀態

WM_SETREDRAW = 11

設置窗口是否能重畫

WM_SETTEXT = 12

應用程序發送此消息來設置一個窗口的文本

WM_GETTEXT = 13

應用程序發送此消息來複制對應窗口的文本到緩衝區

WM_GETTEXTLENGTH =14

獲得與一個窗口有關的文本的長度(不包含空字符)

WM_PAINT = 15

要求一個窗口重畫本身

WM_CLOSE = 16

當一個窗口或應用程序要關閉時發送一個信號

WM_QUERYENDSESSION= 17

當用戶選擇結束對話框或程序本身調用ExitWindows函數

WM_QUIT = 18

用來結束程序運行或當程序調用postquitmessage函數

WM_QUERYOPEN = 19

當用戶窗口恢復之前的大小位置時,把此消息發送給某個圖標

WM_ERASEBKGND = 20

當窗口背景必須被擦除時(例在窗口改變大小時)

WM_SYSCOLORCHANGE =21

當系統顏色改變時,發送此消息給全部頂級窗口

WM_ENDSESSION = 22

當系統進程發出WM_QUERYENDSESSION消息後,此消息發送給應用程序,

通知它對話是否結束

WM_SYSTEMERROR = 23

WM_SHOWWINDOW = 24

當隱藏或顯示窗口是發送此消息給這個窗口

WM_ACTIVATEAPP = 28

發此消息給應用程序哪一個窗口是激活的,哪一個是非激活的;

WM_FONTCHANGE = 29

當系統的字體資源庫變化時發送此消息給全部頂級窗口

WM_TIMECHANGE = 30

當系統的時間變化時發送此消息給全部頂級窗口

WM_CANCELMODE = 31

發送此消息來取消某種正在進行的摸態(操做)

WM_SETCURSOR = 32

若是鼠標引發光標在某個窗口中移動且鼠標輸入沒有被捕獲時,就發消息給某個窗口

WM_MOUSEACTIVATE =33

當光標在某個非激活的窗口中而用戶正按着鼠標的某個鍵發送此消息給當前窗口

WM_CHILDACTIVATE =34

發送此消息給MDI子窗口當用戶點擊此窗口的標題欄,或當窗口被激活,移動,改變大小

WM_QUEUESYNC = 35

此消息由基於計算機的訓練程序發送,經過WH_JOURNALPALYBACK的hook程序

分離出用戶輸入消息

WM_GETMINMAXINFO =36

此消息發送給窗口當它將要改變大小或位置;

WM_PAINTICON = 38

發送給最小化窗口當它圖標將要被重畫

WM_ICONERASEBKGND =39

此消息發送給某個最小化窗口,僅當它在畫圖標前它的背景必須被重畫

WM_NEXTDLGCTL = 40

發送此消息給一個對話框程序去更改焦點位置

WM_SPOOLERSTATUS =42

每當打印管理列隊增長或減小一條做業時發出此消息

WM_DRAWITEM = 43

當button,combobox,listbox,menu的可視外觀改變時發送

此消息給這些空件的全部者

WM_MEASUREITEM = 44

當button, combo box, list box, list view control, or menu item 被建立時

發送此消息給控件的全部者

WM_DELETEITEM = 45

當the list box 或 combo box 被銷燬 或 當 某些項被刪除經過LB_DELETESTRING,LB_RESETCONTENT, CB_DELETESTRING, or CB_RESETCONTENT 消息

WM_VKEYTOITEM = 46

此消息有一個LBS_WANTKEYBOARDINPUT風格的發出給它的全部者來響應WM_KEYDOWN消息

WM_CHARTOITEM = 47

此消息由一個LBS_WANTKEYBOARDINPUT風格的列表框發送給他的全部者來響應WM_CHAR消息

WM_SETFONT = 48

當繪製文本時程序發送此消息獲得控件要用的顏色

WM_GETFONT = 49

應用程序發送此消息獲得當前控件繪製文本的字體

WM_SETHOTKEY = 50

應用程序發送此消息讓一個窗口與一個熱鍵相關連

WM_GETHOTKEY = 51

應用程序發送此消息來判斷熱鍵與某個窗口是否有關聯

WM_QUERYDRAGICON =55

此消息發送給最小化窗口,當此窗口將要被拖放而它的類中沒有定義圖標,應用程序能

返回一個圖標或光標的句柄,當用戶拖放圖標時系統顯示這個圖標或光標

WM_COMPAREITEM = 57

發送此消息來斷定combobox或listbox新增長的項的相對位置

WM_GETOBJECT = 61

WM_COMPACTING = 65

顯示內存已經不多了

WM_WINDOWPOSCHANGING= 70

發送此消息給那個窗口的大小和位置將要被改變時,來調用setwindowpos函數或其它窗口管理函數

WM_WINDOWPOSCHANGED= 71

發送此消息給那個窗口的大小和位置已經被改變時,來調用setwindowpos函數或其它窗口管理函數

WM_POWER = 72(適用於16位的windows)

當系統將要進入暫停狀態時發送此消息

WM_COPYDATA = 74

當一個應用程序傳遞數據給另外一個應用程序時發送此消息

WM_CANCELJOURNAL =75

當某個用戶取消程序日誌激活狀態,提交此消息給程序

WM_NOTIFY = 78

當某個控件的某個事件已經發生或這個控件須要獲得一些信息時,發送此消息給它的父窗口

WM_INPUTLANGCHANGEREQUEST= 80

當用戶選擇某種輸入語言,或輸入語言的熱鍵改變

WM_INPUTLANGCHANGE= 81

當平臺現場已經被改變後發送此消息給受影響的最頂級窗口

WM_TCARD = 82

當程序已經初始化windows幫助例程時發送此消息給應用程序

WM_HELP = 83

此消息顯示用戶按下了F1,若是某個菜單是激活的,就發送此消息個此窗口關聯的菜單,不然就

發送給有焦點的窗口,若是當前都沒有焦點,就把此消息發送給當前激活的窗口

WM_USERCHANGED = 84

當用戶已經登入或退出後發送此消息給全部的窗口,當用戶登入或退出時系統更新用戶的具體

設置信息,在用戶更新設置時系統立刻發送此消息;

WM_NOTIFYFORMAT =85

公用控件,自定義控件和他們的父窗口經過此消息來判斷控件是使用ANSI仍是UNICODE結構

在WM_NOTIFY消息,使用此控件能使某個控件與它的父控件之間進行相互通訊

WM_CONTEXTMENU =123

當用戶某個窗口中點擊了一下右鍵就發送此消息給這個窗口

WM_STYLECHANGING =124

當調用SETWINDOWLONG函數將要改變一個或多個 窗口的風格時發送此消息給那個窗口

WM_STYLECHANGED =125

當調用SETWINDOWLONG函數一個或多個 窗口的風格後發送此消息給那個窗口

WM_DISPLAYCHANGE =126

當顯示器的分辨率改變後發送此消息給全部的窗口

WM_GETICON = 127

此消息發送給某個窗口來返回與某個窗口有關連的大圖標或小圖標的句柄;

WM_SETICON = 128

程序發送此消息讓一個新的大圖標或小圖標與某個窗口關聯;

WM_NCCREATE = 129

當某個窗口第一次被建立時,此消息在WM_CREATE消息發送前發送;

WM_NCDESTROY = 130

此消息通知某個窗口,非客戶區正在銷燬

WM_NCCALCSIZE = 131

當某個窗口的客戶區域必須被覈算時發送此消息

WM_NCHITTEST =132//移動鼠標,按住或釋放鼠標時發生

WM_NCPAINT = 133

程序發送此消息給某個窗口當它(窗口)的框架必須被繪製時;

WM_NCACTIVATE = 134

此消息發送給某個窗口僅當它的非客戶區須要被改變來顯示是激活仍是非激活狀態;

WM_GETDLGCODE = 135

發送此消息給某個與對話框程序關聯的控件,widdows控制方位鍵和TAB鍵使輸入進入此控件

經過響應WM_GETDLGCODE消息,應用程序能夠把他當成一個特殊的輸入控件並能處理它

WM_NCMOUSEMOVE =160

當光標在一個窗口的非客戶區內移動時發送此消息給這個窗口 //非客戶區爲:窗體的標題欄及窗

的邊框體

WM_NCLBUTTONDOWN =161

當光標在一個窗口的非客戶區同時按下鼠標左鍵時提交此消息

WM_NCLBUTTONUP =162

當用戶釋放鼠標左鍵同時光標某個窗口在非客戶區十發送此消息;

WM_NCLBUTTONDBLCLK= 163

當用戶雙擊鼠標左鍵同時光標某個窗口在非客戶區十發送此消息

WM_NCRBUTTONDOWN =164

當用戶按下鼠標右鍵同時光標又在窗口的非客戶區時發送此消息

WM_NCRBUTTONUP =165

當用戶釋放鼠標右鍵同時光標又在窗口的非客戶區時發送此消息

WM_NCRBUTTONDBLCLK= 166

當用戶雙擊鼠標右鍵同時光標某個窗口在非客戶區十發送此消息

WM_NCMBUTTONDOWN =167

當用戶按下鼠標中鍵同時光標又在窗口的非客戶區時發送此消息

WM_NCMBUTTONUP =168

當用戶釋放鼠標中鍵同時光標又在窗口的非客戶區時發送此消息

WM_NCMBUTTONDBLCLK= 169

當用戶雙擊鼠標中鍵同時光標又在窗口的非客戶區時發送此消息

WM_KEYFIRST = 256

WM_KEYDOWN = 256

//按下一個鍵

WM_KEYUP = 257

//釋放一個鍵

WM_CHAR = 258

//按下某鍵,並已發出WM_KEYDOWN, WM_KEYUP消息

WM_DEADCHAR = 259

當用translatemessage函數翻譯WM_KEYUP消息時發送此消息給擁有焦點的窗口

WM_SYSKEYDOWN = 260

當用戶按住ALT鍵同時按下其它鍵時提交此消息給擁有焦點的窗口;

WM_SYSKEYUP = 261

當用戶釋放一個鍵同時ALT 鍵還按着時提交此消息給擁有焦點的窗口

WM_SYSCHAR = 262

當WM_SYSKEYDOWN消息被TRANSLATEMESSAGE函數翻譯後提交此消息給擁有焦點的窗口

WM_SYSDEADCHAR =263

當WM_SYSKEYDOWN消息被TRANSLATEMESSAGE函數翻譯後發送此消息給擁有焦點的窗口

WM_KEYLAST = 264

WM_INITDIALOG = 272

在一個對話框程序被顯示前發送此消息給它,一般用此消息初始化控件和執行其它任務

WM_COMMAND = 273

當用戶選擇一條菜單命令項或當某個控件發送一條消息給它的父窗口,一個快捷鍵被翻譯

WM_SYSCOMMAND = 274

當用戶選擇窗口菜單的一條命令或當用戶選擇最大化或最小化時那個窗口會收到此消息

WM_TIMER = 275 //發生了定時器事件

WM_HSCROLL = 276

當一個窗口標準水平滾動條產生一個滾動事件時發送此消息給那個窗口,也發送給擁有它的控件

WM_VSCROLL = 277

當一個窗口標準垂直滾動條產生一個滾動事件時發送此消息給那個窗口也,發送給擁有它的控件 WM_INITMENU = 278

當一個菜單將要被激活時發送此消息,它發生在用戶菜單條中的某項或按下某個菜單鍵,它容許

程序在顯示前更改菜單

WM_INITMENUPOPUP =279

當一個下拉菜單或子菜單將要被激活時發送此消息,它容許程序在它顯示前更改菜單,而不要

改變所有

WM_MENUSELECT = 287

當用戶選擇一條菜單項時發送此消息給菜單的全部者(通常是窗口)

WM_MENUCHAR = 288

當菜單已被激活用戶按下了某個鍵(不一樣於加速鍵),發送此消息給菜單的全部者;

WM_ENTERIDLE = 289

當一個模態對話框或菜單進入空載狀態時發送此消息給它的全部者,一個模態對話框或菜單進入空載狀態就是在處理完一條或幾條先前的消息後沒有消息它的列隊中等待

WM_MENURBUTTONUP =290

WM_MENUDRAG = 291

WM_MENUGETOBJECT =292

WM_UNINITMENUPOPUP= 293

WM_MENUCOMMAND =294

WM_CHANGEUISTATE =295

WM_UPDATEUISTATE =296

WM_QUERYUISTATE =297

WM_CTLCOLORMSGBOX =306

在windows繪製消息框前發送此消息給消息框的全部者窗口,經過響應這條消息,全部者窗口能夠

經過使用給定的相關顯示設備的句柄來設置消息框的文本和背景顏色

WM_CTLCOLOREDIT =307

當一個編輯型控件將要被繪製時發送此消息給它的父窗口;經過響應這條消息,全部者窗口能夠

經過使用給定的相關顯示設備的句柄來設置編輯框的文本和背景顏色

WM_CTLCOLORLISTBOX= 308

當一個列表框控件將要被繪製前發送此消息給它的父窗口;經過響應這條消息,全部者窗口能夠

經過使用給定的相關顯示設備的句柄來設置列表框的文本和背景顏色

WM_CTLCOLORBTN =309

當一個按鈕控件將要被繪製時發送此消息給它的父窗口;經過響應這條消息,全部者窗口能夠

經過使用給定的相關顯示設備的句柄來設置按紐的文本和背景顏色

WM_CTLCOLORDLG =310

當一個對話框控件將要被繪製前發送此消息給它的父窗口;經過響應這條消息,全部者窗口能夠

經過使用給定的相關顯示設備的句柄來設置對話框的文本背景顏色

WM_CTLCOLORSCROLLBAR=311

當一個滾動條控件將要被繪製時發送此消息給它的父窗口;經過響應這條消息,全部者窗口能夠

經過使用給定的相關顯示設備的句柄來設置滾動條的背景顏色

WM_CTLCOLORSTATIC =312

當一個靜態控件將要被繪製時發送此消息給它的父窗口;經過響應這條消息,全部者窗口能夠

經過使用給定的相關顯示設備的句柄來設置靜態控件的文本和背景顏色

WM_MOUSEFIRST = 512

WM_MOUSEMOVE = 512

// 移動鼠標

WM_LBUTTONDOWN =513

//按下鼠標左鍵

WM_LBUTTONUP = 514

//釋放鼠標左鍵

WM_LBUTTONDBLCLK =515

//雙擊鼠標左鍵

WM_RBUTTONDOWN =516

//按下鼠標右鍵

WM_RBUTTONUP = 517

//釋放鼠標右鍵

WM_RBUTTONDBLCLK =518

//雙擊鼠標右鍵

WM_MBUTTONDOWN =519

//按下鼠標中鍵

WM_MBUTTONUP = 520

//釋放鼠標中鍵

WM_MBUTTONDBLCLK =521

//雙擊鼠標中鍵

WM_MOUSEWHEEL = 522

當鼠標輪子轉動時發送此消息個當前有焦點的控件

WM_MOUSELAST = 522

WM_PARENTNOTIFY =528

當MDI子窗口被建立或被銷燬,或用戶按了一下鼠標鍵而光標在子窗口上時發送此消息給它的父窗口

WM_ENTERMENULOOP =529

發送此消息通知應用程序的主窗口that已經進入了菜單循環模式

WM_EXITMENULOOP =530

發送此消息通知應用程序的主窗口that已退出了菜單循環模式

WM_NEXTMENU = 531

WM_SIZING = 532

當用戶正在調整窗口大小時發送此消息給窗口;經過此消息應用程序能夠監視窗口大小和位置

也能夠修改他們

WM_CAPTURECHANGED =533

發送此消息給窗口當它失去捕獲的鼠標時;

WM_MOVING = 534

當用戶在移動窗口時發送此消息,經過此消息應用程序能夠監視窗口大小和位置

也能夠修改他們;

WM_POWERBROADCAST =536

此消息發送給應用程序來通知它有關電源管理事件;

WM_DEVICECHANGE =537

當設備的硬件配置改變時發送此消息給應用程序或設備驅動程序

WM_IME_STARTCOMPOSITION= 269

WM_IME_ENDCOMPOSITION= 270

WM_IME_COMPOSITION= 271

WM_IME_KEYLAST =271

WM_IME_SETCONTEXT =641

WM_IME_NOTIFY = 642

WM_IME_CONTROL =643

WM_IME_COMPOSITIONFULL= 644

WM_IME_SELECT = 645

WM_IME_CHAR = 646

WM_IME_REQUEST =648

WM_IME_KEYDOWN =656

WM_IME_KEYUP = 657

WM_MDICREATE = 544

應用程序發送此消息給多文檔的客戶窗口來建立一個MDI 子窗口

WM_MDIDESTROY = 545

應用程序發送此消息給多文檔的客戶窗口來關閉一個MDI 子窗口

WM_MDIACTIVATE =546

應用程序發送此消息給多文檔的客戶窗口通知客戶窗口激活另外一個MDI子窗口,當客戶窗口收到

此消息後,它發出WM_MDIACTIVE消息給MDI子窗口(未激活)激活它;

WM_MDIRESTORE = 547

程序發送此消息給MDI客戶窗口讓子窗口從最大最小化恢復到原來大小

WM_MDINEXT = 548

程序發送此消息給MDI客戶窗口激活下一個或前一個窗口

WM_MDIMAXIMIZE =549

程序發送此消息給MDI客戶窗口來最大化一個MDI子窗口;

WM_MDITILE = 550

程序發送此消息給MDI客戶窗口以平鋪方式從新排列全部MDI子窗口

WM_MDICASCADE = 551

程序發送此消息給MDI客戶窗口以層疊方式從新排列全部MDI子窗口

WM_MDIICONARRANGE =552

程序發送此消息給MDI客戶窗口從新排列全部最小化的MDI子窗口

WM_MDIGETACTIVE =553

程序發送此消息給MDI客戶窗口來找到激活的子窗口的句柄

WM_MDISETMENU = 560

程序發送此消息給MDI客戶窗口用MDI菜單代替子窗口的菜單

WM_ENTERSIZEMOVE =561

WM_EXITSIZEMOVE =562

WM_DROPFILES = 563

WM_MDIREFRESHMENU =564

WM_MOUSEHOVER = 673

WM_MOUSELEAVE = 675

WM_CUT = 768

程序發送此消息給一個編輯框或combobox來刪除當前選擇的文本

WM_COPY = 769

程序發送此消息給一個編輯框或combobox來複制當前選擇的文本到剪貼板

WM_PASTE = 770

程序發送此消息給editcontrol或combobox從剪貼板中獲得數據

WM_CLEAR = 771

程序發送此消息給editcontrol或combobox清除當前選擇的內容;

WM_UNDO = 772

程序發送此消息給editcontrol或combobox撤消最後一次操做

WM_RENDERFORMAT =773

WM_DESTROYCLIPBOARD= 775

當調用ENPTYCLIPBOARD函數時 發送此消息給剪貼板的全部者

WM_DRAWCLIPBOARD =776

當剪貼板的內容變化時發送此消息給剪貼板觀察鏈的第一個窗口;它容許用剪貼板觀察窗口來

顯示剪貼板的新內容;

WM_PAINTCLIPBOARD =777

當剪貼板包含CF_OWNERDIPLAY格式的數據而且剪貼板觀察窗口的客戶區須要重畫;

WM_VSCROLLCLIPBOARD= 778

WM_SIZECLIPBOARD =779

當剪貼板包含CF_OWNERDIPLAY格式的數據而且剪貼板觀察窗口的客戶區域的大小已經改變是此消息經過剪貼板觀察窗口發送給剪貼板的全部者;

WM_ASKCBFORMATNAME= 780

經過剪貼板觀察窗口發送此消息給剪貼板的全部者來請求一個CF_OWNERDISPLAY格式的剪貼板的名字

WM_CHANGECBCHAIN =781

當一個窗口從剪貼板觀察鏈中移去時發送此消息給剪貼板觀察鏈的第一個窗口;

WM_HSCROLLCLIPBOARD= 782

此消息經過一個剪貼板觀察窗口發送給剪貼板的全部者;它發生在當剪貼板包含CFOWNERDISPALY格式的數據而且有個事件在剪貼板觀察窗的水平滾動條上;全部者應滾動剪貼板圖象並更新滾動條的值;

WM_QUERYNEWPALETTE= 783

此消息發送給將要收到焦點的窗口,此消息能使窗口在收到焦點時同時有機會實現他的邏輯調色板

WM_PALETTEISCHANGING=784

當一個應用程序正要實現它的邏輯調色板時發此消息通知全部的應用程序

WM_PALETTECHANGED =785

此消息在一個擁有焦點的窗口實現它的邏輯調色板後發送此消息給全部頂級並重疊的窗口,以此

來改變系統調色板

WM_HOTKEY = 786

當用戶按下由REGISTERHOTKEY函數註冊的熱鍵時提交此消息

WM_PRINT = 791

應用程序發送此消息僅當WINDOWS或其它應用程序發出一個請求要求繪製一個應用程序的一部分;

WM_PRINTCLIENT =792

WM_HANDHELDFIRST =856

WM_HANDHELDLAST =863

WM_PENWINFIRST =896

WM_PENWINLAST = 911

WM_COALESCE_FIRST =912

WM_COALESCE_LAST =927

WM_DDE_FIRST = 992

WM_DDE_INITIATE =WM_DDE_FIRST + 0

一個DDE客戶程序提交此消息開始一個與服務器程序的會話來響應那個指定的程序和主題名;

WM_DDE_TERMINATE =WM_DDE_FIRST + 1

一個DDE應用程序(不管是客戶仍是服務器)提交此消息來終止一個會話;

WM_DDE_ADVISE =WM_DDE_FIRST + 2

一個DDE客戶程序提交此消息給一個DDE服務程序來請求服務器每當數據項改變時更新它

WM_DDE_UNADVISE =WM_DDE_FIRST + 3

一個DDE客戶程序經過此消息通知一個DDE服務程序不更新指定的項或一個特殊的剪貼板格式的項

WM_DDE_ACK = WM_DDE_FIRST+ 4

此消息通知一個DDE(動態數據交換)程序已收到並正在處理WM_DDE_POKE, WM_DDE_EXECUTE, WM_DDE_DATA, WM_DDE_ADVISE,WM_DDE_UNADVISE, or WM_DDE_INITIAT消息

WM_DDE_DATA =WM_DDE_FIRST + 5

一個DDE服務程序提交此消息給DDE客戶程序來傳遞個一數據項給客戶或通知客戶的一條可用數據項

WM_DDE_REQUEST =WM_DDE_FIRST + 6

一個DDE客戶程序提交此消息給一個DDE服務程序來請求一個數據項的值;

WM_DDE_POKE =WM_DDE_FIRST + 7

一個DDE客戶程序提交此消息給一個DDE服務程序,客戶使用此消息來請求服務器接收一個未經贊成的數據項;服務器經過答覆WM_DDE_ACK消息提示是否它接收這個數據項;

WM_DDE_EXECUTE =WM_DDE_FIRST + 8

一個DDE客戶程序提交此消息給一個DDE服務程序來發送一個字符串給服務器讓它象串行命令同樣被處理,服務器經過提交WM_DDE_ACK消息來做迴應;

WM_DDE_LAST =WM_DDE_FIRST + 8

WM_APP = 32768

WM_USER = 1024

此消息能幫助應用程序自定義私有消息;

/////////////////////////////////////////////////////////////////////

通知消息(Notification message)是指這樣一種消息,一個窗口內的子控件發生了一些事情,須要通

知父窗口。通知消息只適用於標準的窗口控件如按鈕、列表框、組合框、編輯框,以及Windows 95公

共控件如樹狀視圖、列表視圖等。例如,單擊或雙擊一個控件、在控件中選擇部分文本、操做控件的

滾動條都會產生通知消息。

按扭

B N _ C L I C K E D//用戶單擊了按鈕

B N _ D I S A B L E//按鈕被禁止

B N _ D O U B L E CL I C K E D //用戶雙擊了按鈕

B N _ H I L I T E//用戶加亮了按鈕

B N _ PA I N T按鈕應當重畫

B N _ U N H I L I TE加亮應當去掉

組合框

C B N _ C L O S E UP組合框的列表框被關閉

C B N _ D B L C L K用戶雙擊了一個字符串

C B N _ D R O P D OW N組合框的列表框被拉出

C B N _ E D I T C HA N G E用戶修改了編輯框中的文本

C B N _ E D I T U PD AT E編輯框內的文本即將更新

C B N _ E R R S PAC E組合框內存不足

C B N _ K I L L F OC U S組合框失去輸入焦點

C B N _ S E L C H AN G E在組合框中選擇了一項

C B N _ S E L E N DC A N C E L用戶的選擇應當被取消

C B N _ S E L E N DO K用戶的選擇是合法的

C B N _ S E T F O CU S組合框得到輸入焦點

編輯框

E N _ C H A N G E編輯框中的文本己更新

E N _ E R R S PA CE編輯框內存不足

E N _ H S C R O L L用戶點擊了水平滾動條

E N _ K I L L F O CU S編輯框正在失去輸入焦點

E N _ M A X T E X T插入的內容被截斷

E N _ S E T F O C US編輯框得到輸入焦點

E N _ U P D AT E編輯框中的文本將要更新

E N _ V S C R O L L用戶點擊了垂直滾動條消息含義

列表框

L B N _ D B L C L K用戶雙擊了一項

L B N _ E R R S PAC E列表框內存不夠

L B N _ K I L L F OC U S列表框正在失去輸入焦點

L B N _ S E L C A NC E L選擇被取消

L B N _ S E L C H AN G E選擇了另外一項

L B N _ S E T F O CU S列表框得到輸入焦點

 

轉載:

http://blog.csdn.net/zhangguofu2/article/details/19236081

http://www.cppblog.com/suiaiguo/archive/2009/07/18/90412.html

相關文章
相關標籤/搜索