I’ve been working on a little project to involves raw mouse support lately. If you haven’t ever heard of raw mouse, don’t feel too bad. It’s a pretty esoteric part of Windows that’s been around since the XP (and possibly earlier) days, but isn’t widely used.
Essentially, it’s trivially easy to plug a second mouse into your computer and just use it. The cursor onscreen reacts to both mice equally, and usually, that’s exactly what you want.
However, what if it’s not?
What if you’re working on a game and you want to be able to see each mouse’s input independently? Windows does such a good job of hiding the mouse plumbing that doing so is impossible using standard mouse access techniques. Even DirectInput can’t do it, although you’d sure swear that a function like this:
Manager.GetDevices(DeviceClass.Pointer, EnumDevicesFlags.AttachedOnly)
shouldn’t have any problems doing so (it doesn’t work, I tried it!)
RawMouse to the Rescue
Turns out, you CAN get at multiple mice independently through the lower level mouse support functions, call the RawMouse layer. Essentially, the way it works is you register a window handle to receive RawMouse messages and then you react to those messages appropriately. But a full discussion of RawMouse will have to wait for another day.
In any case, you’ll be dealing with raw Windows Message blocks and it’s often not particularly easy for .Net languages to directly parse those blocks.
Or is it?
Comparing
At one point, I needed to compare an Int32 value (a signed 32bit integer value) to a UInt32 value (an unsigned 32 bit integer). Sounds straightforward, and often, a simple CType will work. But if the UInt32 value is greater than 2^30, it’ll overflow if you try to use CType on it (unlike C#, where a cast from UInt32 to Int32 just works, sigh).
I knew the Marshal class had all sorts of functions for doing manipulation like this, but in searching around, I was reminded of a little trick I used quite some time ago, when I was first getting into .net, and which had subsequently exited from my consciousness.
It turns out that the Imports System.Runtime.InteropServices namespace includes several attributes that control the layout of structures.
The two in particular we’re interested in is
- <StructLayout(LayoutKind.Explicit)>
- <FieldOffset(0)>
The StructLayout attribute is applied to the entire structure and it basically says that you the programmer will be explicitly determining the positioning of the fields (members) of the structure.
The FieldOffset atttribute, on the other hand, is applied to each field in the structure and determines where (using a 0 based offset in bytes) in the entire block of memory that defines the structure, that particular field will be located.
When you put it all together, you get a structure like this:
<StructLayout(LayoutKind.Explicit)> _ Public Structure UnionInt32 <FieldOffset(0)> _ Public Int32Value As Int32 <FieldOffset(0)> _ Public UInt32Value As UInt32 End Structure
Which, when put simply, just accesses the first 4 bytes of the structure (due to the FieldOffset of both fields set to 0) as either an Int32 value or a UInt32 value.
Using it couldn’t be simpler (or faster).
Dim v as Int32 = -1234 Dim u as UnionInt32 u.Int32Value = v debug.print u.UInt32Value
The V variable contains your starting signed value, and the debug.print outputs the equivalent unsigned value.
Using this trick can be a godsend when working directly with low level Windows messages (like the RawMouse messages!)