DirectX Input 键盘实现

  1 // DInputKeyboard.h: interface for the CDInputKeyboard class.
  2 //
  3 //////////////////////////////////////////////////////////////////////
  4 
  5 #pragma once
  6 
  7 #define DIRECTINPUT_VERSION 0x800
  8 #include <afxtempl.h>
  9 #include <dinput.h>
 10 #pragma comment(lib, "dinput8.lib")
 11 #pragma comment(lib, "DXguid.Lib")
 12 
 13 class CDInputKeyboard  
 14 {
 15     #define BUFFERCOUNT 256
 16     LPDIRECTINPUT         lpDirectInput;            
 17     LPDIRECTINPUTDEVICE   lpdiKeyboard;     
 18     BOOL                  KeyboardAcquired;
 19     BOOL                  KeyboardFound;
 20     CTypedPtrArray <CPtrArray, LPDIDEVICEINSTANCE> m_KeyboInstance_Array;
 21 
 22 protected:
 23     virtual BOOL ProcessInputKey(TCHAR tChar)
 24     {
 25         return false;
 26     }
 27 
 28   static BOOL CALLBACK DIEnumDevicesProc(LPCDIDEVICEINSTANCE lpddi, 
 29                                   LPVOID pvRef)
 30   {  
 31     if (GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_KEYBOARD
 32             || ((lpddi->dwDevType & DIDEVTYPE_HID) && GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_DEVICE ) )
 33     { 
 34       LPDIDEVICEINSTANCE pNewdid = (LPDIDEVICEINSTANCE) new DIDEVICEINSTANCE;
 35       memcpy(pNewdid, lpddi, sizeof(DIDEVICEINSTANCE));
 36       ((CDInputKeyboard *)pvRef)->m_KeyboInstance_Array.Add(pNewdid);
 37     }
 38     return DIENUM_CONTINUE;  
 39   } // DIEnumDevicesProc
 40 
 41   void RemoveGUID()
 42   {
 43     KeyboardFound = 0;
 44     while(m_KeyboInstance_Array.GetSize() > 0)
 45     {
 46       delete m_KeyboInstance_Array.GetAt(0);
 47       m_KeyboInstance_Array.RemoveAt(0);
 48     }
 49   }
 50 
 51 public:  
 52   HWND                hMainWindow;         // app window handle
 53   
 54   virtual BOOL InitInput(HWND hWnd)
 55   {
 56     ASSERT(lpDirectInput == NULL);
 57     ASSERT(hWnd);
 58 
 59     hMainWindow = hWnd;
 60 
 61     HINSTANCE hInstance = (HINSTANCE) GetWindowLong(hMainWindow, GWL_HINSTANCE); // program instance
 62     // try to create DirectInput object
 63     if(DirectInput8Create(hInstance, DIRECTINPUT_VERSION,  IID_IDirectInput8, (LPVOID*)&lpDirectInput, NULL) != DI_OK)
 64     {
 65       lpDirectInput = NULL;
 66       OutputDebugString( _T("Failed to create DirectInput object./n") );
 67       return FALSE;
 68     }
 69     return TRUE;
 70   }
 71 
 72   INT_PTR EnumKeyboard()
 73   {
 74     RemoveGUID();
 75     if(lpDirectInput)
 76     {
 77       // enumerate devices so we can get the GUIDs
 78       if (lpDirectInput->EnumDevices(0, 
 79                             DIEnumDevicesProc,
 80                             this, 
 81                             DIEDFL_ALLDEVICES) != DI_OK)
 82       {
 83         OutputDebugString( _T("Could not enumerate devices./n") );
 84       }
 85     }
 86     return m_KeyboInstance_Array.GetSize();
 87   }
 88 
 89   BOOL Unacquire()
 90   {
 91     if(lpdiKeyboard)
 92     {
 93       lpdiKeyboard->Unacquire();
 94       lpdiKeyboard->Release();
 95       lpdiKeyboard = NULL;
 96     }
 97     KeyboardAcquired = false;
 98     return TRUE;
 99   }
100 
101   BOOL Acquire(INT_PTR nPos = -1)
102   {
103     Unacquire();
104 
105     if(lpDirectInput == NULL)
106     {
107       OutputDebugString( _T("lpDirectInput is NULL./n") );
108       return FALSE;
109     }
110 
111     GUID KeyboardGUID =  GUID_SysKeyboard;
112     if(nPos >=0 && nPos < m_KeyboInstance_Array.GetSize())
113     {
114       KeyboardGUID = m_KeyboInstance_Array.GetAt(nPos)->guidInstance;
115     }
116     
117    // try to create keyboard device
118     if(lpDirectInput->CreateDevice(KeyboardGUID, &lpdiKeyboard, NULL) != DI_OK ) //GUID_SysKeyboard
119     {
120       OutputDebugString( _T("Failed to create keyboard device./n") );
121             Unacquire();
122       return FALSE;
123     }
124 
125     // set kbd cooperative level
126     if (lpdiKeyboard->SetCooperativeLevel(hMainWindow, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE) != DI_OK)
127     {
128       OutputDebugString( _T("Failed to set keyboard cooperative level./n") );
129             Unacquire();
130       return FALSE;
131     }
132 
133     // set kbd data format
134     if (lpdiKeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK)
135     {
136       OutputDebugString( _T("Failed to set keyboard data format./n") );
137             Unacquire();
138       return FALSE;
139     }
140 
141    // set kbd buffer size
142     DIPROPDWORD dipdw = {0};
143     dipdw.diph.dwSize = sizeof(DIPROPDWORD);
144     dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
145     dipdw.diph.dwObj = 0;
146     dipdw.diph.dwHow = DIPH_DEVICE;
147     dipdw.dwData = BUFFERCOUNT; // * sizeof(DIDEVICEOBJECTDATA);
148     if (lpdiKeyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph) != DI_OK) 
149     {
150       OutputDebugString( _T("Failed to set keyboard buffer size./n") );
151             Unacquire();
152       return FALSE;
153     }
154 
155     // try to acquire the keyboard
156     if (lpdiKeyboard->Acquire() != DI_OK)
157     {
158       OutputDebugString( _T("Failed to acquire the keyboard./n") );
159             Unacquire();
160       return FALSE;
161     }
162 
163     KeyboardAcquired = TRUE;
164     return TRUE;      
165   }
166 
167   BOOL ReacquireInput(void)
168   {
169   //the keyboard
170     if(lpdiKeyboard != NULL)
171     {
172       lpdiKeyboard->Acquire();
173     }
174     else
175     {
176       // keyboard device has not been created.
177       return FALSE;
178     }
179     // if we get here, we are acquired again
180     KeyboardAcquired = TRUE;
181 
182     return TRUE;
183   }  // ReacquireInputDevices()
184 
185   BOOL PollKeyboard(void) //Reads the keyboard state
186   {
187     if(lpdiKeyboard && KeyboardAcquired)
188     {
189       BYTE diKeys[257] = {0};
190       if (lpdiKeyboard->GetDeviceState(256, &diKeys) == DI_OK)
191       {
192         if(diKeys[DIK_LWIN] & 0x80) /* Left Windows key */
193         {
194         }
195         if(diKeys[DIK_RWIN] & 0x80) /* Right Windows key */
196         {
197         }
198       
199         return TRUE;  // success
200       }
201     }
202     return FALSE;
203   } // PollKeyboard()
204 
205   HRESULT ReadKeyboardInput(void)
206   {
207         HRESULT hRes = DI_OK;
208         if(KeyboardAcquired)
209         {
210             DIDEVICEOBJECTDATA  KbdBuffer[BUFFERCOUNT] = {0};
211             DWORD dwItems = BUFFERCOUNT;
212             hRes = lpdiKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),
213                                                                     KbdBuffer, &dwItems, 0);
214             if(hRes == DI_OK || hRes == DI_BUFFEROVERFLOW)
215             {
216 
217                 for (DWORD k = 0; k < dwItems; k++)
218                 {
219                     LPDIDEVICEOBJECTDATA lpdidod = &KbdBuffer[k];
220 
221                     TCHAR VKey = MapVirtualKey(lpdidod->dwOfs, 3); //映射到虚拟键
222                     ProcessInputKey(VKey); //处理输入
223 
224                     CString dbgStr, tmpStr;
225                     dbgStr.Format(_T("%d"), lpdidod->dwSequence);
226                     tmpStr.Format(_T(". Scan code 0x%04X"), lpdidod->dwOfs);
227                     dbgStr += tmpStr;            
228                     dbgStr += (lpdidod->dwData & 0x80)? _T(" pressed ") : _T(" released ");        
229                     tmpStr.Format(_T(". Age: %d ms"), GetTickCount() - lpdidod->dwTimeStamp);
230                     dbgStr += tmpStr;
231                     dbgStr += _T("/n");
232                     OutputDebugString(dbgStr);        
233                 }
234             }
235             else if(hRes == DIERR_INPUTLOST)
236             {
237                 ReacquireInput(); 
238                 hRes = S_FALSE;
239             } 
240         }
241     return hRes;
242   }
243 
244 
245 ////////////////////////////////////////////////
246   CDInputKeyboard()
247   {
248     hMainWindow = NULL;
249     lpDirectInput = NULL;
250     lpdiKeyboard = NULL;
251     KeyboardAcquired = 0;
252     KeyboardFound = 0;
253     m_KeyboInstance_Array.RemoveAll();
254   }
255 
256   virtual ~CDInputKeyboard()
257   {
258     if(lpdiKeyboard)
259     {
260       lpdiKeyboard->Unacquire();
261       lpdiKeyboard->Release();
262       lpdiKeyboard = NULL;
263     }
264 
265     if(lpDirectInput)
266     {
267       lpDirectInput->Release();
268       lpDirectInput = NULL;
269     }
270 
271     RemoveGUID();
272   }
273 
274 
275 };

 

posted @ 2013-06-11 01:20  Max Woods  阅读(1208)  评论(0编辑  收藏  举报