背景
隨著技術的不斷發展,現在手上人人配備的手機似乎正在凝聚著人間所有高新科技的一切美好的成果,可想而知,隨著手機的不斷進步,外部擴展,包括存儲卡、電池、耳機線都將被其帶動,那就是遊戲操縱桿。
使用
在C++Builder中如何使用遊戲操縱桿 在Windows環境下通過編程來操縱滑鼠、鍵盤是一件再簡單不過的事了,不過大家有沒有想過要嘗試一下另一樣我們比較常見的輸入工具——遊戲操縱桿呢?在某些情況下,尤其是象編制一些小型的遊戲軟體的時候,加入對遊戲操縱桿的支持可以給使用者提供更為友好的人機界面,極大的提高遊戲軟體的可玩性。
C++Builder中沒有專門控制操縱桿函式(其實在常見的程式語言中基本上都沒有),因此要增加對遊戲操縱桿的支持,就要和Windows的MCI API函式打交道,在讀取操縱桿的屬性、狀態,位置和按鈕信息時要用到的API函式、常量及數據結構。
相關常量
#define MM_JOY1MOVE 0x3A0 /* 用以傳遞操縱桿當前狀態的一些訊息 */
#define MM_JOY2MOVE 0x3A1
#define MM_JOY1ZMOVE 0x3A2
#define MM_JOY2ZMOVE 0x3A3
#define MM_JOY1BUTTONDOWN 0x3B5
#define MM_JOY2BUTTONDOWN 0x3B6
#define MM_JOY1BUTTONUP 0x3B7
#defineMM_JOY2BUTTONUP 0x3B8
#define JOY_BUTTON1 0x0001 /* 用以表明當前操縱桿的狀態 */
#define JOY_BUTTON2 0x0002
#define JOY_BUTTON3 0x0004
#define JOY_BUTTON4 0x0008
#define JOY_BUTTON1CHG 0x0100
#define JOY_BUTTON2CHG 0x0200
#define JOY_BUTTON3CHG 0x0400
#define JOY_BUTTON4CHG 0x0800
/* 遊戲操縱桿錯誤返回值 */
#define JOYERR_BASE 160
#define JOYERR_NOERROR (0) /* 正常 */
#define JOYERR_ParmS (JOYERR_BASE+5) /* 參數錯誤 */
#define JOYERR_NOCANDO (JOYERR_BASE+6) /* 無法正常工作 */
#define JOYERR_UNPLUGGED (JOYERR_BASE+7) /* 操縱桿未連線 */
/* 操縱桿標識號 */
#define JOYSTICKID1 0
#define JOYSTICKID2 1
相關函式
WINMMAPI UINT WINAPI joyGetNumDevs(void);
獲取設備標識號。
MMRESULT WINAPI joyGetDevCaps(UINT uJoyID, LPJOYCAPS pjc, UINT cbjc);
獲取操縱桿屬性信息,以結構體JoyCaps接收。
WINMMAPI MMRESULT WINAPI joyGetPos(UINT uJoyID, LPJOYINFO pji);
獲取操縱桿位置和按鈕狀態,以結構體接收。
WINMMAPI MMRESULT WINAPI joyGetThreshold(UINT uJoyID, LPUINT puThreshold);
讀取操縱桿移動閾值。
WINMMAPI MMRESULT WINAPI joyReleaseCapture(UINT uJoyID);
結束對操縱桿信息的接收。
WINMMAPI MMRESULT WINAPI joySetCapture(HWND hwnd, UINT uJoyID, UINT uPeriod,
BOOL fChanged);
設定接收某一操縱桿的信息的視窗以及將何種頻度接收。
WINMMAPI MMRESULT WINAPI joySetThreshold(UINT uJoyID, UINT uThreshold);
設定操縱桿移動閾值。
相關結構體: typedef struct joyCaps{
WORD wMid; /* 製造商標識 */
WORD wPid; /* 生產編號 */
char szPname[MAXPNAMELEN]; /* 產品名稱 */
UINT wXmin; /* X軸最小值 */
UINT wXmax; /* X軸最大值 */
UINT wYmin; /* Y軸最小值 */
UINT wYmax; /* Y軸最大值 */
UINT wZmin; /* Z軸最小值 */
UINT wZmax; /* Z軸最大值 */
UINT wNumButtons; /* 按鈕數 */
UINT wPeriodMin; /* 最小調用間隔時間(單位 毫秒)*/
UINT wPeriodMax; /* 最大調用間隔時間(單位 毫秒)*/
}JOYCAPS, *PJOYCAPS, NEAR *NPJOYCAPS, FAR *LPJOYCAPS;
typedef struct joyInfo{
UINT wXpos; /* x 軸位置 */
UINT wYpos; /* y 軸位置 */
UINT wZpos; /* z 軸位置 */
UINT wButtons; /* 按鈕狀態 */
} JOYINFO, *PJOYINFO, NEAR *NPJOYINFO, FAR *LPJOYINFO
驅動
程式需要首先檢查遊戲操縱桿的存在,這包括了檢查驅動程式支持和確認操縱桿已與系統相連的兩項工作。joyGetNumDevs調用檢查系統是否配置了遊戲連線埠和驅動程式。如果返回值為零,表明不支持操縱桿功能。如果joyGetNumDevs返回值不為零,則說明系統支持遊戲操縱桿功能。但joyGetNumDevs並不能確定操縱桿是否已被連線上了,通過調用可以完成這些工作,並檢查是否有錯誤發生。
如果有遊戲連線埠,joyGetNumDevs返回值通常為16.
一旦確認了操縱桿已連上,就可以接受器發來的訊息。joySetCapture通知Windows操縱桿訊息應傳送到哪裡機傳送的頻率如何。
joySetCapture中的第一個參數通知Windows誰將得到訊息,第二個參數確定程式將從那個操縱桿接收訊息。第三個參數時表示希望以怎樣的頻度接受JM_MOVE訊息(單位為毫秒),無論操縱桿是否移動,都將以這個頻度接受JM_MOVE訊息。joySetCapture的四個參數允許程式當操縱桿移動一定的距離後才接受訊息。該距離由joySetThreshold設定。
joySetCapture被調用後,視窗將接受操縱桿事件。MM_JOYXMOVE(X=操縱桿號)事件已joySetCapture定義的時間間隔發生。只有當操縱桿的按鈕被按下時,MM_JOYXBUTTONUP和MM_JOYXBUTTONDOWN事件才發生。操縱桿時間出發句柄,改變相應的標籤狀態信息。移動訊息也同時通知程式在新的位置重畫操縱桿標誌。調用joyReleaseCapture通知Windows已結束操縱桿的調用。
編製程序
在實際編製程序時,應首先在Form1的頭檔案Form1.h中加入對mmsystem.h的引用,再加入一些相關的訊息映射即對MM_JOYXMOVE、MM_JOYXBUTTONUP和MM_JOYXBUTTONDOWN事件的回響函式說明。
#include
//--------------------
class Tform1:public TForm
{ __published:
private:
TPoint Position;//用於存儲操縱桿的坐標位置。
public:
MESSAGE_HANDLER(MM_JOY1BUTTONDOWN,TMessage,JMButonUpdate)
套用
用遊戲操縱桿摸擬滑鼠
調用API函式joySetCapture能捕獲遊戲操縱桿。調用joySetCapture函式後,操縱桿產生的所有訊息將會傳送到指定的視窗。它的原型為:
MMRESULT joySetCapture(HWND hwnd, UINT uJoyID, UINT uPeriod, BOOL fChanged );
其中,參數hwnd為接收操縱桿訊息的視窗句柄;參數uJoyID為要捕獲的操縱桿標識,它可以是JOYSTICKID1或是JOYSTICKID2,即第一、第二個遊戲操縱桿;參數uPeriod為輪詢的頻率,單位為毫秒,它指定給應用程式傳送有關操縱桿信息的間隔時間;參數fChanged為改變位置標識,可設為false。
要釋放操縱桿的捕獲時,使用joyReleaseCapture函式。它只有一個參數,就是操縱桿的標識JOYSTICKID1或JOYSTICKID2。