How to differenciate mousemove inputs of multiple mouse devices? - c#

I have a mouse and a touchpad on my laptop. I want a global hook for mousemove that tells me not only the new position, but also the physical device where it came from. Subscribing the hook only to the touchpad would be an even better solution, since I'm only interested in the touchpad. The hook has to work system wide (even if my application is not in focus).
How can I do this?
I'm not afraid to use Pinvoke in my C#/WPF application

You could use
P-Invoke user32.getrawinputdeviceinfo .
For mouse input you can get thing such:
[StructLayout(LayoutKind.Sequential)]
internal struct RID_DEVICE_INFO_MOUSE
{
[MarshalAs(UnmanagedType.U4)]
public int dwId;
[MarshalAs(UnmanagedType.U4)]
public int dwNumberOfButtons;
[MarshalAs(UnmanagedType.U4)]
public int dwSampleRate;
[MarshalAs(UnmanagedType.U4)]
public int fHasHorizontalWheel;
}
and, about Device:
StructLayout(LayoutKind.Sequential)]
internal struct RID_DEVICE_INFO_HID
{
[MarshalAs(UnmanagedType.U4)]
public int dwVendorId;
[MarshalAs(UnmanagedType.U4)]
public int dwProductId;
[MarshalAs(UnmanagedType.U4)]
public int dwVersionNumber;
[MarshalAs(UnmanagedType.U2)]
public ushort usUsagePage;
[MarshalAs(UnmanagedType.U2)]
public ushort usUsage;
}

Related

In C#, given an intptr to a window handle, how do I measure this window handle's true height using scrollinfo

I have a sub-window within a scroll window in a separate application. I am attempting to use a C# console application to inspect that scroll-window's true height (not its on screen height, but the height in pixels of how many pixels can be scrolled). I know using the existing user32.dll libs I can ask for a scroll info but that gives me details about the scrollbar itself, the scrollbar's height and position, but it doesn't give me the total pixels that the scrollbar would scroll through.
[DllImport("User32.dll")]
private static extern bool GetScrollInfo(IntPtr hwnd, int fnBar, ref ScrollInfo lpsi);
Is there a way I can use the scrollinfo returned by the above method to derive the actual pixels of the scrollable area?
public struct ScrollInfo
{
public uint cbSize;
public uint fMask;
public int nMin;
public int nMax;
public uint nPage;
public int nPos;
public int nTrackPos;
}

disabling AF programmatically?

I have a EOS 1100D and use edsdk to taking picture by my camera from my computer.
in Manual mode I should can chand every properties, and in EOS Utility that is released by Canon, in Manual mode, user can switch between AF and MF. So, there should be a property!
What I found in EDSDK.cs is:
/*---------------------------------------------
Focus Info
----------------------------------------------*/
[StructLayout(LayoutKind.Sequential)]
public struct EdsFocusPoint
{
public uint valid;
public uint selected;
public uint justFocus;
public EdsRect rect;
public uint reserved;
}
[StructLayout(LayoutKind.Sequential)]
public struct EdsFocusInfo
{
public EdsRect imageRect;
public uint pointNumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public EdsFocusPoint[] focusPoint;
public uint executeMode;
}
How can I set this executeMode?
In fact, I should set in to what for AF and what for MF?
you can do this with EdsSendCommand where inCommand is kEdsCameraCommand_PressShutterButton and inParam is one of the kEdsCameraCommand_ShutterButton_ values.
With it you can control the shutterbutton (i.e. press it remotely).
To take a photo without AF, you simply use the value CameraCommand_ShutterButton_Completely_NonAF
But don't forget to set it back to CameraCommand_ShutterButton_OFF after you have taken the photo!
In the EDSDK documentation you can find details on page 42 and 43.

Send Shift/Alt/Ctrl in SendInput

I'm writing a controller program, which simulates keystrokes to any active application. I found the SendInput method like this(I only care for keyboard, so irrelevant definitions omitted):
[StructLayout(LayoutKind.Explicit)]
public struct INPUT
{
[FieldOffset(0)]
public Int32 type;
[FieldOffset(4)]
public KEYBDINPUT ki;
[FieldOffset(4)]
public MOUSEINPUT mi;
[FieldOffset(4)]
public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
public struct KEYBDINPUT
{
public Int16 wVk;
public Int16 wScan;
public Int32 dwFlags;
public Int32 time;
public IntPtr dwExtraInfo;
}
[DllImport("user32.dll")]
public static extern UInt32 SendInput(UInt32 nInputs, ref INPUT pInputs, int cbSize);
I know the wVk and wScan can be assigned by a System.Windows.Forms.Keys enumation value. I also looked at the values, and found Shift=65536, Control=131072, Alt=262144(the value of all keys is 1-254). I also know those three values should be in wScan(corresponding 1,2,4) and they are modifier state flags. But three questions:
For example, I want to send a left Ctrl key to the active application, must I pass both wVk==LControlKey and wScan==Control right? What will happen if I only pass the first and not the second? And should I pass wVk==LControlKey; wScan==Control; dwFlags==0(key down dwFlags), and wVk==LControlKey; wScan==0; dwFlags==2(key up dwFlags)?
in Keys enumation there exist LControlKey, RControlKey, ControlKey, what's the third one mean?
in Keys enumation there exist Control keys and Shift keys, but why not Alt keys? So isn't it possible to send an Alt keystroke by SendInput method?

How to call DrawThemeTextEx in .NET

I need to write a text with glow in a Vista/seven glass window, and I'm, trying to call the API to write some text there. I have checked out a great sample in CodeProject, but the problem is that I'm using .NET 1 (please, don't ask :-)
I need to translate the follwing .NET 2 code to PInvoke, .NET 1 code.
// using System.Windows.Forms.VisualStyles
VisualStyleRenderer renderer = new VisualStyleRenderer(
VisualStyleElement.Window.Caption.Active);
// call to UxTheme.dll
DrawThemeTextEx(renderer.Handle,
memoryHdc, 0, 0, text, -1, (int)flags,
ref textBounds, ref dttOpts);
The class VisualStyleRenderer does not exist in .NET 1, so I need to get the renderer.Handle in other way.
Define the OpenThemeData API and DrawThemeTextEx, as well as some required structs and constants:
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
private static extern IntPtr OpenThemeData(IntPtr hwnd, string pszClassList);
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
private extern static Int32 DrawThemeTextEx(IntPtr hTheme, IntPtr hdc, int iPartId, int iStateId, string pszText, int iCharCount, uint flags, ref RECT rect, ref DTTOPTS poptions);
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[StructLayout(LayoutKind.Sequential)]
private struct DTTOPTS
{
public int dwSize;
public int dwFlags;
public int crText;
public int crBorder;
public int crShadow;
public int iTextShadowType;
public int ptShadowOffsetX;
public int ptShadowOffsetY;
public int iBorderSize;
public int iFontPropId;
public int iColorPropId;
public int iStateId;
public bool fApplyOverlay;
public int iGlowSize;
public IntPtr pfnDrawTextCallback;
public IntPtr lParam;
}
// taken from vsstyle.h
private const int WP_CAPTION = 1;
private const int CS_ACTIVE = 1;
And then, call it like this:
IntPtr handle = OpenThemeData(IntPtr.Zero, "WINDOW");
DrawThemeTextExt(handle, hdc, WS_CAPTION, CS_ACTIVE, ...)
The WS_CAPTION and CS_ACTIVE values match .NET 2's Caption and Active respectively. Values are described here officially: Parts and States
In short, you get what you want by calling OpenThemeData().
To work out all the details it would be much easier for you to write a sample app in C++ to get to know how to drive the theme API from the ground up. There are many tutorials and lots of sample code on the web. But do it in C++ where you will have all the functions readily available. The last thing you want to get doing is fighting with P/Invokes whilst you are also getting to grips with low-level theme API.
Once you get it cracked in C++, then move on to the P/Invokes and if you have trouble it will be easy to refer back to the C++ code that works.

Can I set the size attribute of StructLayout at runtime?

Im trying to use SendInput to simulate keyboard presses in my app and want to support both 32-bit and 64-bit.
I've determined that for this to work, I need to have 2 different INPUT structs as such
[StructLayout(LayoutKind.Sequential)]
public struct KEYBDINPUT
{
public ushort wVk; // Virtual Key Code
public ushort wScan; // Scan Code
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Explicit, Size = 28)]
public struct INPUT32
{
[FieldOffset(0)]
public uint type; // eg. INPUT_KEYBOARD
[FieldOffset(4)]
public KEYBDINPUT ki;
}
[StructLayout(LayoutKind.Explicit, Size = 40)]
public struct INPUT64
{
[FieldOffset(0)]
public uint type; // eg. INPUT_KEYBOARD
[FieldOffset(8)]
public KEYBDINPUT ki;
}
I wanted to know if there was a way to set the StructLayout size and FieldOffsets at runtime so I could use just one INPUT struct and determine the size and fieldoffset depending on the machine.
I have tried the code below but I would like to know if the same is possible at runtime instead of compile time.
#if _M_IX86
[StructLayout(LayoutKind.Explicit, Size = 28)]
#else
[StructLayout(LayoutKind.Explicit, Size = 40)]
#endif
public struct INPUT
{
[FieldOffset(0)]
public uint type; // eg. INPUT_KEYBOARD
#if _M_IX86
[FieldOffset(4)]
#else
[FieldOffset(8)]
#endif
public KEYBDINPUT ki;
}
Unfortunately, no.
Attributes are "fused" to the type at compile-time, which is why all values passed to an attribute constructor must be constants.
And at runtime you can't modify the attributes attached to the type. You can grab a copy and modify its values, but the actual attribute attached to the type will remain unchanged, so you can't "trick" mscorlib code into seeing your changes instead of the original, either.
You could always have 2 structs and determine which one to use at runtime.
With a proper design you could limit code duplication to a few lines. (Plus having the structures twice.)

Categories

Resources