本篇教學示範在 Win32 視窗程序中處理滑鼠左鍵按下訊息(WM_LBUTTONDOWN),於點擊位置繪製字串。涵蓋訊息迴路、座標提取、無效區觸發重繪、WM_PAINT 繪圖流程等核心概念。
WM_LBUTTONDOWN/UP、WM_RBUTTONDOWN/UP、WM_MOUSEMOVE、WM_LBUTTONDBLCLK(需 CS_DBLCLKS 類別風格)lParam 低 16 位 = x 座標,高 16 位 = y 座標(相對用戶區左上角)wParam 指示修飾鍵狀態(Shift/Ctrl/滑鼠鍵).data
ClassName db "SimpleWinClass",0
AppName db "Our First Window",0
MouseClick db 0 ; 0=尚未點擊
.data?
hitpoint POINT <> ; 儲存點擊座標
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_LBUTTONDOWN
; 取出 x, y 座標
MOV EAX, lParam
AND EAX, 0FFFFh
MOV hitpoint.x, EAX
MOV EAX, lParam
SHR EAX, 16
MOV hitpoint.y, EAX
MOV MouseClick, TRUE
INVOKE InvalidateRect, hWnd, NULL, TRUE ; 觸發 WM_PAINT
.ELSEIF uMsg==WM_PAINT
INVOKE BeginPaint, hWnd, ADDR ps
MOV hdc, EAX
.IF MouseClick
INVOKE lstrlen, ADDR AppName
INVOKE TextOut, hdc, hitpoint.x, hitpoint.y, ADDR AppName, EAX
.ENDIF
INVOKE EndPaint, hWnd, ADDR ps
.ENDIF
...
WndProc endp
lParam 為 32 位有號整數,AND 0FFFFh 取低字(x),SHR 16 取高字(y)。MouseClick 區分「首次顯示(無點擊)」與「有點擊需繪製」。InvalidateRect(hWnd, NULL, TRUE) 將整個用戶區標記為無效,並要求清除背景,Windows 隨後發送 WM_PAINT。BeginPaint/EndPaint 之間呼叫 TextOut,才能確保視窗縮放、遮蔽還原時字串持續可見。WM_LBUTTONDOWN 直接呼叫 GetDC/TextOut/ReleaseDC → 視窗重繪時字串消失WM_PAINT 內完成,透過狀態變數傳遞參數InvalidateRect / UpdateWindow 主動觸發重繪,而非手動繪圖WM_MOUSEMOVE 即時顯示游標位置SetCapture/ReleaseCapture 實現拖曳繪圖