Windows 提供 joySetCapture/joyReleaseCapture 將搖桿訊息(MM_JOY1MOVE、MM_JOY1BUTTONDOWN 等)直接路由到指定視窗,無需輪詢,延遲極低。
joySetCapture(Handle, JOYSTICKID1, 0, FALSE),uPeriod=0 表示事件驅動模式。MM_JOY1MOVE,需在表單頭文件手動建立訊息映射:// Unit1.h
class TForm1 : public TForm {
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(MM_JOY1MOVE, TMessage, OnJoyMove)
MESSAGE_HANDLER(MM_JOY1BUTTONDOWN, TMessage, OnJoyDown)
END_MESSAGE_MAP(TForm)
private:
void __fastcall OnJoyMove(TMessage &Msg);
void __fastcall OnJoyDown(TMessage &Msg);
};
FormCloseQuery 中呼叫 joyReleaseCapture(JOYSTICKID1)。void __fastcall TForm1::OnJoyMove(TMessage &Msg) {
// Msg.LParam 低位 = X 軸, 高位 = Y 軸 (0~65535)
int x = LOWORD(Msg.LParam);
int y = HIWORD(Msg.LParam);
// 以 32768 為中心,計算偏移
const int CENTER = 32768;
const int DEAD_ZONE = 2000; // 死區
int dx = (abs(x - CENTER) > DEAD_ZONE) ? (x - CENTER) / 500 : 0;
int dy = (abs(y - CENTER) > DEAD_ZONE) ? (y - CENTER) / 500 : 0;
if (dx || dy) {
POINT pt; GetCursorPos(&pt);
SetCursorPos(pt.x + dx, pt.y + dy);
}
}
void __fastcall TForm1::OnJoyDown(TMessage &Msg) {
// Msg.WParam 低位按鈕掩碼: bit0=Btn1, bit1=Btn2...
WORD btn = LOWORD(Msg.WParam);
if (btn & JOY_BUTTON1) mouse_event(MOUSEEVENTF_LEFTDOWN, 0,0,0,0);
if (btn & JOY_BUTTON2) mouse_event(MOUSEEVENTF_RIGHTDOWN, 0,0,0,0);
// 彈起需處理 MM_JOY1BUTTONUP (同理)
}
dx/dy 縮放係數。MM_JOY1BUTTONUP 配對。JOYSTICKID1/2 對應兩個端口,可擴展為陣列管理多設備。組合搖桿按鈕組合(如 L1+方向鍵),可映射為鍵盤熱鍵(keybd_event)、滾輪(mouse_event(MOUSEEVENTF_WHEEL))、甚至啟動應用程式(ShellExecute),打造個性化「手柄啟動器」。
僅需 joySetCapture + 兩條自定義訊息 + SetCursorPos/mouse_event,即可在 C++ Builder 中用 50 行代碼實現功能完整的「搖桿鼠標」,適合無障礙輔助、HTPC 遙控、工業現場無鍵盤操作等場景。