c#低电平输入解码消息参数
我正在制作一个处理全局按键的低级键盘钩子,将其转发到原始输入API以检查它来自哪个键盘设备 我通过使用API可以接收的钩子中的c#低电平输入解码消息参数,c#,raw-input,low-level,C#,Raw Input,Low Level,我正在制作一个处理全局按键的低级键盘钩子,将其转发到原始输入API以检查它来自哪个键盘设备 我通过使用API可以接收的钩子中的SendMessage函数来实现这一点 我的问题是API无法读取LPRAM的缓冲区,返回false 获取原始输入缓冲区时出错 如何调整钩子以允许API成功解码该消息的LPRAM (我正在使用Rawkeyboard结构,我觉得这可能不是正确的使用方法,我还尝试使用了其他一些结构,但没有成功) 钩住 //^ DLL Imports, SetWindowsHookEx, etc
SendMessage
函数来实现这一点
我的问题是API无法读取LPRAM的缓冲区,返回false
获取原始输入缓冲区时出错
如何调整钩子以允许API成功解码该消息的LPRAM
(我正在使用Rawkeyboard结构,我觉得这可能不是正确的使用方法,我还尝试使用了其他一些结构,但没有成功)
钩住
//^ DLL Imports, SetWindowsHookEx, etc^
public int HookProc(int Code, int wParam, ref CWPRETSTRUCT lParam) {
if (Code >= 0) {
// Block
Rawkeyboard lParamKeyboard = new Rawkeyboard();
int result = SendMessage(Handle, 0x00FF, wParam, ref lParamKeyboard ); // Send to API
if (result == 1) {
return 1;
}
}
// Allow
return CallNextHookEx(Handle, Code, wParam, ref lParam);
}
[StructLayout(LayoutKind.Sequential)]
public struct Rawkeyboard {
public ushort Makecode; // Scan code from the key depression
public ushort Flags; // One or more of RI_KEY_MAKE, RI_KEY_BREAK, RI_KEY_E0, RI_KEY_E1
private readonly ushort Reserved; // Always 0
public ushort VKey; // Virtual Key Code
public uint Message; // Corresponding Windows message for exmaple (WM_KEYDOWN, WM_SYASKEYDOWN etc)
public uint ExtraInformation; // The device-specific addition information for the event (seems to always be zero for keyboards)
public override string ToString() {
return string.Format("Rawkeyboard\n Makecode: {0}\n Makecode(hex) : {0:X}\n Flags: {1}\n Reserved: {2}\n VKeyName: {3}\n Message: {4}\n ExtraInformation {5}\n",
Makecode, Flags, Reserved, VKey, Message, ExtraInformation);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct CWPRETSTRUCT {
IntPtr lResult;
IntPtr lParam;
IntPtr wParam;
uint message;
IntPtr hWnd;
}
API
protected override void WndProc(ref Message message){
switch (message.Msg){
// Message Received!
case 0x00FF:{
bool result = false;
hdevice = message.LParam;
if (_deviceList.Count == 0) return false;
var dwSize = 0;
Win32.GetRawInputData(hdevice, DataCommand.RID_INPUT, IntPtr.Zero, ref dwSize, Marshal.SizeOf(typeof(Rawinputheader)));
if (dwSize != Win32.GetRawInputData(hdevice, DataCommand.RID_INPUT, out _rawBuffer, ref dwSize, Marshal.SizeOf(typeof (Rawinputheader)))){
Debug.WriteLine("Error getting the rawinput buffer");
result = false;
}
else{
// Do checks here
result = true;
}
message.Result = (IntPtr)Convert.ToInt32(result);
}
break;
}
base.WndProc(ref message);
}
[StructLayout(LayoutKind.Sequential)]
public struct Rawinputheader
{
public uint dwType; // Type of raw input (RIM_TYPEHID 2, RIM_TYPEKEYBOARD 1, RIM_TYPEMOUSE 0)
public uint dwSize; // Size in bytes of the entire input packet of data. This includes RAWINPUT plus possible extra input reports in the RAWHID variable length array.
public IntPtr hDevice; // A handle to the device generating the raw input data.
public IntPtr wParam; // RIM_INPUT 0 if input occurred while application was in the foreground else RIM_INPUTSINK 1 if it was not.
public override string ToString()
{
return string.Format("RawInputHeader\n dwType : {0}\n dwSize : {1}\n hDevice : {2}\n wParam : {3}", dwType, dwSize, hDevice, wParam);
}
}
HookProc
和SendMessage(WM\u输入)
的lParam
类型不同
对于HookProc
,它的结构是
对于发送消息(WM\U输入)
,它的结构是
因此,您需要创建一个新的
RAWINPUT
对象,然后传递给SendMessage
方法。HookProc
和SendMessage(WM_输入)
的lParam
类型不同
对于HookProc
,它的结构是
对于发送消息(WM\U输入)
,它的结构是
因此,您需要创建一个新的
RAWINPUT
对象,然后传递给SendMessage
方法。您可以尝试使用if(Win32.GetRawInputData(…)!=dwSize
,并确认是否仍然出现错误?@Xiaoy312是的,仍然是相同的错误,但切换运算符无效,谢谢!)捕获第一个api的结果并检查最后一个错误<代码>变量结果=Win32.GetRaw…();如果(result=-1){var code=Marshal.GetLastWin32Error();var error=new Win32Exception(code);Debug.WriteLine(code+“:“+error.ToString());}检查这是否给了您任何帮助。哇,谢谢!我得到一个System.ComponentModel.Win32Exception(0x80004005):句柄无效
错误,这一定与@shingo的响应有关,你可以尝试if(Win32.GetRawInputData(…)!=dwSize
,确认你是否仍然得到错误?@Xiaoy312是的,仍然是相同的错误,但是切换操作符无效,谢谢!)捕获第一个api的结果并检查最后一个错误<代码>变量结果=Win32.GetRaw…();如果(result=-1){var code=Marshal.GetLastWin32Error();var error=new Win32Exception(code);Debug.WriteLine(code+“:“+error.ToString());}检查这是否给了您任何帮助。哇,谢谢!我得到一个System.ComponentModel.Win32Exception(0x80004005):句柄无效
错误,这一定与@shingo的responceHey有关,你能看看我的编辑,看看它们是否是你建议的,仍然得到相同的错误;(我错了,发送WM_输入消息需要RAWINPUT结构,它包含RAWKEYBOARD结构。嘿,你能看看我的编辑是否是你建议的,仍然得到相同的错误;(我错了,发送WM_输入消息需要RAWINPUT结构,它包含RAWKEYBOARD结构。)。