DirectInput的使用(1)
前言
在偵測輸入時可以採用XInput來偵測,可以參考XInput的使用這一篇,但XInput並不支援鍵盤與滑鼠,且手把要是年代較久遠的話也會無法被XInput偵測到。為什麼不用訊息幫浦來偵測輸入呢?理由很簡單,作業系統的訊息幫浦沒辦法調整偵測的速度,像現代電玩時常需求的FPS60偵測速度是達不到的,就我以前實測的經驗,訊息幫浦不但偵測速度不夠,而且偶爾還有掉輸入(明明有輸入卻沒反應),雖然不知是否為偵測速度不夠造成,但用DirectInput偵測鍵盤的輸入,這個狀況就可以得到解決。這次的紀錄只會記錄到鍵盤的偵測與使用,在此做個紀錄。內容
使用DirectInput的過程並不會太繁雜,首先使用DirectInputCreate()製造出IDirectInput8,這個介面只需造一次即可,接著用IDirectInput8來製造出IDirectInputDevice8,而依據製造的參數不同可以讓IDirectInputDevice8代表鍵盤、滑鼠與手把,本篇將說明如何將IDirectInputDevice8初始化為鍵盤。初始化鍵盤的範例碼如下
#include <dinput> #include <dinputd> void DetectedKeyboardKeys(IDirectInputDevice8* pDIDeviceKeyboard) { unsigned char keyState[256]; if(pDIDeviceKeyboard->etDeviceState(256,keyState) != DI_OK) return; //if GetDeviceState() is fined,keyState will save all key state from keyboard... //Follow detect sample... //Is num 0 pressed? if(keyState[DIK_0]) { //do something... } //Is key a pressed? if(keyState[DIK_A]) { //do something... } } int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ) { //Init main window //... HWND mainWin = initMainWindow; //Init DiectInput... IDirectInput8* pDirectInput = nullptr; if(DirectInput8Create(hInstance,DIRECTINPUT_VERSION,IID_IDirectInput8,(void**)&pDirectInput ,NULL) != DI_OK) return 1; //Init keyboard IDirectInputDevice8* pDIDeviceKeyboard = nullptr; if(pDirectInput->CreateDevice(GUID_SysKeyboard,&pDIDeviceKeyboard ,NULL) != DI_OK) { pDirectInput->Release(); return 1; } // if(pDIDeviceKeyboard->SetCooperativeLevel(mainWin,DISCL_FOREGROUND|DISCL_NONEXCLUSIVE) != DI_OK) { pDIDeviceKeyboard->Release(); pDirectInput->Release(); return 1; } if(pDIDeviceKeyboard->SetDataFormat((DIDATAFORMAT*)&c_dfDIKeyboard) != DI_OK) { pDIDeviceKeyboard->Release(); pDirectInput->Release(); return 1; } // pDIDeviceKeyboard->Acquire(); //Init keyboard end // return 0; }
在主程式一如之前所說製造出IDirectInput8,要注意HINSTANCE是必要的參數,再來是透過 IDirectInput8的CreateDevice()來製造出IDirectInputDevice8,並可載參數上看到"GUID_SysKeyboard",這個參數會決定裝置是鍵盤、滑鼠或手把,接著是SetCooperativeLevel(),主要的目的確定要偵測哪個視窗的輸入,SetDataFormat()決定偵測資料的輸出格式,在鍵盤時這是固定的,所以用c_dfDIKeyboard來設定即可,接著Acquire(),這個過程很重要,初始化的最後一個流程,勢必要流程請勿省略,Acquire()如果失敗表示該裝置目前沒連上,以上就是初始化鍵盤的部分。偵測的部分在DetectedKeyboardKeys(),首先準備好一塊Buffer,範例使用的是keyState,256是鍵盤上所有的鍵的大小,透過GetDeviceState()來取得所有按鍵的輸入狀態,取完之後如何取得要偵測的按鍵的狀態呢?可以參考
Keyboard Device Enumeration,用該列舉來做為索引值取得目前按鍵的狀態,如果不是0就代表按下。
參考資料
Capturing DirectX DirectInput Keyboard and Mouse InputDirectInput
Keyboard Device Enumeration
沒有留言:
張貼留言