Параметры низкоуровневого входного декодирования c # - PullRequest
0 голосов
/ 21 ноября 2018

Я делаю низкоуровневый хук клавиатуры, который обрабатывает глобальные нажатия клавиш, перенаправляя это в Raw Input API, чтобы проверить, с какого устройства клавиатуры оно пришло.

Я делаю это с помощью функции SendMessage вмой хук, который может быть получен API.

Моя проблема в том, что API не может прочитать буфер lParam, возвращая false

>> Error getting the rawinput buffer

Как я могуприспособить ловушку, чтобы позволить API lParam того сообщения быть успешно декодированным API?

(я использую структуру Rawkeyboard, и я чувствую, что она может быть неправильной для использования, я также попытался использовать некоторые другие без удачи)

Hook

//^ 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);
    }
}

1 Ответ

0 голосов
/ 21 ноября 2018

Тип lParam для HookProc и SendMessage(WM_INPUT) различен.

Для HookProc, это CWPRETSTRUCT структура.

Для SendMessage(WM_INPUT), это RAWINPUT структура.

Итак, вам нужно создать новый RAWINPUT объект, а затем перейти к методу SendMessage.

...