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

Win32 組合語言教學:鍵盤字元訊息處理(WM_CHAR)

     編輯:組合語言

教學目標

示範在 Win32 視窗程序中處理 WM_CHAR 訊息,接收鍵盤輸入字元並即時顯示於用戶區左上角。涵蓋訊息類型區別、TranslateMessage 角色、InvalidateRect 觸發重繪、繪圖集中於 WM_PAINT 的最佳實踐。

鍵盤訊息三層架構

訊息觸發時機wParam 內容典型用途
WM_KEYDOWN按鍵按下虛擬鍵碼 (VK_*)遊戲控制、快捷鍵、非字元按鍵
WM_KEYUP按鍵釋放虛擬鍵碼按鍵釋放偵測
WM_CHARTranslateMessage 轉換字元碼 (ANSI/Unicode)文字輸入、編輯框

關鍵點:GetMessage → TranslateMessage → DispatchMessage 迴路中,TranslateMessage 將 WM_KEYDOWN 轉為 WM_CHAR(含鍵盤佈局、Shift 狀態、死鍵處理)。若不呼叫 TranslateMessage,將不會產生 WM_CHAR。

範例程式關鍵片段

資料區

.data
  Char WPARAM 20h          ; 初始為空格 (無輸入時不顯示)
.code

視窗程序

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
  .IF uMsg==WM_CHAR
    PUSH wParam
    POP  Char              ; 儲存接收到的字元
    INVOKE InvalidateRect, hWnd, NULL, TRUE  ; 整個用戶區無效化 + 擦除背景
  .ELSEIF uMsg==WM_PAINT
    INVOKE BeginPaint, hWnd, ADDR ps
    MOV hdc, EAX
    INVOKE TextOut, hdc, 0, 0, ADDR Char, 1  ; 繪製單一字元
    INVOKE EndPaint, hWnd, ADDR ps
  .ENDIF
  ...
WndProc endp

流程解析

  1. 使用者按下 'A' → 驅動程式產生掃描碼 → Windows 發送 WM_KEYDOWN (wParam=41h)
  2. 訊息迴路 TranslateMessage 依當前鍵盤佈局轉為 WM_CHAR (wParam='A'=41h)
  3. DispatchMessage 傳遞給 WndProc
  4. WM_CHAR 分支:將字元存入 Char,呼叫 InvalidateRect(hWnd, NULL, TRUE)
  5. Windows 標記用戶區無效,發送 WM_PAINT
  6. WM_PAINT 分支:BeginPaint → TextOut(0,0,Char,1) → EndPaint

為什麼要用 InvalidateRect + WM_PAINT?

  • ❌ 直接在 WM_CHAR 呼叫 GetDC/TextOut/ReleaseDC:視窗最小化還原、被遮蔽後顯示時,字元會消失,因為 Windows 不會自動重繪非 WM_PAINT 產生的內容。
  • ✅ 所有持久化視覺內容必須在 WM_PAINT 內繪製,狀態資料儲存在全域/靜態變數,InvalidateRect 通知 Windows 「需重繪」。
  • InvalidateRect(hWnd, NULL, TRUE):NULL=整個用戶區,TRUE=擦除背景(呼叫 BeginPaint 時自動填充類別背景筆刷)。

擴展練習

  • 累積字元字串(陣列 + 長度計數),實現簡易編輯區
  • 處理 WM_KEYDOWN 攔截 Backspace (VK_BACK) 刪除字元
  • 使用 GetTextExtentPoint32 計算文字寬度,實現自動換行
  • 對比 WM_CHAR (ANSI) 與 WM_UNICHAR (Unicode) 在 Unicode 版本程式中的差異
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved