Windows 標準 API 未直接提供遊戲搖桿類別,需呼叫 winmm.dll 中的 Multimedia API(joyGetPos、joySetCapture 等)。本文系統整理常數、結構體、API 函式,並給出 C++Builder 表單應用程式完整實作:裝置偵測、屬性讀取、事件驅動座標追蹤、按鈕狀態監聽、資源釋放。
| 分類 | 常數/結構 | 用途 |
|---|---|---|
| 訊息 | MM_JOY1MOVE (0x3A0) 等 | 搖桿移動、Z 軸、按鈕按下/釋放通知 |
| 按鈕遮罩 | JOY_BUTTON1 (0x0001)~JOY_BUTTON4CHG (0x0800) | 判斷按鈕狀態與變化 |
| 錯誤碼 | JOYERR_NOERROR (0)、JOYERR_UNPLUGGED (167) | API 呼叫結果判斷 |
| 裝置 ID | JOYSTICKID1 (0)、JOYSTICKID2 (1) | 指定第一/第二搖桿 |
| 能力結構 | JOYCAPS | 廠商 ID、軸範圍、按鈕數、輪詢週期 |
| 狀態結構 | JOYINFO | X/Y/Z 座標、按鈕位元組 |
joyGetNumDevs() → 確認系統支援遊戲埠。joyGetPos(ID, &info) → 偵測實際連接的搖桿(排除 JOYERR_UNPLUGGED)。joyGetDevCaps(ID, &caps, sizeof(caps)) → 取得軸範圍、按鈕數、最小輪詢週期。joySetCapture(Handle, ID, 2*caps.wPeriodMin, FALSE) → 註冊視窗接收 MM_JOY1MOVE 等訊息。OnCreate 初始化,OnDestroy 呼叫 joyReleaseCapture(ID) 釋放。class TForm1 : public TForm {
__published: // IDE 元件
private:
JOYCAPS JoyCaps; JOYINFO JoyInfo;
bool Connected; int JoystickID;
double XDivider, YDivider; // 座標映射比率
TPoint Position;
void __fastcall ShowDeviceInfo();
void __fastcall ShowStatusInfo();
public:
MESSAGE_HANDLER(MM_JOY1MOVE, TMessage, OnJoyMove)
MESSAGE_HANDLER(MM_JOY1BUTTONDOWN, TMessage, OnJoyButton)
MESSAGE_HANDLER(MM_JOY1BUTTONUP, TMessage, OnJoyButton)
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(MM_JOY1MOVE, TMessage, OnJoyMove)
VCL_MESSAGE_HANDLER(MM_JOY1BUTTONDOWN, TMessage, OnJoyButton)
VCL_MESSAGE_HANDLER(MM_JOY1BUTTONUP, TMessage, OnJoyButton)
END_MESSAGE_MAP(TForm)
};
void __fastcall TForm1::OnJoyMove(TMessage &Msg) {
Position.x = Msg.LParamLo; // X 軸
Position.y = Msg.LParamHi; // Y 軸
// 映射至螢幕座標
int screenX = (Position.x - JoyCaps.wXmin) / XDivider - Image1->Width/2;
int screenY = (Position.y - JoyCaps.wYmin) / YDivider - Image1->Height/2;
Image1->Left = screenX; Image1->Top = screenY;
LabelX->Caption = "X: " + IntToStr(Position.x);
LabelY->Caption = "Y: " + IntToStr(Position.y);
}
void __fastcall TForm1::OnJoyButton(TMessage &Msg) {
if (Msg.WParam & JOY_BUTTON1) LabelBtn1->Caption = "Pressed";
else LabelBtn1->Caption = "Released";
// 同理處理 BUTTON2~4
}
SetCursorPos,按鈕對應 mouse_event。「Multimedia API 雖屬舊世代,但零相依、無需 DirectX SDK,寫輕量小工具依然是最高 CP 值選擇。」