想通过DirectInput对joystick信息收集的方式进行收集,参考了论坛中
Thrustmaster Hotas Warthog/猪杆/疣猪飞行操作杆开发
这篇帖子,发现枚举函数总是无法枚举到设备,由于小白半路出家找不到问题所在,特来求教一下。
代码如下:
#define DIRECTINPUT_VERSION 0x0800
#include <windows.h>
#include <stdio.h>
#include <dinput.h>
#include "resource.h"
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "dinput8.lib")
#pragma warning(disable : 4996)
#define Safe_Release(p) if((p)) (p)->Release();
// window handles, class and caption text.
HWND g_hwnd;
char g_class_name[] = "JoystickClass";
IDirectInput8* g_directinput; // directinput component
IDirectInputDevice8* g_enum_joystick; // enum joystick device 枚举设备接口
IDirectInputDevice8* g_joystick; // joystick device 设备接口
//--------------------------------------------------------------------------------
// Window procedure.
//--------------------------------------------------------------------------------
long WINAPI Window_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return (long)DefWindowProc(hwnd, msg, wParam, lParam);
}
//--------------------------------------------------------------------------------
// 回调函数enum_joysticks的定义,当枚举到对应的设备之后,就调用对应的回调函数来对其进行初始化配置。
//--------------------------------------------------------------------------------
BOOL CALLBACK enum_joysticks(LPCDIDEVICEINSTANCE device_inst, LPVOID ref)
{
g_enum_joystick = NULL;
//使用全局DirectInput对象创建设d备对象
if (FAILED(g_directinput->CreateDevice(device_inst->guidInstance, &g_enum_joystick, NULL)))
//调用IDirectInput8::CreateDevice 创建全局的设备COM对象
return DIENUM_CONTINUE;
// set the data format
if (FAILED(g_enum_joystick->SetDataFormat(&c_dfDIJoystick2)))//设置数据格式
{
g_enum_joystick->Release();
g_enum_joystick = NULL;
return DIENUM_CONTINUE;
}
// set the cooperative mode
if (FAILED(g_enum_joystick->SetCooperativeLevel(g_hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
//设置协作等级
{
g_enum_joystick->Release();
g_enum_joystick = NULL;
return DIENUM_CONTINUE;
}
// acquire the device for use
if (FAILED(g_enum_joystick->Acquire()))//获取控制权
{
g_enum_joystick->Release();
g_enum_joystick = NULL;
return DIENUM_CONTINUE;
}
// stop enumeration
return DIENUM_STOP;
}
//--------------------------------------------------------------------------------
// init_joystick函数的定义,封装好了对接口的所有配置。
//--------------------------------------------------------------------------------
IDirectInputDevice8* Init_joystick(HWND hwnd, IDirectInput8* directinput)
{
directinput->EnumDevices(DI8DEVTYPE_JOYSTICK, enum_joysticks, NULL, DIEDFL_ALLDEVICES);
return g_enum_joystick;
}
//--------------------------------------------------------------------------------
//读取设备状态。
//--------------------------------------------------------------------------------
BOOL Read_Device(IDirectInputDevice8* directinput_device, void* buffer, long buffer_size)
{
HRESULT rv;
while (1)
{
// poll device
g_joystick->Poll();
g_joystick->Acquire();
// read in state
if (SUCCEEDED(rv = g_joystick->GetDeviceState(buffer_size, buffer)))
break;
// return when an unknown error
if (rv != DIERR_INPUTLOST || rv != DIERR_NOTACQUIRED)
return FALSE;
// re-acquire and try again
if (FAILED(g_joystick->Acquire()))
return FALSE;
}
return TRUE;
}
//--------------------------------------------------------------------------------
// 主函数
//--------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
{
WNDCLASS win_class;
MSG msg;
DIJOYSTATE2 joy_state = { 0 };
char text[256];
long x_pos = 0, y_pos = 0;
// create window class and register it
win_class.style = CS_HREDRAW | CS_VREDRAW;
win_class.lpfnWndProc = Window_Proc;
win_class.cbClsExtra = 0;
win_class.cbWndExtra = DLGWINDOWEXTRA;
win_class.hInstance = inst;
win_class.hIcon = LoadIcon(inst, IDI_APPLICATION);
win_class.hCursor = LoadCursor(NULL, IDC_ARROW);
win_class.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
win_class.lpszMenuName = NULL;
win_class.lpszClassName = g_class_name;
if (!RegisterClass(&win_class))
return FALSE;
// create the main window
g_hwnd = CreateDialog(inst, MAKEINTRESOURCE(IDD_MOUSE), 0, NULL);
ShowWindow(g_hwnd, cmd_show);
UpdateWindow(g_hwnd);
// initialize directinput and get keyboard device
DirectInput8Create(inst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)& g_directinput, NULL);
// initialize mouse
g_joystick = Init_joystick(g_hwnd, g_directinput);
// start message pump, waiting for signal to quit.
ZeroMemory(&msg, sizeof(MSG));
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// read in mouse and display coordinates
Read_Device(g_joystick, &joy_state, sizeof(DIMOUSESTATE));
x_pos += joy_state.lX;
y_pos += joy_state.lY;
if (joy_state.lX != 0 || joy_state.lY != 0)
{
sprintf(text, "%ld, %ld", x_pos, y_pos);
SetWindowText(GetDlgItem(g_hwnd, IDC_COORDINATES), text);
}
}
// release directinput objects
g_joystick->Unacquire();
g_joystick->Release();
g_directinput->Release();
UnregisterClass(g_class_name, inst);
return (int)msg.wParam;
}