• 初学Direct X(3)


    初学Direct X(3)


    1.获取外设输入——键盘以及鼠标

    无论是获取鼠标还是键盘的设备,首先得初始化DirectInput,不过先把必要的环境先配置好:
    所要用到的头文件以及库文件是(相比于前两次):

    #include <dinput.h>
    #pragma comment(lib,"dinput8.lib")
    #pragma comment(lib,"dxguid.lib")
    

    以及要用到的DirectInput对象以及设备(包括键盘和鼠标)对象:

    LPDIRECTINPUT8 dinput;
    LPDIRECTINPUTDEVICE8A dikeyboard;
    LPDIRECTINPUTDEVICE8A dimouse;
    

    准备完毕后开始初始化DirectInput:

    HRESULT DirectInput8Create(
             HINSTANCE hinst, // 可以通过GetModuleHandle(NULL)
             DWORD dwVersion, // DirectInput版本,通常是DIRECTINPUT_VERSION
             REFIID riidltf, // 使用的DirectInput版本的引用标识符,我这儿是IID_IDirectInput8
             LPVOID * ppvOut,   //指向DirectInput对象指针的指针
             LPUNKNOWN punkOuter //总是NULL
    );
    

    下面是一个调用示例:

    HRESULT result = DirectInput8Create(
    		GetModuleHandle(NULL),
    		DIRECTINPUT_VERSION,
    		IID_IDirectInput8,
    		(void **)&dinput,
    		NULL
    );
    

    至此,DirectInput的初始化就已经完成

    2. 初始化键盘

    在初始化了DirectInput之后,可通过调用CreateDevice函数来创建键盘设备

    HRESULT CreateDevice(
    	THIS_ REFGUID, 
    	LPDIRECTINPUTDEVICE8A *lplpDirectInputDevice, 
    	LPUNKNOWN pUnkouter 
    ); 
    

    REFGUID:指定要创建的对象类型,例如键盘或者鼠标,键盘是GUID_SysKeyboard,鼠标是GUID_SysMouse
    lplpDirectInputDevice:接收DirectInput设备句柄的地址设备指针
    pUnkouter : 总是NULL

    2.1 设置数据格式

    这一步是设置键盘的数据格式,告诉DirectInput如何将数据传给程序,这是一种面对市场上多种多样的输入设备的统一读取办法

    HRESULT SetDataFormat(
            LPCDIDATAFORMAT lpdf
    )
    

    lpdf :不需要我们自己定义,它在dinput中就有定义,对于键盘是 c_dfDIKeyboard,对于鼠标是 c_dfDIMouse

    2.2 设置协作级别

    这一步是设置协作级别,它按优先级决定DirectInput将键盘输入传递给程序的优先级

    HRESULT SetCooperativeLevel(
             HWND hwnd,
             DWORD  
    )
    

    dwFlags:最常用的是DISCL_NONEXCLUSIVE | DISCL_FOREGROUND

    2.3 获取设备

    这一步也是收获的一步,就是使用Acquire获取设备

    HRESULT Acquire()
    

    若不在程序结束的时候使用Unacquire()释放设备,则可能会导致DirectInput和键盘句柄处于未知状态,这对于老的Windows来说是不友好的,虽然现代的Windows会自动处理

    2.4 获取键盘的输入

    通过GetDeviceState来获设备的输入,无论什么输入设备,它都是一个标准

    HRESULT GetDeviceState(
             DWORD cbData, 
             LPVOID lpvData
    )
    

    对于键盘,需要定义键的数组:

    // 对应于cbData,sizeof(keys)
    // 对应于lpvData,(LPVOID)&keys
    char keys[256]; 
    

    检查keys数组中的数据方法如下:

    if (key[DIK_A] & 0x80){
    	// do samething
    }
    

    2.6 获取键盘输入的完整版

    完整的获取键盘输入的程序如下:

    bool init_input(HWND  window){
    	// 初始化DirectInput
    	HRESULT result = DirectInput8Create(
    		GetModuleHandle(NULL),
    		DIRECTINPUT_VERSION,
    		IID_IDirectInput8,
    		(void **)&dinput,
    		NULL
    		);
    	if (result != DI_OK) return false;
    
    	// 创建DirectInput的keyboard
    	result = dinput->CreateDevice(GUID_SysKeyboard, &dikeyboard, NULL);
    	if (result != D3D_OK) return false;
    
    	// 设置数据格式
    	result = dikeyboard->SetDataFormat(&c_dfDIKeyboard);
    	if (result != DI_OK) return false;
    
    	// 设置协作级别
    	result = dikeyboard->SetCooperativeLevel(window,DISCL_NONEXCLUSIVE|DISCL_FOREGROUND);
    	if (result != DI_OK) return false;
    
    	// 获取设备
    	result = dikeyboard->Acquire();
    	if (result != DI_OK) return false;
    
    	return true;
    }
    
    //响应键盘输入
    void key_update(){
    	LRESULT result = dikeyboard->GetDeviceState(sizeof(keys), (LPVOID)(&keys));
    	if (result != DI_OK) return;
    	if (keys[DIK_A] & 0x80){
    		X--;
    	}
    	else if (keys[DIK_S] & 0x80){
    		Y++;
    	}
    	else if (keys[DIK_D] & 0x80){
    		X++;
    	}
    	else if (keys[DIK_W] & 0x80){
    		Y--;
    	}
    }
    

    3. 初始化鼠标

    了解了初始化键盘的机制后,初始化鼠标显得就很简单了,在读取鼠标输入前,大都只是传入一个区别于键盘的标识而已,不一样的我会用[异]标注一下

    	ZeroMemory(keys, sizeof(keys));
    	// 初始化DirectInput
    	HRESULT result = DirectInput8Create(
    		GetModuleHandle(NULL),
    		DIRECTINPUT_VERSION,
    		IID_IDirectInput8,
    		(void **)&dinput,
    		NULL
    		);
    	if (result != DI_OK) return false;
    
    	// 创建DirectInput的mouse对象
    	result = dinput->CreateDevice(GUID_SysMouse[异], &dimouse, NULL);
    	if (result != D3D_OK) return false;
    
    	// 设置数据格式
    	result = dimouse->SetDataFormat(&c_dfDIMouse[异]);
    	if (result != DI_OK) return false;
    
    	// 设置协作级别
    	result = dimouse->SetCooperativeLevel(window, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
    	if (result != DI_OK) return false;
    
    	// 获取设备
    	result = dimouse->Acquire();
    	if (result != DI_OK) return false;
    

    3.1 获取鼠标的输入

    同样是使用GetDeviceState这个标准的获取函数,但是获取的数据变了,是:

    DIMOUSESTATE mouse_state;
    

    也可以使用DIMOUSESTATE2,它能够获取更多的按键

    获取函数如下:

    result = dimouse->GetDeviceState(sizeof(mouse_state), (LPVOID)&mouse_state);
    

    这里值得注意的是,在DIMOUSESTATE结构中:

    typedef struct _DIMOUSESTATE {
        LONG    lX;
        LONG    lY;
        LONG    lZ;
        BYTE    rgbButtons[4];
    } 
    

    lXlYlZ都只是相对于上一帧鼠标的相对移动坐标,在rgbButtons
    rgbButtons[0]是鼠标左单击,
    rgbButtons[1]是鼠标左单击,
    rgbButtons[2]是鼠标滑轮按下
    判断获取输入的代码如下:

    if(mouse_state.rgbButtons[0] & 0x80) 
    {
    	//do samething
    }
    
  • 相关阅读:
    Java基础——字符编码
    三:简单工厂模式
    二:代理模式(静态代理,动态代理)
    一:设计者模式六大原则和单例模式
    java源码
    JDK8新特性 -- Function接口: apply,andThen,compose
    JDK8新特性:Lambda表达式
    Java同步的三种实现方式
    spring boot注解和启动
    springboot:基础学习一 linux下后台启动springboot项目
  • 原文地址:https://www.cnblogs.com/leihui/p/8904025.html
Copyright © 2020-2023  润新知