本實驗採用「最佳」層次的觸控開發方式——直接處理低階 WM_TOUCH 訊息,建立多點觸控繪圖應用(模擬 MS Paint 多指繪圖),學習:
視窗支援多指同時繪製連續線條,每根手指對應一條獨立筆劃,主觸點(第一指)以黑色顯示,次要觸點循環使用紅、綠、藍、青、洋紅、黃六色。
同前一實驗,建立 C++ Win32 專案,修改 targetver.h 設定 0x0601。
程式碼與手勢實驗相同,使用 GetSystemMetrics(SM_DIGITIZER) 與 SM_MAXIMUMTOUCHES。
加入 Stroke.h/.cpp 管理筆劃集合:
g_StrkColFinished:已完成筆劃集合g_StrkColDrawing:正在繪製中筆劃集合在 WM_PAINT 中繪製兩個集合所有筆劃。
在 InitInstance 的 ShowWindow 前呼叫:
if (!RegisterTouchWindow(hWnd, 0)) {
MessageBox(hWnd, L"Cannot register for touch input", L"Error", MB_OK);
return FALSE;
}
預設視窗接收 WM_GESTURE,此呼叫切換為低階 WM_TOUCH。
WM_TOUCH 的 wParam 為觸點數量,lParam 為觸控輸入控制代碼。處理流程:
case WM_TOUCH: {
UINT numInputs = (UINT)wParam;
TOUCHINPUT* ti = new TOUCHINPUT[numInputs];
if (GetTouchInputInfo((HTOUCHINPUT)lParam, numInputs, ti, sizeof(TOUCHINPUT))) {
for (UINT i = 0; i < numInputs; ++i) {
if (ti[i].dwFlags & TOUCHEVENTF_DOWN) OnTouchDownHandler(hWnd, ti[i]);
else if (ti[i].dwFlags & TOUCHEVENTF_MOVE) OnTouchMoveHandler(hWnd, ti[i]);
else if (ti[i].dwFlags & TOUCHEVENTF_UP) OnTouchUpHandler(hWnd, ti[i]);
}
}
CloseTouchInputHandle((HTOUCHINPUT)lParam);
delete[] ti;
break;
}
x, y:螢幕座標(單位:百分之一像素),需除以 100 並用 ScreenToClient 轉換dwID:觸點唯一識別碼(手指按下時產生,抬起時釋放,可重複使用)dwFlags:TOUCHEVENTF_DOWN、MOVE、UPOnTouchDownHandler:建立新筆劃、記錄起始點、指派顏色與觸點 ID,加入 g_StrkColDrawing。
OnTouchMoveHandler:依觸點 ID 在 g_StrkColDrawing 找到對應筆劃,加入新點,局部重繪最新線段。
OnTouchUpHandler:依觸點 ID 找到筆劃,移至 g_StrkColFinished,從繪製中集合移除,觸發全視窗重繪。
輔助函式 GetTouchPoint 處理座標轉換,GetTouchColor 根據是否為主觸點決定顏色。
本實驗深入展示 WM_TOUCH 低階觸控程式設計核心:視窗註冊、訊息解封裝、觸點 ID 追蹤與筆劃生命週期管理。此技術適用於繪圖板、樂器模擬、多使用者協作等需精確控制每個觸點的高階應用場景。