參考學習博客:http://www.cnblogs.com/kingthy/archive/2009/03/28/1424055.html
看了這一篇博客,直接用了上文的例子,發送數據的確會遇到發送n多消息這個問題,所以想方法解決一下,順便記錄一下。
主動方式:按自己的需要去獲取游戲手柄的狀態信息。
需要用到如下的API函數 joyGetPos和joyGetPosEx,因為joyGetPos只能獲取到1、2、3、4按鈕的狀態,所以使用joyGetPosEx函數
MMRESULT joyGetPosEx( UINT uJoyID, LPJOYINFOEX pji );
uJoyID
要查詢的操縱桿的標識。有效值uJoyID范圍從零(JOYSTICKID1)15。
PJI
指針到一個joyInfoEx結構包含擴展的位置信息和導航鍵的按鍵狀態。你必須設置的dwSize和dwFlags中成員或joyGetPosEx,否則將失敗。從返回的信息joyGetPosEx取決於你在指定的標志dwFlags中。
joyInfoEx結構體如下
typedef struct joyinfoex_tag { DWORD dwSize; DWORD dwFlags; DWORD dwXpos; DWORD dwYpos; DWORD dwZpos; DWORD dwRpos; DWORD dwUpos; DWORD dwVpos; DWORD dwButtons; DWORD dwButtonNumber; DWORD dwPOV; DWORD dwReserved1; DWORD dwReserved2; } JOYINFOEX;
換成C#中的代碼可以寫成如下:
[StructLayout(LayoutKind.Sequential)] //順序布局 public struct JOYINFOEX { /// <summary> /// Size, in bytes, of this structure.//大小,以字節為單位 /// </summary> public int dwSize; /// <summary> /// Flags indicating the valid information returned in this structure. Members that do not contain valid information are set to zero.標志,指示在該結構返回的有效信息。構件不包含有效信息被設定為零 /// </summary> public int dwFlags; /// <summary> /// Current X-coordinate. /// </summary> public int dwXpos;//X坐標 /// <summary> /// Current Y-coordinate. /// </summary> public int dwYpos; /// <summary> /// Current Z-coordinate. /// </summary> public int dwZpos; /// <summary> /// Current position of the rudder or fourth joystick axis. /// </summary> public int dwRpos; /// <summary> /// Current fifth axis position. /// </summary> public int dwUpos; /// <summary> /// Current sixth axis position. /// </summary> public int dwVpos; /// <summary> /// Current state of the 32 joystick buttons. The value of this member can be set to any combination of JOY_BUTTONn flags, where n is a value in the range of 1 through 32 corresponding to the button that is pressed.當前32個按鈕的狀態 /// </summary> public int dwButtons; /// <summary> /// Current button number that is pressed. //當前那些按鈕被按下 /// </summary> public int dwButtonNumber; /// <summary> /// Current position of the point-of-view control. Values for this member are in the range 0 through 35,900. These values represent the angle, in degrees, of each view multiplied by 100. /// </summary> public int dwPOV; /// <summary> /// Reserved; do not use. /// </summary> public int dwReserved1; /// <summary> /// Reserved; do not use. /// </summary> public int dwReserved2; }
如果我們要使用joyGetPosEx來獲取游戲設備的狀態,我們必須先初始化JOYINFOEX結構實例,並要設置dwSize的值。也即是JOYINFOEX結構體所占用的內存空間大小(其值可通過Marshal.SizeOf求得)。而如果要取得游戲設備的其它參數,則還必須要設置dwFlags參數的值!dwFlag標志的值有如下一些;
我們設置為JOY_RETURNBUTTONS
示例代碼:
JoystickAPI.JOYINFOEX infoEx = new JoystickAPI.JOYINFOEX(); infoEx.dwSize = Marshal.SizeOf(typeof(JoystickAPI.JOYINFOEX)); infoEx.dwFlags = (int)JoystickAPI.JOY_RETURNBUTTONS; int result = JoystickAPI.joyGetPosEx(this.Id, ref infoEx);
如果joyGetPosEx函數獲取手柄狀態數據成功,則返回JOYERR_NOERROR(值為0),否則返回其它值的話表示獲取失敗。
當數據獲取成功后,對應的游戲手柄的狀態數據都已存儲在JOYINFOEX結構實例中了。如要判斷是否按下了方向鍵,則可判斷dwXPos與dwYPos的值;而判斷是否按了其它按鈕,則可判斷dwButtons的值。
因為“主動方式”的“時效性”只有一次,所以為了能夠隨時監視到游戲手柄的按鍵事件,就必須進行“輪循”獲取,當監視到游戲手柄有按鍵發生時就進行事件通知(噫?好像“被動方式”?嗯,其實當我們向系統申請捕捉某個游戲手柄時,系統最后也是在幫我們進行“輪循”操作!)。而實現“輪循”的方式則可以有多種方式,比如采用獨立的線程進行一個死循環;或者采用Timer進行定時執行。
還是會遇到那個發送多個數據的問題,以后解決重復狀態的問題。
這篇文章參考了網上的其他大神的文章,里面很少自己寫的,旨在記錄學習過程,希望能幫到你們,一起探討