首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

深度解析 VC 訊息機制(上):訊息結構、分類與核心識別碼完整對照

     編輯:關於VC++

什麼是訊息?

訊息系統是 Win32 程式運行的動力源泉。一個訊息是系統定義的 32 位元值,唯一定義一個事件,通知應用程式某事發生:滑鼠點擊、視窗大小變更、鍵盤按鍵等。訊息以記錄形式傳遞,包含類型與額外資訊 (如滑鼠座標)。記錄類型為 MSG:

typedef struct tagMSG
{
    HWND hwnd;        // 接收視窗控制代碼
    UINT message;     // 訊息常數識別碼 (訊息號)
    WPARAM wParam;    // 32 位元附加資訊,具體含義依賴訊息值
    LPARAM lParam;    // 32 位元附加資訊,具體含義依賴訊息值
    DWORD time;       // 訊息建立時間
    POINT pt;         // 訊息建立時滑鼠/游標螢幕座標
} MSG;

訊息來源

  • 系統產生:輸入事件 (按鍵、滑鼠、點擊控制項)、應用程式帶來的系統變化 (字體變更、視窗大小調整)
  • 應用程式產生:讓視窗執行任務、與其他應用程式視窗通訊

訊息結構欄位深度解析

欄位類型詳細說明
hwndHWND32 位視窗控制代碼。Win32 維護多數可視物件控制代碼 (視窗、對話方塊、按鈕、編輯框等)
messageUINT區別其他訊息的常數值。預定義常數或自訂常數。視窗程序用此決定如何處理。如 WM_PAINT 告知客戶區需重繪。前綴指明處理視窗類型
wParamWPARAM通常為相關常數值,也可能是視窗/控制項控制代碼
lParamLPARAM通常為指向記憶體資料的指標。WPARAM/LPARAM/Pointer 皆 32 位,可互轉
timeDWORD訊息建立時間 (毫秒,系統啟動後)
ptPOINT滑鼠/游標螢幕座標

訊息識別碼數值範圍與分類

範圍用途說明
0x0000 - 0x03FF (WM_USER-1)系統保留系統定義訊息,應用程式不可使用
0x0400 (WM_USER) - 0x7FFF應用程式私有應用程式內部使用,視窗類別私有
0x8000 (WM_APP) - 0xBFFF應用程式全域跨視窗類別的應用程式訊息
0xC000 - 0xFFFF跨應用程式通訊RegisterWindowMessage 產生,系統保證唯一

關鍵訊息值對照表

訊息值說明
WM_NULL0x0000空訊息
0x0001 - 0x0087-主要視窗訊息
0x00A0 - 0x00A9-非客戶區訊息
0x0100 - 0x0108-鍵盤訊息
0x0111 - 0x0126-功能表訊息
0x0132 - 0x0138-色彩控制訊息
0x0200 - 0x020A-滑鼠訊息
0x0211 - 0x0213-功能表迴路訊息
0x0220 - 0x0230-多文件訊息 (MDI)
0x03E0 - 0x03E8-DDE 訊息
WM_USER0x0400應用程式私有訊息起始
WM_APP0x8000應用程式全域訊息起始

訊息三大分類

類別定義處理者範圍典型例子
視窗訊息作業系統與控制其他視窗的視窗使用視窗類別 (CWnd 衍生)CreateWindow、DestroyWindow、MoveWindow、滑鼠點擊
命令訊息特殊視窗訊息,處理視窗間使用者請求視窗類別、文件類別、文件樣板類別、應用程式類別按下按鈕 → 發送命令訊息給主視窗
控制項通知訊息子控制項發生事件需通知父視窗視窗類別 (CWnd 衍生)點擊/雙擊控制項、選取文字、操作捲軸

命令訊息處理者範圍最廣,不限於視窗類別。控制項通知訊息類似命令訊息 (從控制項發送至父視窗),但目的在讓父視窗改變控制項 (載入/顯示資料),而非處理使用者命令。按鈕點擊既可視為命令訊息也可視為通知訊息;滑鼠點擊可由主視窗直接處理或交給控制項。

常見控制項通知訊息完整對照

按鈕控制項 (Button)

通知代碼觸發條件
BN_CLICKED使用者單擊按鈕
BN_DISABLE按鈕被停用
BN_DOUBLECLICKED使用者雙擊按鈕
BN_HILITE使用者高亮按鈕
BN_PAINT按鈕應重繪
BN_UNHILITE高亮應移除

下拉式方塊 (ComboBox)

通知代碼觸發條件
CBN_CLOSEUP清單方塊關閉
CBN_DBLCLK雙擊字串
CBN_DROPDOWN清單方塊展開
CBN_EDITCHANGE編輯框文字變更
CBN_EDITUPDATE編輯框文字即將更新
CBN_ERRSPACE記憶體不足
CBN_KILLFOCUS失去輸入焦點
CBN_SELCHANGE選取項目變更
CBN_SELENDCANCEL選取應取消
CBN_SELENDOK選取合法
CBN_SETFOCUS獲得輸入焦點

編輯框 (Edit)

通知代碼觸發條件
EN_CHANGE文字已更新
EN_ERRSPACE記憶體不足
EN_HSCROLL點擊水平捲軸
EN_KILLFOCUS正在失去焦點
EN_MAXTEXT插入內容被截斷
EN_SETFOCUS獲得輸入焦點
EN_UPDATE文字即將更新
EN_VSCROLL點擊垂直捲軸

清單方塊 (ListBox)

通知代碼觸發條件
LBN_DBLCLK雙擊項目
LBN_ERRSPACE記憶體不足
LBN_KILLFOCUS正在失去焦點
LBN_SELCANCEL選取被取消
LBN_SELCHANGE選取其他項目
LBN_SETFOCUS獲得輸入焦點

自訂訊息最佳實務

  1. 視窗類別私有:#define WM_MYMSG (WM_USER + 1)
  2. 應用程式全域:#define WM_MYAPPMSG (WM_APP + 1)
  3. 跨程式通訊:UINT WM_MYGLOBAL = RegisterWindowMessage(TEXT("MyUniqueMessageName"));
  4. 避免衝突:WM_USER 範圍僅在同一視窗類別內有效,不同類別可重用相同值

下一章預告

下回將深入探討:佇列/非佇列訊息機制、SendMessage/PostMessage 發送與佇列差異、GetMessage/PeekMessage 接收處理、標準訊息泵運作細節、視窗程序架構與 WindowsX.h 訊息分發器技術。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved