上一篇講解了鍵盤事件處理,本文將聚焦 Windows 控制台程序中的鼠標事件捕獲與處理。掌握鼠標事件,能實現按鈕點擊、拖拽、選區、右鍵菜單等豐富交互,是控制台 GUI 開發的核心技能。
MOUSE_EVENT_RECORD當控制台輸入模式啟用 ENABLE_MOUSE_INPUT 後,ReadConsoleInput 讀取到的 INPUT_RECORD 中 EventType == MOUSE_EVENT 時,其 Event.MouseEvent 字段即為此結構:
typedef struct _MOUSE_EVENT_RECORD {
COORD dwMousePosition; // 鼠標在控制台緩衝區座標 (列, 行)
DWORD dwButtonState; // 按鍵狀態位掩碼
DWORD dwControlKeyState; // 控制鍵狀態 (Shift/Ctrl/Alt 等)
DWORD dwEventFlags; // 事件類型
} MOUSE_EVENT_RECORD;
dwButtonState:哪個鍵被按下/釋放位掩碼,可組合 (如同時按左+右鍵):
FROM_LEFT_1ST_BUTTON_PRESSED (0x01) —— 左鍵FROM_LEFT_2ND_BUTTON_PRESSED (0x04) —— 中鍵/滾輪鍵FROM_LEFT_3RD_BUTTON_PRESSED (0x08) —— 第四鍵FROM_LEFT_4TH_BUTTON_PRESSED (0x10) —— 第五鍵RIGHTMOST_BUTTON_PRESSED (0x02) —— 右鍵判斷技巧:(state & FROM_LEFT_1ST_BUTTON_PRESSED) 非零即左鍵按下。
dwControlKeyState:組合鍵狀態與鍵盤事件一致,常用標志:
SHIFT_PRESSED (0x10)、LEFT_CTRL_PRESSED (0x08)、LEFT_ALT_PRESSED (0x02)CAPSLOCK_ON、NUMLOCK_ON、SCROLLLOCK_ONENHANCED_KEY (擴展鍵,如右 Ctrl/右 Alt/方向鍵)dwEventFlags:發生了什麼動作0 —— 按鍵按下或釋放 (需配合 dwButtonState 判斷具體鍵)DOUBLE_CLICK (0x02) —— 雙擊 (第二下觸發,第一下仍為 0)MOUSE_MOVED (0x01) —— 鼠標移動 (高頻觸發,需節流)MOUSE_WHEELED (0x04) —— 垂直滾輪滾動 (dwButtonState 高字節含滾動量)MOUSE_HWHEELED (0x08) —— 水平滾輪滾動void HandleMouseEvent(MOUSE_EVENT_RECORD *mer) {
// 1. 獲取座標
int col = mer->dwMousePosition.X;
int row = mer->dwMousePosition.Y;
// 2. 判斷事件類型
switch (mer->dwEventFlags) {
case 0: { // 按鍵變化
DWORD btn = mer->dwButtonState;
if (btn & FROM_LEFT_1ST_BUTTON_PRESSED) OnLeftClick(col, row, mer->dwControlKeyState);
else if (btn & RIGHTMOST_BUTTON_PRESSED) OnRightClick(col, row, mer->dwControlKeyState);
// 注意:釋放時對應位變 0,可記錄前幀狀態檢測釋放
break;
}
case DOUBLE_CLICK:
OnDoubleClick(col, row);
break;
case MOUSE_MOVED:
OnMouseMove(col, row); // 建議節流 (如 50ms 一次)
break;
case MOUSE_WHEELED: {
short delta = (short)(mer->dwButtonState >> 16); // 高 16 位為滾動量
OnWheelScroll(col, row, delta);
break;
}
}
}
SetConsoleMode(hStdin, ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS | ENABLE_WINDOW_INPUT)。COORD 以字符單元格為單位,原點 (0,0) 在左上角,X 向右,Y 向下。MOUSE_MOVED 極其頻繁,UI 更新必須節流/去抖,避免阻塞主循環。dwButtonState,通過異或/與運算檢測「按下瞬間」與「釋放瞬間」。dwButtonState 高 16 位為有符號短整數,正值向上/向左,負值向下/向右,單位通常為 120 (WHEEL_DELTA)。鼠標事件處理的核心在於:正確解析位掩碼狀態、區分事件類型、座標映射到 UI 邏輯、高頻事件節流。結合鍵盤事件,即可構建完整的控制台交互系統。下一篇將講解窗口繪製與雙緩衝渲染技術。