I am using RegisterRawInputDevices of user32.dll to register the keyboard, but it's returning false. I am developing an Office add-in using VSTO and C#.
[StructLayout(LayoutKind.Sequential)]
public struct RAWINPUTDEVICE
{
[MarshalAs(UnmanagedType.U2)]
public UInt16 usUsagePage;
[MarshalAs(UnmanagedType.U2)]
public UInt16 usUsage;
[MarshalAs(UnmanagedType.U4)]
public int dwFlags;
public IntPtr hwndTarget;
}
[DllImport("User32.dll", SetLastError = true)]
public static extern bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice,
UInt32 uiNumDevices, UInt32 cbSize);
[DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
public void Register()
{
IntPtr hwnd = FindWindow("PPTFrameClass", "Presentation1 - PowerPoint");
RegisterKeyboardDevice(hwnd);
}
public void RegisterKeyboardDevice(IntPtr hwnd)
{
const int RIDEV_INPUTSINK = 0x00000100;
RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[1];
rid[0].usUsagePage = Convert.ToUInt16(1);
rid[0].usUsage = Convert.ToUInt16(6);
rid[0].dwFlags = RIDEV_INPUTSINK;
rid[0].hwndTarget = hwnd;
if (!RegisterRawInputDevices(rid, Convert.ToUInt32(rid.Length),
Convert.ToUInt32(Marshal.SizeOf(rid[0]))))
{
throw new ApplicationException("Failed to register raw input device(s). " +
"Error code: " + Marshal.GetLastWin32Error());
}
}
But the same logic is working fine for VB.NET and COM-addins. Please correct me if I am going wrong.
You can call RegisterRawInputDevices
only on windows that belong to the same process as your calling code.
I tested your code in an Excel C# VSTO addin as well as in an Excel C# COM addin and in both cases I could successfully call RegisterRawInputDevices
on the Excel window itself and on a WPF test window, that was created from inside the addin, without any kind of error. (My version for this test was Excel 2016 64-bit.)
Unfortunately I don't have any kind of reference for this behavior but I think this is intentional by design, maybe because of security concerns as you could potentially hijack some other window and possibly act as a kind of keylogger or doing some other really bad stuff.
So your code does work perfectly but you have to use a window that belongs to the same process. And I think the difference to your VB.NET addin is that it's working because it's playing by this rule.
User contributions licensed under CC BY-SA 3.0