• Direct3D轮回:构建基于DirectInput机制的键盘输入设备


    有了鼠标输入设备,这一篇简单讨论基于DirectInput机制的键盘输入设备的构建。

    继续上一篇,我们再原有基础上丰富DirectInput.h和DirectInput.cpp的内容:

    /*-------------------------------------

    代码清单:D3DInput.h
    来自:
    http://www.cnblogs.com/kenkao

    -------------------------------------
    */
    …………
    …………
    class CKeyboardInput
    {
    public:
        CKeyboardInput();
        
    ~CKeyboardInput();
        HRESULT Initialize(HINSTANCE hInst,HWND hWnd);      
    //初始化输入设备
        void    GetState();                                 //获取设备状态
        BOOL    IsKeyDown(int KeyCode);                     //键位是否按下
        BOOL    IsKeyUp(int KeyCode);                       //键位是否弹起
        void    Release();                                  //释放输入设备
    private:
        HWND                 m_hWnd;                           
    //设备所属的窗口句柄
        LPDIRECTINPUT8       m_pIDirectInput;                  //IDirectInput接口对象
        LPDIRECTINPUTDEVICE8 m_pIDirectInputDevice;            //IDirectInput设备对象
        char keyBuffer[256];                                   //键盘缓冲区,对应全盘256个字符
    };
    D3DInput.cpp
    /*-------------------------------------

    代码清单:D3DInput.cpp
    来自:
    http://www.cnblogs.com/kenkao

    -------------------------------------
    */
    …………
    …………
    CKeyboardInput::CKeyboardInput() : m_pIDirectInput(NULL),
                                       m_pIDirectInputDevice(NULL)
    {

    }

    CKeyboardInput::
    ~CKeyboardInput()
    {

    }

    HRESULT CKeyboardInput::Initialize(HINSTANCE hInst,HWND hWnd)
    {
        m_hWnd
    =hWnd;
        HRESULT hr;
        
    //创建IDirectInput接口对象
        hr=DirectInput8Create(hInst,DIRECTINPUT_VERSION,
            IID_IDirectInput8,(
    void**)&m_pIDirectInput,NULL);
        
    if(FAILED(hr)){
            
    return hr;
        }
        
    //初始化键盘输入设备
        hr=m_pIDirectInput->CreateDevice(GUID_SysKeyboard,&m_pIDirectInputDevice,NULL);//GUID_SysKeyboard代表初始化设备为键盘设备
        if(FAILED(hr)){
            ReleaseCOM(m_pIDirectInput);
            
    return hr;
        }
        
    //设置键盘设备的数据格式
        hr=m_pIDirectInputDevice->SetDataFormat(&c_dfDIKeyboard);
        
    if(FAILED(hr)){
            ReleaseCOM(m_pIDirectInputDevice);
            ReleaseCOM(m_pIDirectInput);
            
    return hr;
        }
        
    //设置键盘设备的协调级别
        hr=m_pIDirectInputDevice->SetCooperativeLevel(hWnd,DISCL_FOREGROUND|DISCL_EXCLUSIVE);
        
    if(FAILED(hr)){
            ReleaseCOM(m_pIDirectInputDevice);
            ReleaseCOM(m_pIDirectInput);
            
    return hr;
        }
        
    //获取键盘设备访问权限
        hr=m_pIDirectInputDevice->Acquire();
        
    //键盘缓冲区清零
        ZeroMemory(keyBuffer,sizeof(char)*256);
        
    return S_OK;
    }

    void CKeyboardInput::GetState()
    {
        HRESULT hr;
        
    //键盘缓冲区清零
        ZeroMemory(keyBuffer,sizeof(char)*256);
        
    //立即模式下获取设备状态
        hr = m_pIDirectInputDevice->GetDeviceState(sizeof(keyBuffer),(LPVOID)keyBuffer);
        
    if(FAILED(hr))
        {
            
    //如果失败,则重新获取键盘设备的访问权限
            hr=m_pIDirectInputDevice->Acquire();
        }
    }

    BOOL CKeyboardInput::IsKeyDown(
    int KeyCode)
    {
        
    return keyBuffer[KeyCode] & 0x80;
    }

    BOOL CKeyboardInput::IsKeyUp(
    int KeyCode)
    {
        
    return !IsKeyDown(KeyCode);
    }

    void CKeyboardInput::Release()
    {
        // 释放键盘设备的访问权
        m_pIDirectInputDevice
    ->Unacquire();
        ReleaseCOM(m_pIDirectInputDevice);
        ReleaseCOM(m_pIDirectInput);
    }

    通过如上代码不难发现,键盘输入设备的构建流程其实与鼠标设备很类似~

    区别在于,这次我们将输入设备的相关信息记录到了

    char keyBuffer[256];

    之中,长度256代表键盘上的256个键位(我没有仔细统计,感兴趣的朋友可以详细的数一下~囧~),换言之,键盘设备通过GetDeviceState记录下了键盘当前256个键位的所有状态。

    理解清楚这些内容,我们可以在原有工程基础上新增一个键盘输入设备检测函数:

    void TestKeyboardInput()
    {
        TCHAR tmpText[
    50];
        
    // 获得键盘输入设备状态
        g_pKeyboardInput->GetState();
        
    // 单键检测
        if(g_pKeyboardInput->IsKeyDown(DIK_D))
        {
            sprintf(tmpText,
    "D键被按下");
            MessageBox(NULL,tmpText,
    "提示",MB_OK|MB_ICONINFORMATION);
        }
        
    // 组合键检测
        else if(g_pKeyboardInput->IsKeyDown(DIK_A)&g_pKeyboardInput->IsKeyDown(DIK_S))
        {
            sprintf(tmpText,
    "A&S组合键被按下");
            MessageBox(NULL,tmpText,
    "提示",MB_OK|MB_ICONINFORMATION);
        }
    }

    大家不难看出,组合键检测的实现其实相当容易~

    当然,最后不要忘记释放我们构建的键盘设备~

    ReleaseCOM(g_pKeyboardInput);

    如下效果图:

  • 相关阅读:
    firebird database (快速入門)
    firebird的数据类型(datatype)
    通过ASP.NET获取URL地址方法
    FIREBIRD使用经验总结
    C# Append a host header to a website in IIS by code
    Ubuntu 9.04 下载镜像地址
    Firebird如何防止空值扩散
    Tmail: 开源邮件服务器软件包
    Firebird中的NULL
    本地数据源:使用firebird数据库
  • 原文地址:https://www.cnblogs.com/kenkao/p/2087654.html
Copyright © 2020-2023  润新知