gpt4 book ai didi

winapi - 正确使用 GetRawInputBuffer

转载 作者:行者123 更新时间:2023-12-04 05:44:27 26 4
gpt4 key购买 nike

我正在尝试使用 Win32 原始输入 API 以更高的精度收集原始鼠标数据,但我似乎无法理解 documentation and samples完全为GetRawInputBuffer .

当我的鼠标悬停在窗口上时,似乎什么也没发生。当我在窗口的标题栏上单击或释放时,我似乎只得到缓冲的数据,即使如此,我也大多得到 0 移动值并且从不接收鼠标按钮的更改。我尽可能密切地跟踪样本,并且在网上搜索几乎没有运气。

下面是一个非常简化的例子的窗口过程和主要的问题。

LRESULT CALLBACK MessageHandler(HWND WindowHandle, UINT Message, WPARAM wParameter, LPARAM lParameter)
{
switch(Message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
break;
case WM_CLOSE:
{
DestroyWindow(WindowHandle);
return 0;
}
break;
case WM_INPUT:
{
UINT RawInputSize;
UINT Result;

Result = GetRawInputBuffer(NULL, &(RawInputSize), sizeof(RAWINPUTHEADER));
if(Result == -1)
{
DWORD ErrorCode = GetLastError();
std::cout << "GetRawInputBuffer returned error code" << ErrorCode << std::endl;
}
else if(Result == 0 && RawInputSize != 0)
{
UINT AllocatedBufferByteCount = RawInputSize * 16;
RAWINPUT* RawInputBuffer = reinterpret_cast<RAWINPUT*>(malloc(AllocatedBufferByteCount));

UINT AllocatedBufferByteCountTwo = AllocatedBufferByteCount;
Result = GetRawInputBuffer(RawInputBuffer, &(AllocatedBufferByteCountTwo), sizeof(RAWINPUTHEADER));
if(Result == -1)
{
DWORD ErrorCode = GetLastError();
std::cout << "GetRawInputBuffer returned error code" << ErrorCode << std::endl;
}
else if(Result != 0)
{
UINT RawInputCount = Result;

DWORD MouseDeltaX = 0;
DWORD MouseDeltaY = 0;

bool ButtonsPressed[2] = {false, false};

RAWINPUT* RawInput = RawInputBuffer;
for(unsigned int i = 0; i < RawInputCount; ++i)
{
switch(RawInput->header.dwType)
{
// Raw mouse movement data for high-resolution mice.
case RIM_TYPEMOUSE:
{
MouseDeltaX += RawInput->data.mouse.lLastX;
MouseDeltaY += RawInput->data.mouse.lLastY;

ButtonsPressed[0] = ((RawInput->data.mouse.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) == RI_MOUSE_LEFT_BUTTON_DOWN);
ButtonsPressed[1] = ((RawInput->data.mouse.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) == RI_MOUSE_RIGHT_BUTTON_DOWN);
}
break;
}

RawInput = NEXTRAWINPUTBLOCK(RawInput);
}
DefRawInputProc(&(RawInputBuffer), RawInputCount, sizeof(RAWINPUTHEADER));
std::cout << "Mouse moved (" << MouseDeltaX << ", " << MouseDeltaY << ")." << std::endl;

if(ButtonsPressed[0])
{
std::cout << "LMB pressed." << std::endl;
}
if(ButtonsPressed[1])
{
std::cout << "RMB pressed." << std::endl;
}
}

free(RawInputBuffer);
}
return 0;
}
break;
default:
{
return DefWindowProc(WindowHandle, Message, wParameter, lParameter);
}
break;
}
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
// Initialize window strings.
wchar_t WindowClassName[] = L"DominionWindowClass";
wchar_t WindowCaption[] = L"Test Window";

// Create the window class.
WNDCLASSEX WindowClass;
WindowClass.cbSize = sizeof(WindowClass);
WindowClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
WindowClass.lpfnWndProc = &(MessageHandler);
WindowClass.cbClsExtra = 0;
WindowClass.cbWndExtra = 0;
WindowClass.hInstance = hInstance;
WindowClass.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
WindowClass.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WindowClass.hbrBackground = NULL;
WindowClass.lpszMenuName = NULL;
WindowClass.lpszClassName = WindowClassName;

// Register window class.
RegisterClassEx(&WindowClass);

// Setup window style flags.
DWORD WindowStyles = WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU;
DWORD ExWindowStyles = WS_EX_APPWINDOW;

// Setup window rectangle area.
RECT WindowArea;
WindowArea.left = 0;
WindowArea.top = 0;
WindowArea.right = 1024;
WindowArea.bottom = 768;

AdjustWindowRectEx(&(WindowArea), WindowStyles, false, ExWindowStyles);

// Window creation.
HWND WindowHandle = CreateWindowEx(ExWindowStyles, WindowClass.lpszClassName, WindowCaption, WindowStyles, CW_USEDEFAULT, CW_USEDEFAULT, (WindowArea.right - WindowArea.left), (WindowArea.bottom - WindowArea.top), NULL, NULL, hInstance, NULL);

// Display the window.
ShowWindow(WindowHandle, SW_SHOWDEFAULT);
UpdateWindow(WindowHandle);

// Register devices for raw input.
const unsigned int RawInputDeviceCount = 1;
RAWINPUTDEVICE RawInputDevices[RawInputDeviceCount];

memset(RawInputDevices, 0, RawInputDeviceCount * sizeof(RAWINPUTDEVICE));

RAWINPUTDEVICE* MouseRawInputDevice;

MouseRawInputDevice = RawInputDevices;
MouseRawInputDevice->usUsagePage = 1;
MouseRawInputDevice->usUsage = 2;
MouseRawInputDevice->hwndTarget = WindowHandle;

BOOL SuccessfullyRegisteredInput = RegisterRawInputDevices(RawInputDevices, RawInputDeviceCount, sizeof(RAWINPUTDEVICE));

// Core loop.
MSG Message;
for(;;)
{
while(PeekMessage(&Message, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
if(Message.message == WM_QUIT)
{
break;
}
}

if(Message.message == WM_QUIT)
{
break;
}
}

// Unregister devices for raw input.
memset(RawInputDevices, 0, RawInputDeviceCount * sizeof(RAWINPUTDEVICE));
MouseRawInputDevice = RawInputDevices;
MouseRawInputDevice->usUsagePage = 1;
MouseRawInputDevice->usUsage = 2;
MouseRawInputDevice->dwFlags = RIDEV_REMOVE;
MouseRawInputDevice->hwndTarget = NULL;

BOOL SuccessfullyUnregisteredInput = RegisterRawInputDevices(RawInputDevices, RawInputDeviceCount, sizeof(RAWINPUTDEVICE));

return Message.wParam;
}

我想不出更简单的方法来试验原始输入 API。想法?

最佳答案

迟到的答案,但 GetRawInputBuffer似乎用于消息处理循环之外的轮询。使用 GetRawInputDataWM_INPUT处理或使用 GetRawInputBuffer在消息处理循环之外。

关于winapi - 正确使用 GetRawInputBuffer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10866226/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com