S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

DirectX Input 键盘实现 收藏

Posted on 2010-03-12 15:01 S.l.e!ep.¢% 阅读(1353) 评论(0)  编辑 收藏 引用 所属分类: RootKit

 DirectX Input 键盘实现 收藏
view plaincopy to clipboardprint?
// DInputKeyboard.h: interface for the CDInputKeyboard class.  
//  
//////////////////////////////////////////////////////////////////////  
 
#pragma once  
 
#define DIRECTINPUT_VERSION 0x800  
#include <afxtempl.h>  
#include <dinput.h>  
#pragma comment(lib, "dinput8.lib")  
#pragma comment(lib, "DXguid.Lib")  
 
class CDInputKeyboard    
{  
    #define BUFFERCOUNT 256  
    LPDIRECTINPUT         lpDirectInput;              
    LPDIRECTINPUTDEVICE   lpdiKeyboard;       
    BOOL                  KeyboardAcquired;  
    BOOL                  KeyboardFound;  
    CTypedPtrArray <CPtrArray, LPDIDEVICEINSTANCE> m_KeyboInstance_Array;  
 
protected:  
    virtual BOOL ProcessInputKey(TCHAR tChar)  
    {  
        return false;  
    }  
 
  static BOOL CALLBACK DIEnumDevicesProc(LPCDIDEVICEINSTANCE lpddi,   
                                  LPVOID pvRef)  
  {    
    if (GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_KEYBOARD  
            || ((lpddi->dwDevType & DIDEVTYPE_HID) && GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_DEVICE ) )  
    {   
      LPDIDEVICEINSTANCE pNewdid = (LPDIDEVICEINSTANCE) new DIDEVICEINSTANCE;  
      memcpy(pNewdid, lpddi, sizeof(DIDEVICEINSTANCE));  
      ((CDInputKeyboard *)pvRef)->m_KeyboInstance_Array.Add(pNewdid);  
    }  
    return DIENUM_CONTINUE;    
  } // DIEnumDevicesProc  
 
  void RemoveGUID()  
  {  
    KeyboardFound = 0;  
    while(m_KeyboInstance_Array.GetSize() > 0)  
    {  
      delete m_KeyboInstance_Array.GetAt(0);  
      m_KeyboInstance_Array.RemoveAt(0);  
    }  
  }  
 
public:    
  HWND                hMainWindow;         // app window handle  
    
  virtual BOOL InitInput(HWND hWnd)  
  {  
    ASSERT(lpDirectInput == NULL);  
    ASSERT(hWnd);  
 
    hMainWindow = hWnd;  
 
    HINSTANCE hInstance = (HINSTANCE) GetWindowLong(hMainWindow, GWL_HINSTANCE); // program instance  
    // try to create DirectInput object  
    if(DirectInput8Create(hInstance, DIRECTINPUT_VERSION,  IID_IDirectInput8, (LPVOID*)&lpDirectInput, NULL) != DI_OK)  
    {  
      lpDirectInput = NULL;  
      OutputDebugString( _T("Failed to create DirectInput object.\n") );  
      return FALSE;  
    }  
    return TRUE;  
  }  
 
  INT_PTR EnumKeyboard()  
  {  
    RemoveGUID();  
    if(lpDirectInput)  
    {  
      // enumerate devices so we can get the GUIDs  
      if (lpDirectInput->EnumDevices(0,   
                            DIEnumDevicesProc,  
                            this,   
                            DIEDFL_ALLDEVICES) != DI_OK)  
      {  
        OutputDebugString( _T("Could not enumerate devices.\n") );  
      }  
    }  
    return m_KeyboInstance_Array.GetSize();  
  }  
 
  BOOL Unacquire()  
  {  
    if(lpdiKeyboard)  
    {  
      lpdiKeyboard->Unacquire();  
      lpdiKeyboard->Release();  
      lpdiKeyboard = NULL;  
    }  
    KeyboardAcquired = false;  
    return TRUE;  
  }  
 
  BOOL Acquire(INT_PTR nPos = -1)  
  {  
    Unacquire();  
 
    if(lpDirectInput == NULL)  
    {  
      OutputDebugString( _T("lpDirectInput is NULL.\n") );  
      return FALSE;  
    }  
 
    GUID KeyboardGUID =  GUID_SysKeyboard;  
    if(nPos >=0 && nPos < m_KeyboInstance_Array.GetSize())  
    {  
      KeyboardGUID = m_KeyboInstance_Array.GetAt(nPos)->guidInstance;  
    }  
      
   // try to create keyboard device  
    if(lpDirectInput->CreateDevice(KeyboardGUID, &lpdiKeyboard, NULL) != DI_OK ) //GUID_SysKeyboard  
    {  
      OutputDebugString( _T("Failed to create keyboard device.\n") );  
            Unacquire();  
      return FALSE;  
    }  
 
    // set kbd cooperative level  
    if (lpdiKeyboard->SetCooperativeLevel(hMainWindow, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE) != DI_OK)  
    {  
      OutputDebugString( _T("Failed to set keyboard cooperative level.\n") );  
            Unacquire();  
      return FALSE;  
    }  
 
    // set kbd data format  
    if (lpdiKeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK)  
    {  
      OutputDebugString( _T("Failed to set keyboard data format.\n") );  
            Unacquire();  
      return FALSE;  
    }  
 
   // set kbd buffer size  
    DIPROPDWORD dipdw = {0};  
    dipdw.diph.dwSize = sizeof(DIPROPDWORD);  
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);  
    dipdw.diph.dwObj = 0;  
    dipdw.diph.dwHow = DIPH_DEVICE;  
    dipdw.dwData = BUFFERCOUNT; // * sizeof(DIDEVICEOBJECTDATA);  
    if (lpdiKeyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph) != DI_OK)   
    {  
      OutputDebugString( _T("Failed to set keyboard buffer size.\n") );  
            Unacquire();  
      return FALSE;  
    }  
 
    // try to acquire the keyboard  
    if (lpdiKeyboard->Acquire() != DI_OK)  
    {  
      OutputDebugString( _T("Failed to acquire the keyboard.\n") );  
            Unacquire();  
      return FALSE;  
    }  
 
    KeyboardAcquired = TRUE;  
    return TRUE;        
  }  
 
  BOOL ReacquireInput(void)  
  {  
  //the keyboard  
    if(lpdiKeyboard != NULL)  
    {  
      lpdiKeyboard->Acquire();  
    }  
    else 
    {  
      // keyboard device has not been created.  
      return FALSE;  
    }  
    // if we get here, we are acquired again  
    KeyboardAcquired = TRUE;  
 
    return TRUE;  
  }  // ReacquireInputDevices()  
 
  BOOL PollKeyboard(void) //Reads the keyboard state  
  {  
    if(lpdiKeyboard && KeyboardAcquired)  
    {  
      BYTE diKeys[257] = {0};  
      if (lpdiKeyboard->GetDeviceState(256, &diKeys) == DI_OK)  
      {  
        if(diKeys[DIK_LWIN] & 0x80) /* Left Windows key */ 
        {  
        }  
        if(diKeys[DIK_RWIN] & 0x80) /* Right Windows key */ 
        {  
        }  
        
        return TRUE;  // success  
      }  
    }  
    return FALSE;  
  } // PollKeyboard()  
 
  HRESULT ReadKeyboardInput(void)  
  {  
        HRESULT hRes = DI_OK;  
        if(KeyboardAcquired)  
        {  
            DIDEVICEOBJECTDATA  KbdBuffer[BUFFERCOUNT] = {0};  
            DWORD dwItems = BUFFERCOUNT;  
            hRes = lpdiKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),  
                                                                    KbdBuffer, &dwItems, 0);  
            if(hRes == DI_OK || hRes == DI_BUFFEROVERFLOW)  
            {  
 
                for (DWORD k = 0; k < dwItems; k++)  
                {  
                    LPDIDEVICEOBJECTDATA lpdidod = &KbdBuffer[k];  
 
                    TCHAR VKey = MapVirtualKey(lpdidod->dwOfs, 3); //映射到虚拟键  
                    ProcessInputKey(VKey); //处理输入  
 
                    CString dbgStr, tmpStr;  
                    dbgStr.Format(_T("%d"), lpdidod->dwSequence);  
                    tmpStr.Format(_T(". Scan code 0x%04X"), lpdidod->dwOfs);  
                    dbgStr += tmpStr;              
                    dbgStr += (lpdidod->dwData & 0x80)? _T(" pressed ") : _T(" released ");          
                    tmpStr.Format(_T(". Age: %d ms"), GetTickCount() - lpdidod->dwTimeStamp);  
                    dbgStr += tmpStr;  
                    dbgStr += _T("\n");  
                    OutputDebugString(dbgStr);          
                }  
            }  
            else if(hRes == DIERR_INPUTLOST)  
            {  
                ReacquireInput();   
                hRes = S_FALSE;  
            }   
        }  
    return hRes;  
  }  
 
 
////////////////////////////////////////////////  
  CDInputKeyboard()  
  {  
    hMainWindow = NULL;  
    lpDirectInput = NULL;  
    lpdiKeyboard = NULL;  
    KeyboardAcquired = 0;  
    KeyboardFound = 0;  
    m_KeyboInstance_Array.RemoveAll();  
  }  
 
  virtual ~CDInputKeyboard()  
  {  
    if(lpdiKeyboard)  
    {  
      lpdiKeyboard->Unacquire();  
      lpdiKeyboard->Release();  
      lpdiKeyboard = NULL;  
    }  
 
    if(lpDirectInput)  
    {  
      lpDirectInput->Release();  
      lpDirectInput = NULL;  
    }  
 
    RemoveGUID();  
  }  
 
 
}; 
// DInputKeyboard.h: interface for the CDInputKeyboard class.
//
//////////////////////////////////////////////////////////////////////

#pragma once

#define DIRECTINPUT_VERSION 0x800
#include <afxtempl.h>
#include <dinput.h>
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "DXguid.Lib")

class CDInputKeyboard 
{
 #define BUFFERCOUNT 256
 LPDIRECTINPUT         lpDirectInput;           
 LPDIRECTINPUTDEVICE   lpdiKeyboard;  
 BOOL                  KeyboardAcquired;
 BOOL                  KeyboardFound;
 CTypedPtrArray <CPtrArray, LPDIDEVICEINSTANCE> m_KeyboInstance_Array;

protected:
 virtual BOOL ProcessInputKey(TCHAR tChar)
 {
  return false;
 }

  static BOOL CALLBACK DIEnumDevicesProc(LPCDIDEVICEINSTANCE lpddi,
                                  LPVOID pvRef)
  { 
    if (GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_KEYBOARD
   || ((lpddi->dwDevType & DIDEVTYPE_HID) && GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_DEVICE ) )
    {
      LPDIDEVICEINSTANCE pNewdid = (LPDIDEVICEINSTANCE) new DIDEVICEINSTANCE;
      memcpy(pNewdid, lpddi, sizeof(DIDEVICEINSTANCE));
      ((CDInputKeyboard *)pvRef)->m_KeyboInstance_Array.Add(pNewdid);
    }
    return DIENUM_CONTINUE; 
  } // DIEnumDevicesProc

  void RemoveGUID()
  {
    KeyboardFound = 0;
    while(m_KeyboInstance_Array.GetSize() > 0)
    {
      delete m_KeyboInstance_Array.GetAt(0);
      m_KeyboInstance_Array.RemoveAt(0);
    }
  }

public: 
  HWND                hMainWindow;         // app window handle
 
  virtual BOOL InitInput(HWND hWnd)
  {
    ASSERT(lpDirectInput == NULL);
    ASSERT(hWnd);

    hMainWindow = hWnd;

    HINSTANCE hInstance = (HINSTANCE) GetWindowLong(hMainWindow, GWL_HINSTANCE); // program instance
    // try to create DirectInput object
    if(DirectInput8Create(hInstance, DIRECTINPUT_VERSION,  IID_IDirectInput8, (LPVOID*)&lpDirectInput, NULL) != DI_OK)
    {
      lpDirectInput = NULL;
      OutputDebugString( _T("Failed to create DirectInput object.\n") );
      return FALSE;
    }
    return TRUE;
  }

  INT_PTR EnumKeyboard()
  {
    RemoveGUID();
    if(lpDirectInput)
    {
      // enumerate devices so we can get the GUIDs
      if (lpDirectInput->EnumDevices(0,
                            DIEnumDevicesProc,
                            this,
                            DIEDFL_ALLDEVICES) != DI_OK)
      {
        OutputDebugString( _T("Could not enumerate devices.\n") );
      }
    }
    return m_KeyboInstance_Array.GetSize();
  }

  BOOL Unacquire()
  {
    if(lpdiKeyboard)
    {
      lpdiKeyboard->Unacquire();
      lpdiKeyboard->Release();
      lpdiKeyboard = NULL;
    }
    KeyboardAcquired = false;
    return TRUE;
  }

  BOOL Acquire(INT_PTR nPos = -1)
  {
    Unacquire();

    if(lpDirectInput == NULL)
    {
      OutputDebugString( _T("lpDirectInput is NULL.\n") );
      return FALSE;
    }

    GUID KeyboardGUID =  GUID_SysKeyboard;
    if(nPos >=0 && nPos < m_KeyboInstance_Array.GetSize())
    {
      KeyboardGUID = m_KeyboInstance_Array.GetAt(nPos)->guidInstance;
    }
   
   // try to create keyboard device
    if(lpDirectInput->CreateDevice(KeyboardGUID, &lpdiKeyboard, NULL) != DI_OK ) //GUID_SysKeyboard
    {
      OutputDebugString( _T("Failed to create keyboard device.\n") );
   Unacquire();
      return FALSE;
    }

    // set kbd cooperative level
    if (lpdiKeyboard->SetCooperativeLevel(hMainWindow, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE) != DI_OK)
    {
      OutputDebugString( _T("Failed to set keyboard cooperative level.\n") );
   Unacquire();
      return FALSE;
    }

    // set kbd data format
    if (lpdiKeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK)
    {
      OutputDebugString( _T("Failed to set keyboard data format.\n") );
   Unacquire();
      return FALSE;
    }

   // set kbd buffer size
    DIPROPDWORD dipdw = {0};
    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dipdw.diph.dwObj = 0;
    dipdw.diph.dwHow = DIPH_DEVICE;
    dipdw.dwData = BUFFERCOUNT; // * sizeof(DIDEVICEOBJECTDATA);
    if (lpdiKeyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph) != DI_OK)
    {
      OutputDebugString( _T("Failed to set keyboard buffer size.\n") );
   Unacquire();
      return FALSE;
    }

    // try to acquire the keyboard
    if (lpdiKeyboard->Acquire() != DI_OK)
    {
      OutputDebugString( _T("Failed to acquire the keyboard.\n") );
   Unacquire();
      return FALSE;
    }

    KeyboardAcquired = TRUE;
    return TRUE;     
  }

  BOOL ReacquireInput(void)
  {
  //the keyboard
    if(lpdiKeyboard != NULL)
    {
      lpdiKeyboard->Acquire();
    }
    else
    {
      // keyboard device has not been created.
      return FALSE;
    }
    // if we get here, we are acquired again
    KeyboardAcquired = TRUE;

    return TRUE;
  }  // ReacquireInputDevices()

  BOOL PollKeyboard(void) //Reads the keyboard state
  {
    if(lpdiKeyboard && KeyboardAcquired)
    {
      BYTE diKeys[257] = {0};
      if (lpdiKeyboard->GetDeviceState(256, &diKeys) == DI_OK)
      {
        if(diKeys[DIK_LWIN] & 0x80) /* Left Windows key */
        {
        }
        if(diKeys[DIK_RWIN] & 0x80) /* Right Windows key */
        {
        }
     
        return TRUE;  // success
      }
    }
    return FALSE;
  } // PollKeyboard()

  HRESULT ReadKeyboardInput(void)
  {
  HRESULT hRes = DI_OK;
  if(KeyboardAcquired)
  {
   DIDEVICEOBJECTDATA  KbdBuffer[BUFFERCOUNT] = {0};
   DWORD dwItems = BUFFERCOUNT;
   hRes = lpdiKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),
                 KbdBuffer, &dwItems, 0);
   if(hRes == DI_OK || hRes == DI_BUFFEROVERFLOW)
   {

    for (DWORD k = 0; k < dwItems; k++)
    {
     LPDIDEVICEOBJECTDATA lpdidod = &KbdBuffer[k];

     TCHAR VKey = MapVirtualKey(lpdidod->dwOfs, 3); //映射到虚拟键
     ProcessInputKey(VKey); //处理输入

     CString dbgStr, tmpStr;
     dbgStr.Format(_T("%d"), lpdidod->dwSequence);
     tmpStr.Format(_T(". Scan code 0x%04X"), lpdidod->dwOfs);
     dbgStr += tmpStr;           
     dbgStr += (lpdidod->dwData & 0x80)? _T(" pressed ") : _T(" released ");       
     tmpStr.Format(_T(". Age: %d ms"), GetTickCount() - lpdidod->dwTimeStamp);
     dbgStr += tmpStr;
     dbgStr += _T("\n");
     OutputDebugString(dbgStr);       
    }
   }
   else if(hRes == DIERR_INPUTLOST)
   {
    ReacquireInput();
    hRes = S_FALSE;
   }
  }
    return hRes;
  }


////////////////////////////////////////////////
  CDInputKeyboard()
  {
    hMainWindow = NULL;
    lpDirectInput = NULL;
    lpdiKeyboard = NULL;
    KeyboardAcquired = 0;
    KeyboardFound = 0;
    m_KeyboInstance_Array.RemoveAll();
  }

  virtual ~CDInputKeyboard()
  {
    if(lpdiKeyboard)
    {
      lpdiKeyboard->Unacquire();
      lpdiKeyboard->Release();
      lpdiKeyboard = NULL;
    }

    if(lpDirectInput)
    {
      lpDirectInput->Release();
      lpDirectInput = NULL;
    }

    RemoveGUID();
  }


};


 

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zgl7903/archive/2010/02/01/5277822.aspx


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理