Beginners Direct X (3)

Beginners Direct X (3)


1. Get peripheral input - keyboard and mouse

Whether it is to obtain a mouse or keyboard device, you must first initialize DirectInput, but first configure the necessary environment:
the header files and library files to be used are (compared to the previous two):

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

And the DirectInput objects and device (including keyboard and mouse) objects to be used:

LPDIRECTINPUT8 dinput;
LPDIRECTINPUTDEVICE8A dikeyboard;
LPDIRECTINPUTDEVICE8A dimouse;

Start to initialize DirectInput after preparation:

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

Here is an example of a call:

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

At this point, the initialization of DirectInput has been completed

2. Initialize the keyboard

After initializing DirectInput, you can create a keyboard device by calling the CreateDevice function

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

REFGUID : Specifies the type of object to create, such as keyboard or mouse, the keyboard is GUID_SysKeyboard, the mouse is GUID_SysMouse
lplpDirectInputDevice : The address of the device that receives the DirectInput device handle
pUnkouter : always NULL

2.1 Set the data format

This step is to set the data format of the keyboard and tell DirectInput how to pass the data to the program. This is a unified reading method for various input devices on the market.

HRESULT SetDataFormat(
        LPCDIDATAFORMAT lpdf
)

lpdf : We don't need to define it ourselves, it is defined in dinput, c_dfDIKeyboard for the keyboard, c_dfDIMouse for the mouse

2.2 Setting the collaboration level

This step is to set the cooperation level, which determines the priority of DirectInput to pass keyboard input to the program

HRESULT SetCooperativeLevel(
         HWND hwnd,
         DWORD  
)

dwFlags : The most commonly used is DISCL_NONEXCLUSIVE | DISCL_FOREGROUND

2.3 Get the device

This step is also a harvest step, which is to use Acquire to obtain the device

HRESULT Acquire()

If you don't use Unacquire() to release the device at the end of the program, it may cause DirectInput and keyboard handles to be in an unknown state, which is not friendly to old Windows, although modern Windows will automatically handle this.

2.4 Get keyboard input

Get the input of the device through GetDeviceState, no matter what the input device is, it is a standard

HRESULT GetDeviceState(
         DWORD cbData, 
         LPVOID lpvData
)

For the keyboard, an array of keys needs to be defined:

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

Check the data in the keys array as follows:

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

2.6 Get the full version of keyboard input

The complete procedure for getting keyboard input is as follows:

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. Initialize the mouse

After understanding the mechanism of initializing the keyboard, initializing the mouse seems to be very simple. Before reading the mouse input, most of them just pass in a logo that is different from the keyboard. If they are different, I will mark them with [different].

    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 Get mouse input

It also uses the standard acquisition function GetDeviceState, but the acquired data has changed, it is:

DIMOUSESTATE mouse_state;

You can also use DIMOUSESTATE2, which gets more keys

The get function is as follows:

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

It's worth noting here that in the DIMOUSESTATE structure:

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

lX , lY , lZ are only relative movement coordinates relative to the previous frame of the mouse. In rgbButtons ,
rgbButtons[0] is the left mouse click,
rgbButtons[1] is the left mouse click, and
rgbButtons[2] is the mouse wheel down
The code for judging to get the input is as follows:

if(mouse_state.rgbButtons[0] & 0x80) 
{
    //do samething
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324620083&siteId=291194637