win.RegisterRawInputDevices Всегда возвращает false - PullRequest
0 голосов
/ 31 декабря 2018

Я использую пакет https://github.com/lxn/win для доступа к низкоуровневым вызовам Windows в Go.Я звоню win.RegisterRawInputDevices, чтобы зарегистрировать устройства для необработанных входных данных, но всегда возвращает false.Я сделал это в C # без проблем.Ниже приведен мой код:

package main

import (
    "fmt"
    "syscall"
    "unsafe"
    "github.com/lxn/win"
)

func WndProc(hWnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr {
    switch msg {
    case win.WM_CREATE:
        fmt.Println("Received WM_CREATE message")
        devices := getRawInputDevices(hWnd)
        len := uint32(len(devices))
        size := uint32(unsafe.Sizeof(devices[0]))
        if !win.RegisterRawInputDevices(&devices[0], len, size) {
            panic("Unable to register devices")
        }

    case win.WM_DESTROY:
        fmt.Println("Posting quit message")
        win.PostQuitMessage(0)
    default:
        return win.DefWindowProc(hWnd, msg, wParam, lParam)
    }

    return 0
}

func getRawInputDevices(hWnd win.HWND) []win.RAWINPUTDEVICE {
    devices := make([]win.RAWINPUTDEVICE, 5)
    devices[0].UsUsagePage = 0x01
    devices[0].UsUsage = 0x02
    devices[0].DwFlags = win.RIDEV_INPUTSINK
    devices[0].HwndTarget = hWnd
    devices[1].UsUsagePage = 0x01
    devices[1].UsUsage = 0x06
    devices[1].DwFlags = win.RIDEV_INPUTSINK
    devices[1].HwndTarget = hWnd
    devices[2].UsUsagePage = 0x00
    devices[2].UsUsage = 0x51
    devices[2].DwFlags = win.RIDEV_INPUTSINK
    devices[2].HwndTarget = hWnd
    devices[3].UsUsagePage = 0x00
    devices[3].UsUsage = 0x04
    devices[3].DwFlags = win.RIDEV_INPUTSINK
    devices[3].HwndTarget = hWnd
    devices[4].UsUsagePage = 0x00
    devices[4].UsUsage = 0x00
    devices[4].DwFlags = win.RIDEV_INPUTSINK
    devices[4].HwndTarget = hWnd
    return devices
}

func WinMain() int {

    hInstance := win.GetModuleHandle(syscall.StringToUTF16Ptr(""))
    lpszClassName := syscall.StringToUTF16Ptr("WNDclass")
    var wcex win.WNDCLASSEX
    wcex.HInstance = hInstance
    wcex.LpszClassName = lpszClassName
    wcex.LpfnWndProc = syscall.NewCallback(WndProc)
    wcex.CbSize = uint32(unsafe.Sizeof(wcex))
    win.RegisterClassEx(&wcex)
    win.CreateWindowEx(
        0, lpszClassName, syscall.StringToUTF16Ptr("Simple Go Window!"),
        win.WS_OVERLAPPEDWINDOW,
        win.CW_USEDEFAULT, win.CW_USEDEFAULT, 400, 400, 0, 0, hInstance, nil)
    var msg win.MSG
    for {
        if win.GetMessage(&msg, 0, 0, 0) == 0 {
            break
        }
        win.TranslateMessage(&msg)
        win.DispatchMessage(&msg)
    }
    return int(msg.WParam)
}

func main() {
    WinMain()
    return
}

Я получаю сообщение WM_CREATE, но win.RegisterRawInputDevices всегда возвращает false со значением «Параметр неверен».ошибка.Как я уже говорил, я сделал это на C # без проблем, поэтому я знаком с основными шагами.Я новичок в Go, поэтому я могу что-то упустить.Есть идеи?

1 Ответ

0 голосов
/ 31 декабря 2018

После нескольких часов исследования стратегии выравнивания структуры Go и всех других низкоуровневых вещей я наконец понял, что у меня неверные значения для RAWINPUTDEVICE.UsUsagePage!Для элементов 2, 3 и 4 UsUsagePage должно быть установлено на 0x0D вместо 0x00!Ну, по крайней мере, я многое узнал о том, как Go выравнивает элементы структуры по границам слов!

...