Raw input mouse windows

About Raw Input

There are many user-input devices beside the traditional keyboard and mouse. For example, user input can come from a joystick, a touch screen, a microphone, or other devices that allow great flexibility in user input. These devices are collectively known as Human Interface Devices (HIDs). The raw input API provides a stable and robust way for applications to accept raw input from any HID, including the keyboard and mouse.

This section covers the following topics:

Raw Input Model

Previously, the keyboard and mouse typically generated input data. The system interpreted the data coming from these devices in a way that eliminated the device-specific details of the raw information. For example, the keyboard generates the device-specific scan code but the system provides an application with the virtual key code. Besides hiding the details of the raw input, the window manager did not support all the new HIDs. To get input from the unsupported HIDs, an application had to do many things: open the device, manage the shared mode, periodically read the device or set up the I/O completion port, and so forth. The raw input model and the associated APIs were developed to allow simple access to raw input from all input devices, including the keyboard and mouse.

The raw input model is different from the original Windows input model for the keyboard and mouse. In the original input model, an application receives device-independent input in the form of messages that are sent or posted to its windows, such as WM_CHAR, WM_MOUSEMOVE, and WM_APPCOMMAND. In contrast, for raw input an application must register the devices it wants to get data from. Also, the application gets the raw input through the WM_INPUT message.

There are several advantages to the raw input model:

  • An application does not have to detect or open the input device.
  • An application gets the data directly from the device, and processes the data for its needs.
  • An application can distinguish the source of the input even if it is from the same type of device. For example, two mouse devices.
  • An application manages the data traffic by specifying data from a collection of devices or only specific device types.
  • HID devices can be used as they become available in the marketplace, without waiting for new message types or an updated OS to have new commands in WM_APPCOMMAND.

Note that WM_APPCOMMAND does provide for some HID devices. However, WM_APPCOMMAND is a higher level device-independent input event, while WM_INPUT sends raw, low level data that is specific to a device.

Registration for Raw Input

By default, no application receives raw input. To receive raw input from a device, an application must register the device.

To register devices, an application first creates an array of RAWINPUTDEVICE structures that specify the top level collection (TLC) for the devices it wants. The TLC is defined by a Usage Page (the class of the device) and a Usage ID (the device within the class). For example, to get the keyboard TLC, set UsagePage = 0x01 and UsageID = 0x06. The application calls RegisterRawInputDevices to register the devices.

Читайте также:  Как работать с vpn windows 10

Note that an application can register a device that is not currently attached to the system. When this device is attached, the Windows Manager will automatically send the raw input to the application. To get the list of raw input devices on the system, an application calls GetRawInputDeviceList. Using the hDevice from this call, an application calls GetRawInputDeviceInfo to get the device information.

Through the dwFlags member of RAWINPUTDEVICE, an application can select the devices to listen to and also those it wants to ignore. For example, an application can ask for input from all telephony devices except for answering machines. For sample code, see Registering for Raw Input.

Note that the mouse and the keyboard are also HIDs, so data from them can come through both the HID message WM_INPUT and from traditional messages. An application can select either method by the proper selection of flags in RAWINPUTDEVICE.

To get an application’s registration status, call GetRegisteredRawInputDevices at any time.

Reading Raw Input

An application receives raw input from any HID whose top level collection (TLC) matches a TLC from the registration. When an application receives raw input, its message queue gets a WM_INPUT message and the queue status flag QS_RAWINPUT is set (QS_INPUT also includes this flag). An application can receive data when it is in the foreground and when it is in the background.

There are two ways to read the raw data: the unbuffered (or standard) method and the buffered method. The unbuffered method gets the raw data one RAWINPUT structure at a time and is adequate for many HIDs. Here, the application calls GetMessage to get the WM_INPUT message. Then the application calls GetRawInputData using the RAWINPUT handle contained in WM_INPUT. For an example, see Doing a Standard Read of Raw Input.

In contrast, the buffered method gets an array of RAWINPUT structures at a time. This is provided for devices that can produce large amounts of raw input. In this method, the application calls GetRawInputBuffer to get an array of RAWINPUT structures. Note that the NEXTRAWINPUTBLOCK macro is used to traverse an array of RAWINPUT structures. For an example, see Doing a Buffered Read of Raw Input.

To interpret the raw input, detailed information about the HIDs is required. An application gets the device information by calling GetRawInputDeviceInfo with the device handle. This handle can come either from WM_INPUT or from the hDevice member of RAWINPUTHEADER.

Raw input mouse windows

No answers till today? A shame. I’ll give it a try, and if just for those who came here because they stumbled over the same question:

So, what’s what and what’s best? Depends on your mouse. Raw Input is best, as the name implies: it’s the pure data from your mouse, what it doesn’t say is, it’s without Windows meddling in the mouse input data. Thus «Raw». Contrary to «Windows Mouse», it’s the exact opposite: Now Windows does alter your mouse inputs, in fact the way you’ve or haven’t set it in your Windows settings. Not in the game settings.

Читайте также:  Microsoft edge windows 10 переустановка

But even if you haven’t set anything there, you should go there, asa general advice, and turn all Windows mouse acceleration/smoothing stuff off. For gaming. Because not all games offer «raw input» mouse settings and can therefore circumvent the Windows mouse settings.

But in case of RDR2 you can also just choose «raw input» and you are good to go and will get everything what your mouse is capable of. Unaltered. Hence I said it depends on your mouse, because if the mouse is crap, the input will be crap too. Self-explanatory, right?

And «Direct Input» is for controllers. DirectInput is also Microsoft’s controller API, but a deprecated legacy API. You want to choose this method if you use a controller with force feedback/rumble functions and whatnot, because these may stop working when you chose «raw input». Also, when you have trouble with your mouse in «raw input», jittering, lags or whatever, then try «directinput», that might be your best choice then.

As I said above, it depends on your mouse, or, more generally spoken: on your control devices.

Try «raw input» and then compare it to the other settings. If «raw input» worked flawlessly, then everything seems fine. If you feel the mouse is more responsive in «direct input», well, then this is the best method for your mouse. And as for Windows. it heavily depends on what you have set there in Windows’ mouse settings in the first place. So, if those are already crap, then don’t blame RDR2 for inputs that don’t feel right ingame. 😉

luluco250 / MouseRaw.cpp

/*
Example of how to get raw mouse input data using the native Windows API
through a «message-only» window that outputs to an allocated console window.
Not prepared for Unicode.
I don’t recommend copy/pasting this, understand it before integrating it.
*/
// Make Windows.h slightly less of a headache.
# define NOMINMAX
# define WIN32_LEAN_AND_MEAN
# define VC_EXTRALEAN
# include Windows.h >
// Only for redirecting stdout to the console.
# include cstdio >
# include iostream >
// Structure to store out input data.
// Not necessary, I just find it neat.
struct <
struct <
// Keep in mind these are all deltas,
// they’ll change for one frame/cycle
// before going back to zero.
int x = 0 ;
int y = 0 ;
int wheel = 0 ;
> mouse;
> input;
// Window message callback.
LRESULT CALLBACK EventHandler (HWND, unsigned , WPARAM, LPARAM);
// Clear the console window.
void ClearConsole ();
// Make sure to set the entrypoint to «mainCRTStartup», or change this to WinMain.
int main () <
// Why even bother with WinMain?
HINSTANCE instance = GetModuleHandle ( 0 );
// Make std::cout faster:
std::ios_base::sync_with_stdio ( false );
// Get console window:
FILE* console_output;
FILE* console_error;
if ( AllocConsole ()) <
freopen_s (&console_output, » CONOUT$ » , » w » , stdout);
freopen_s (&console_error, » CONERR$ » , » w » , stderr);
> else <
return — 1 ;
>
// Create message-only window:
const char * class_name = » SimpleEngine Class » ;
// «<>» is necessary, otherwise we have to use ZeroMemory() (which is just memset).
WNDCLASS window_class = <>;
window_class. lpfnWndProc = EventHandler;
window_class. hInstance = instance;
window_class. lpszClassName = class_name;
if (! RegisterClass (&window_class))
return — 1 ;
HWND window = CreateWindow (class_name, » SimpleEngine » , 0 , 0 , 0 , 0 , 0 , HWND_MESSAGE, 0 , 0 , 0 );
if (window == nullptr )
return — 1 ;
// End of creating window.
// Registering raw input devices
# ifndef HID_USAGE_PAGE_GENERIC
# define HID_USAGE_PAGE_GENERIC (( unsigned short ) 0x01 )
# endif
# ifndef HID_USAGE_GENERIC_MOUSE
# define HID_USAGE_GENERIC_MOUSE (( unsigned short ) 0x02 )
# endif
// We’re configuring just one RAWINPUTDEVICE, the mouse,
// so it’s a single-element array (a pointer).
RAWINPUTDEVICE rid[ 1 ];
rid[ 0 ]. usUsagePage = HID_USAGE_PAGE_GENERIC;
rid[ 0 ]. usUsage = HID_USAGE_GENERIC_MOUSE;
rid[ 0 ]. dwFlags = RIDEV_INPUTSINK;
rid[ 0 ]. hwndTarget = window;
RegisterRawInputDevices (rid, 1 , sizeof (rid[ 0 ]));
// End of resgistering.
// Main loop:
MSG event;
bool quit = false ;
while (!quit) <
while ( PeekMessage (&event, 0 , 0 , 0 , PM_REMOVE)) <
if (event. message == WM_QUIT) <
quit = true ;
break ;
>
// Does some Windows magic and sends the message to EventHandler()
// because it’s associated with the window we created.
TranslateMessage (&event);
DispatchMessage (&event);
>
// Output mouse input to console:
std::cout » Mouse input: ( » mouse . x ;
std::cout » , » mouse . y ;
std::cout » , » mouse . wheel » ) \n » ;
// Sleep a bit so that console output can be read.
Sleep ( 100 );
// . before clearing the console:
ClearConsole ();
// Reset mouse data in case WM_INPUT isn’t called:
input. mouse . x = 0 ;
input. mouse . y = 0 ;
input. mouse . wheel = 0 ;
>
fclose (console_output);
fclose (console_error);
return 0 ;
>
LRESULT CALLBACK EventHandler (
HWND hwnd,
unsigned event,
WPARAM wparam,
LPARAM lparam
) <
switch (event) <
case WM_DESTROY:
PostQuitMessage ( 0 );
return 0 ;
case WM_INPUT: <
// The official Microsoft examples are pretty terrible about this.
// Size needs to be non-constant because GetRawInputData() can return the
// size necessary for the RAWINPUT data, which is a weird feature.
unsigned size = sizeof (RAWINPUT);
static RAWINPUT raw[ sizeof (RAWINPUT)];
GetRawInputData ((HRAWINPUT)lparam, RID_INPUT, raw, &size, sizeof (RAWINPUTHEADER));
if (raw-> header . dwType == RIM_TYPEMOUSE) <
input. mouse . x = raw-> data . mouse . lLastX ;
input. mouse . y = raw-> data . mouse . lLastY ;
// Wheel data needs to be pointer casted to interpret an unsigned short as a short, with no conversion
// otherwise it’ll overflow when going negative.
// Didn’t happen before some minor changes in the code, doesn’t seem to go away
// so it’s going to have to be like this.
if (raw-> data . mouse . usButtonFlags & RI_MOUSE_WHEEL)
input. mouse . wheel = (*( short *)&raw-> data . mouse . usButtonData ) / WHEEL_DELTA;
>
> return 0 ;
>
// Run default message processor for any missed events:
return DefWindowProc (hwnd, event, wparam, lparam);
>
void ClearConsole () <
static const COORD top_left = < 0 , 0 >;
CONSOLE_SCREEN_BUFFER_INFO info;
HANDLE console = GetStdHandle (STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo (console, &info);
DWORD written, cells = info. dwSize . X * info. dwSize . Y ;
FillConsoleOutputCharacter (console, ‘ ‘ , cells, top_left, &written);
SetConsoleCursorPosition (console, top_left);
>
Читайте также:  Как вызвать меню bios windows 10

You can’t perform that action at this time.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

Оцените статью