我如何填写getRawinputdata模块的PDATA参数

发布于 2025-01-25 02:43:20 字数 11314 浏览 3 评论 0原文

我是半新的ctypes,我在如何使用 getRawinputdata 函数。我不确定如何填写第三参数。这是代码现在的外观以下方式

def get_raw_input(handle):
    dw_size = c_uint()
    GetRawInputData(handle, RID_INPUT, None, byref(dw_size), sizeof(RawInputHeader))
    lpb = LPBYTE(dw_size)
    print(lpb.contents)
    GetRawInputData(handle, RID_INPUT, lpb, byref(dw_size), sizeof(RawInputHeader))
    print(lpb.contents)
    return cast(lpb, POINTER(RawInput))

,我已经定义了模块,例如:

GetRawInputData = user32.GetRawInputData
GetRawInputData.argtypes = INT, UINT, LPVOID, PUINT, UINT
GetRawInputData.restype = UINT
GetRawInputData.errcheck = errcheck

运行get_raw_input是运行的,输出是其中之一:

c_byte(48)
c_byte(0)
c_byte(40)
c_byte(1)

有一些示例C ++代码在这里,但是我不确定在python中如何看。

如果有点混乱):

window.py(运行的文件)

from ctypes import *
from ctypes.wintypes import *
from structures import *
from constants import *
from devices import get_raw_input, register_devices
import random
import sys


def errcheck(result,func,args):
    if result is None or result == 0:
        raise WinError(get_last_error())
    return result


user32 = WinDLL('user32', use_last_error=True)
k32 = WinDLL('kernel32', use_last_error=True)
gdi32 = WinDLL('gdi32',use_last_error=True)
RegisterClass = user32.RegisterClassW
RegisterClass.argtypes = POINTER(WndClass),
RegisterClass.restype = ATOM
RegisterClass.errcheck = errcheck
CreateWindowEx = user32.CreateWindowExW
CreateWindowEx.argtypes = DWORD, LPCWSTR, LPCWSTR, DWORD, INT, INT, INT, INT, HWND, HMENU, HINSTANCE, LPVOID
CreateWindowEx.restype = HWND
CreateWindowEx.errcheck = errcheck
GetModuleHandle = k32.GetModuleHandleW
GetModuleHandle.argtypes = LPCWSTR,
GetModuleHandle.restype = HMODULE
GetModuleHandle.errcheck = errcheck
DefWindowProc = user32.DefWindowProcW
DefWindowProc.argtypes = HWND, UINT, WPARAM, LPARAM
DefWindowProc.restype = LRESULT
ShowWindow = user32.ShowWindow
ShowWindow.argtypes = HWND, INT
ShowWindow.restype = BOOL
UpdateWindow = user32.UpdateWindow
UpdateWindow.argtypes = HWND,
UpdateWindow.restype = BOOL
UpdateWindow.errcheck = errcheck
BeginPaint = user32.BeginPaint
BeginPaint.argtypes = HWND, POINTER(PaintStruct)
BeginPaint.restype = HDC
BeginPaint.errcheck = errcheck
FillRect = user32.FillRect
FillRect.argtypes = HDC, POINTER(RECT), HBRUSH
FillRect.restype = INT
FillRect.errcheck = errcheck
EndPaint = user32.EndPaint
EndPaint.argtypes = HWND, POINTER(PaintStruct)
EndPaint.restype = BOOL
EndPaint.errcheck = errcheck
PostQuitMessage = user32.PostQuitMessage
PostQuitMessage.argtypes = INT,
PostQuitMessage.restype = None
TranslateMessage = user32.TranslateMessage
TranslateMessage.argtypes = POINTER(MSG),
TranslateMessage.restype = BOOL
DispatchMessage = user32.DispatchMessageW
DispatchMessage.argtypes = POINTER(MSG),
DispatchMessage.restype = LRESULT
GetClientRect = user32.GetClientRect
GetClientRect.argtypes = HWND, POINTER(RECT)
GetClientRect.restype = BOOL
GetClientRect.errcheck = errcheck
GetMessage = user32.GetMessageW
GetMessage.argtypes = POINTER(MSG), HWND, UINT, UINT
GetMessage.restype = BOOL
DrawText = user32.DrawTextW
DrawText.argtypes = HDC, LPCWSTR, INT, POINTER(RECT), UINT
DrawText.restype = LRESULT
LoadIcon = user32.LoadIconW
LoadIcon.argtypes = HINSTANCE, LPCWSTR
LoadIcon.restype = HICON
LoadIcon.errcheck = errcheck
LoadCursor = user32.LoadCursorW
LoadCursor.argtypes = HINSTANCE, LPCWSTR
LoadCursor.restype = HCURSOR
LoadCursor.errcheck = errcheck
GetStockObject = gdi32.GetStockObject
GetStockObject.argtypes = INT,
GetStockObject.restype = HGDIOBJ
CreateSolidBrush = gdi32.CreateSolidBrush
CreateSolidBrush.argtypes = COLORREF,
CreateSolidBrush.restype = HBRUSH
TextOut = gdi32.TextOutW
TextOut.argtypes = HDC, INT, INT, LPCWSTR, INT
TextOut.restype = INT
SetBkMode = gdi32.SetBkMode
SetBkMode.argtypes = HDC, INT
SetBkMode.restype = INT
SetTextColor = gdi32.SetTextColor
SetTextColor.argtypes = HDC, COLORREF
SetTextColor.restype = COLORREF


def window_callback(handle, message, w_param, l_param):
    ps = PaintStruct()
    rect = RECT()

    if message == WM_PAINT:
        hdc = BeginPaint(handle, byref(ps))
        GetClientRect(handle, byref(rect))

        SetBkMode(hdc, -1)
        SetTextColor(hdc, 0xFFFFFF)

        FillRect(hdc, byref(ps.rcPaint), CreateSolidBrush(0x0))
        DrawText(hdc, 'Testing oawguna', -1, byref(rect), DT_SINGLELINE|DT_CENTER|DT_VCENTER)

        EndPaint(handle, byref(ps))
        return 0
    elif message == WM_INPUT:
        raw_input = get_raw_input(l_param)
    elif message == WM_DESTROY:
        PostQuitMessage(0)
        return 0
    return DefWindowProc(handle, message, w_param, l_param)


def run():
    instance = GetModuleHandle(None)
    class_name = 'TestWindow'

    wnd = WndClass()
    wnd.style = CS_HREDRAW | CS_VREDRAW
    wnd.lpfnWndProc = WNDPROC(window_callback)
    wnd.hInstace = instance
    wnd.hCursor = LoadCursor(None, IDC_ARROW)
    wnd.lpszClassName = class_name

    RegisterClass(byref(wnd))

    handle = CreateWindowEx(
        0, class_name, 'Python Window', WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        None, None, instance, None
    )

    ShowWindow(handle, SW_NORMAL)
    UpdateWindow(handle)

    register_devices(handle)
    msg = MSG()
    while GetMessage(byref(msg), None, 0, 0) != 0:
        TranslateMessage(byref(msg))
        DispatchMessage(byref(msg))

    return msg.wParam


if __name__ == "__main__":
    sys.exit(run())

decection.py:startants.py:structures.py

from ctypes import *
from ctypes.wintypes import *
from structures import *
from constants import *


def errcheck(result,func,args):
    if result is None or result == -1:
        raise WinError(get_last_error())
    return result


user32 = WinDLL('user32', use_last_error=True)
RegisterRawInputDevices = user32.RegisterRawInputDevices
RegisterRawInputDevices.argtypes = (RawInputDevice * 7), UINT, UINT
RegisterRawInputDevices.restype = BOOL
RegisterRawInputDevices.errcheck = errcheck
GetRawInputData = user32.GetRawInputData
GetRawInputData.argtypes = INT, UINT, LPVOID, PUINT, UINT
GetRawInputData.restype = UINT
GetRawInputData.errcheck = errcheck


def register_devices(hwnd_target=None):
    page = 0x01
    devices = (RawInputDevice * 7)(
        RawInputDevice(page, 0x01, DW_FLAGS, hwnd_target),
        RawInputDevice(page, 0x02, DW_FLAGS, hwnd_target),
        RawInputDevice(page, 0x04, DW_FLAGS, hwnd_target),
        RawInputDevice(page, 0x05, DW_FLAGS, hwnd_target),
        RawInputDevice(page, 0x06, DW_FLAGS, hwnd_target),
        RawInputDevice(page, 0x07, DW_FLAGS, hwnd_target),
        RawInputDevice(page, 0x08, DW_FLAGS, hwnd_target),
    )
    RegisterRawInputDevices(devices, len(devices), sizeof(devices[0]))


def get_raw_input(handle):
    dw_size = c_uint()
    GetRawInputData(handle, RID_INPUT, None, byref(dw_size), sizeof(RawInputHeader))
    lpb = LPBYTE(dw_size)
    print(lpb.contents)
    GetRawInputData(handle, RID_INPUT, lpb, byref(dw_size), sizeof(RawInputHeader))
    print(lpb.contents)
    return cast(lpb, POINTER(RawInput))

from ctypes.wintypes import *
from ctypes import c_int64, WINFUNCTYPE, c_void_p


LRESULT = c_int64
HCURSOR = c_void_p

USAGE_PAGE = 0x01
USAGE = 0x06
DW_FLAGS = 0
DW_TYPE = 2
WM_INPUT = 0x00FF
WM_PAINT = 0x000F
WM_DESTROY = 0x0002
WM_QUI = 0x0012
RIDI_DEVICENAME = 0x20000007
RIDI_DEVICEINFO = 0x2000000b
ERROR_INSUFFICIENT_BUFFER = 0x7A
WS_EX_CLIENTEDGE = 0x00000200
WS_BORDER = 0x00800000
CS_BYTEALIGNCLIENT = 0x1000
CS_HREDRAW = 2
CS_VREDRAW = 1
SW_NORMAL = 1
CW_USEDEFAULT = -2147483648
WS_OVERLAPPED = 0x00000000
WS_CAPTION = 0x00C00000
WS_SYSMENU = 0x00080000
WS_THICKFRAME = 0x00040000
WS_MINIMIZEBOX = 0x00020000
WS_MAXIMIZEBOX = 0x00010000
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
RID_INPUT = 0x10000003
PM_REMOVE = 0x0001
DT_SINGLELINE = 32
DT_CENTER = 1
DT_VCENTER = 4
IDI_APPLICATION = LPCWSTR(32512)
IDC_ARROW = LPCWSTR(32512)
WHITE_BRUSH = 0
WNDPROC = WINFUNCTYPE(LRESULT, HWND, UINT, WPARAM, LPARAM)

这是完整的运行代码(对不起,

from ctypes import Structure, windll, WINFUNCTYPE, c_int64, Union, c_byte, c_void_p
from ctypes.wintypes import *
from constants import *


HCURSOR = c_void_p


class RawInputDevice(Structure):
    _fields_ = [
        ("usUsagePage", USHORT),
        ("usUsage", USHORT),
        ("dwFlags", DWORD),
        ("hwndTarget", HWND),
    ]


class RawInputDeviceList(Structure):
    _fields_ = [
        ("hDevice", HANDLE),
        ("dwType", DWORD),
    ]


class RIDDeviceInfoHID(Structure):
    _fields_ = [
        ("dwVendorId", DWORD),
        ("dwProductId", DWORD),
        ("dwVersionNumber", DWORD),
        ("usUsagePage", USHORT),
        ("usUsage", USHORT),
    ]


class RIDDeviceInfo(Structure):
    _fields_ = [
        ("cbSize", DWORD),
        ("dwType", DWORD),
        ("hid", RIDDeviceInfoHID),
    ]


class WndClass(Structure):
    _fields_ = [
        ("style", UINT),
        ("lpfnWndProc", WNDPROC),
        ("cbClsExtra", INT),
        ("cbWndExtra", INT),
        ("hInstance", HINSTANCE),
        ("hIcon", HICON),
        ("hCursor", HCURSOR),
        ("hbrBackground", HBRUSH),
        ("lpszMenuName", LPCWSTR),
        ("lpszClassName", LPCWSTR),
    ]


class PaintStruct(Structure):
    _fields_ = [
        ("hdc", HDC),
        ("fErase", BOOL),
        ("rcPaint", RECT),
        ("fRestore", BOOL),
        ("fIncUpdate", BOOL),
        ("rgbReserved", BYTE * 32),
    ]


class RawInputHeader(Structure):
    _fields_ = [
        ("dwType", DWORD),
        ("dwSize", DWORD),
        ("hDevice", HANDLE),
        ("wParam", WPARAM),
    ]


class RawHID(Structure):
    _fields_ = [
        ("dwSizeHid", DWORD),
        ("dwCount", DWORD),
        ("bRawData", BYTE),
    ]


class MouseStruct(Structure):
    _fields_ = [
        ("usButtonFlags", USHORT),
        ("usButtonData", USHORT)
    ]


class MouseUnion(Union):
    _fields_ = [
        ("ulButtons", ULONG),
        ("data", MouseStruct)
    ]


class RawMouse(Structure):
    _fields_ = [
        ("usFlags", USHORT),
        ("data", MouseUnion),
        ("ulRawButtons", ULONG),
        ("lLastX", LONG),
        ("lLastY", LONG),
        ("ulExtraInformation", ULONG),
    ]


class RawKeyboard(Structure):
    _fields_ = [
        ("MakeCode", USHORT),
        ("Flags", USHORT),
        ("Reserved", USHORT),
        ("VKey", USHORT),
        ("Message", UINT),
        ("ExtraInformation", ULONG),
    ]


class RawUnion(Union):
    _fields_ = [
        ("mouse", RawMouse),
        ("keyboard", RawKeyboard),
        ("hid", RawHID)
    ]


class RawInput(Structure):
    _fields_ = [
        ("header", RawInputHeader),
        ("data", RawUnion),
    ]

I'm semi-new to ctypes and I'm having trouble with how to use the GetRawInputData function. I'm not sure how to fill in the 3rd argument. Here's how the code looks right now

def get_raw_input(handle):
    dw_size = c_uint()
    GetRawInputData(handle, RID_INPUT, None, byref(dw_size), sizeof(RawInputHeader))
    lpb = LPBYTE(dw_size)
    print(lpb.contents)
    GetRawInputData(handle, RID_INPUT, lpb, byref(dw_size), sizeof(RawInputHeader))
    print(lpb.contents)
    return cast(lpb, POINTER(RawInput))

I've defined the module like so:

GetRawInputData = user32.GetRawInputData
GetRawInputData.argtypes = INT, UINT, LPVOID, PUINT, UINT
GetRawInputData.restype = UINT
GetRawInputData.errcheck = errcheck

When get_raw_input is run, the output is one of either of these:

c_byte(48)
c_byte(0)
c_byte(40)
c_byte(1)

There's some example C++ code here, but I'm not sure how that should look in Python.

Here's the full running code (sorry if it's a bit messy):

window.py (file that runs)

from ctypes import *
from ctypes.wintypes import *
from structures import *
from constants import *
from devices import get_raw_input, register_devices
import random
import sys


def errcheck(result,func,args):
    if result is None or result == 0:
        raise WinError(get_last_error())
    return result


user32 = WinDLL('user32', use_last_error=True)
k32 = WinDLL('kernel32', use_last_error=True)
gdi32 = WinDLL('gdi32',use_last_error=True)
RegisterClass = user32.RegisterClassW
RegisterClass.argtypes = POINTER(WndClass),
RegisterClass.restype = ATOM
RegisterClass.errcheck = errcheck
CreateWindowEx = user32.CreateWindowExW
CreateWindowEx.argtypes = DWORD, LPCWSTR, LPCWSTR, DWORD, INT, INT, INT, INT, HWND, HMENU, HINSTANCE, LPVOID
CreateWindowEx.restype = HWND
CreateWindowEx.errcheck = errcheck
GetModuleHandle = k32.GetModuleHandleW
GetModuleHandle.argtypes = LPCWSTR,
GetModuleHandle.restype = HMODULE
GetModuleHandle.errcheck = errcheck
DefWindowProc = user32.DefWindowProcW
DefWindowProc.argtypes = HWND, UINT, WPARAM, LPARAM
DefWindowProc.restype = LRESULT
ShowWindow = user32.ShowWindow
ShowWindow.argtypes = HWND, INT
ShowWindow.restype = BOOL
UpdateWindow = user32.UpdateWindow
UpdateWindow.argtypes = HWND,
UpdateWindow.restype = BOOL
UpdateWindow.errcheck = errcheck
BeginPaint = user32.BeginPaint
BeginPaint.argtypes = HWND, POINTER(PaintStruct)
BeginPaint.restype = HDC
BeginPaint.errcheck = errcheck
FillRect = user32.FillRect
FillRect.argtypes = HDC, POINTER(RECT), HBRUSH
FillRect.restype = INT
FillRect.errcheck = errcheck
EndPaint = user32.EndPaint
EndPaint.argtypes = HWND, POINTER(PaintStruct)
EndPaint.restype = BOOL
EndPaint.errcheck = errcheck
PostQuitMessage = user32.PostQuitMessage
PostQuitMessage.argtypes = INT,
PostQuitMessage.restype = None
TranslateMessage = user32.TranslateMessage
TranslateMessage.argtypes = POINTER(MSG),
TranslateMessage.restype = BOOL
DispatchMessage = user32.DispatchMessageW
DispatchMessage.argtypes = POINTER(MSG),
DispatchMessage.restype = LRESULT
GetClientRect = user32.GetClientRect
GetClientRect.argtypes = HWND, POINTER(RECT)
GetClientRect.restype = BOOL
GetClientRect.errcheck = errcheck
GetMessage = user32.GetMessageW
GetMessage.argtypes = POINTER(MSG), HWND, UINT, UINT
GetMessage.restype = BOOL
DrawText = user32.DrawTextW
DrawText.argtypes = HDC, LPCWSTR, INT, POINTER(RECT), UINT
DrawText.restype = LRESULT
LoadIcon = user32.LoadIconW
LoadIcon.argtypes = HINSTANCE, LPCWSTR
LoadIcon.restype = HICON
LoadIcon.errcheck = errcheck
LoadCursor = user32.LoadCursorW
LoadCursor.argtypes = HINSTANCE, LPCWSTR
LoadCursor.restype = HCURSOR
LoadCursor.errcheck = errcheck
GetStockObject = gdi32.GetStockObject
GetStockObject.argtypes = INT,
GetStockObject.restype = HGDIOBJ
CreateSolidBrush = gdi32.CreateSolidBrush
CreateSolidBrush.argtypes = COLORREF,
CreateSolidBrush.restype = HBRUSH
TextOut = gdi32.TextOutW
TextOut.argtypes = HDC, INT, INT, LPCWSTR, INT
TextOut.restype = INT
SetBkMode = gdi32.SetBkMode
SetBkMode.argtypes = HDC, INT
SetBkMode.restype = INT
SetTextColor = gdi32.SetTextColor
SetTextColor.argtypes = HDC, COLORREF
SetTextColor.restype = COLORREF


def window_callback(handle, message, w_param, l_param):
    ps = PaintStruct()
    rect = RECT()

    if message == WM_PAINT:
        hdc = BeginPaint(handle, byref(ps))
        GetClientRect(handle, byref(rect))

        SetBkMode(hdc, -1)
        SetTextColor(hdc, 0xFFFFFF)

        FillRect(hdc, byref(ps.rcPaint), CreateSolidBrush(0x0))
        DrawText(hdc, 'Testing oawguna', -1, byref(rect), DT_SINGLELINE|DT_CENTER|DT_VCENTER)

        EndPaint(handle, byref(ps))
        return 0
    elif message == WM_INPUT:
        raw_input = get_raw_input(l_param)
    elif message == WM_DESTROY:
        PostQuitMessage(0)
        return 0
    return DefWindowProc(handle, message, w_param, l_param)


def run():
    instance = GetModuleHandle(None)
    class_name = 'TestWindow'

    wnd = WndClass()
    wnd.style = CS_HREDRAW | CS_VREDRAW
    wnd.lpfnWndProc = WNDPROC(window_callback)
    wnd.hInstace = instance
    wnd.hCursor = LoadCursor(None, IDC_ARROW)
    wnd.lpszClassName = class_name

    RegisterClass(byref(wnd))

    handle = CreateWindowEx(
        0, class_name, 'Python Window', WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        None, None, instance, None
    )

    ShowWindow(handle, SW_NORMAL)
    UpdateWindow(handle)

    register_devices(handle)
    msg = MSG()
    while GetMessage(byref(msg), None, 0, 0) != 0:
        TranslateMessage(byref(msg))
        DispatchMessage(byref(msg))

    return msg.wParam


if __name__ == "__main__":
    sys.exit(run())

devices.py:

from ctypes import *
from ctypes.wintypes import *
from structures import *
from constants import *


def errcheck(result,func,args):
    if result is None or result == -1:
        raise WinError(get_last_error())
    return result


user32 = WinDLL('user32', use_last_error=True)
RegisterRawInputDevices = user32.RegisterRawInputDevices
RegisterRawInputDevices.argtypes = (RawInputDevice * 7), UINT, UINT
RegisterRawInputDevices.restype = BOOL
RegisterRawInputDevices.errcheck = errcheck
GetRawInputData = user32.GetRawInputData
GetRawInputData.argtypes = INT, UINT, LPVOID, PUINT, UINT
GetRawInputData.restype = UINT
GetRawInputData.errcheck = errcheck


def register_devices(hwnd_target=None):
    page = 0x01
    devices = (RawInputDevice * 7)(
        RawInputDevice(page, 0x01, DW_FLAGS, hwnd_target),
        RawInputDevice(page, 0x02, DW_FLAGS, hwnd_target),
        RawInputDevice(page, 0x04, DW_FLAGS, hwnd_target),
        RawInputDevice(page, 0x05, DW_FLAGS, hwnd_target),
        RawInputDevice(page, 0x06, DW_FLAGS, hwnd_target),
        RawInputDevice(page, 0x07, DW_FLAGS, hwnd_target),
        RawInputDevice(page, 0x08, DW_FLAGS, hwnd_target),
    )
    RegisterRawInputDevices(devices, len(devices), sizeof(devices[0]))


def get_raw_input(handle):
    dw_size = c_uint()
    GetRawInputData(handle, RID_INPUT, None, byref(dw_size), sizeof(RawInputHeader))
    lpb = LPBYTE(dw_size)
    print(lpb.contents)
    GetRawInputData(handle, RID_INPUT, lpb, byref(dw_size), sizeof(RawInputHeader))
    print(lpb.contents)
    return cast(lpb, POINTER(RawInput))

constants.py:

from ctypes.wintypes import *
from ctypes import c_int64, WINFUNCTYPE, c_void_p


LRESULT = c_int64
HCURSOR = c_void_p

USAGE_PAGE = 0x01
USAGE = 0x06
DW_FLAGS = 0
DW_TYPE = 2
WM_INPUT = 0x00FF
WM_PAINT = 0x000F
WM_DESTROY = 0x0002
WM_QUI = 0x0012
RIDI_DEVICENAME = 0x20000007
RIDI_DEVICEINFO = 0x2000000b
ERROR_INSUFFICIENT_BUFFER = 0x7A
WS_EX_CLIENTEDGE = 0x00000200
WS_BORDER = 0x00800000
CS_BYTEALIGNCLIENT = 0x1000
CS_HREDRAW = 2
CS_VREDRAW = 1
SW_NORMAL = 1
CW_USEDEFAULT = -2147483648
WS_OVERLAPPED = 0x00000000
WS_CAPTION = 0x00C00000
WS_SYSMENU = 0x00080000
WS_THICKFRAME = 0x00040000
WS_MINIMIZEBOX = 0x00020000
WS_MAXIMIZEBOX = 0x00010000
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
RID_INPUT = 0x10000003
PM_REMOVE = 0x0001
DT_SINGLELINE = 32
DT_CENTER = 1
DT_VCENTER = 4
IDI_APPLICATION = LPCWSTR(32512)
IDC_ARROW = LPCWSTR(32512)
WHITE_BRUSH = 0
WNDPROC = WINFUNCTYPE(LRESULT, HWND, UINT, WPARAM, LPARAM)

structures.py:

from ctypes import Structure, windll, WINFUNCTYPE, c_int64, Union, c_byte, c_void_p
from ctypes.wintypes import *
from constants import *


HCURSOR = c_void_p


class RawInputDevice(Structure):
    _fields_ = [
        ("usUsagePage", USHORT),
        ("usUsage", USHORT),
        ("dwFlags", DWORD),
        ("hwndTarget", HWND),
    ]


class RawInputDeviceList(Structure):
    _fields_ = [
        ("hDevice", HANDLE),
        ("dwType", DWORD),
    ]


class RIDDeviceInfoHID(Structure):
    _fields_ = [
        ("dwVendorId", DWORD),
        ("dwProductId", DWORD),
        ("dwVersionNumber", DWORD),
        ("usUsagePage", USHORT),
        ("usUsage", USHORT),
    ]


class RIDDeviceInfo(Structure):
    _fields_ = [
        ("cbSize", DWORD),
        ("dwType", DWORD),
        ("hid", RIDDeviceInfoHID),
    ]


class WndClass(Structure):
    _fields_ = [
        ("style", UINT),
        ("lpfnWndProc", WNDPROC),
        ("cbClsExtra", INT),
        ("cbWndExtra", INT),
        ("hInstance", HINSTANCE),
        ("hIcon", HICON),
        ("hCursor", HCURSOR),
        ("hbrBackground", HBRUSH),
        ("lpszMenuName", LPCWSTR),
        ("lpszClassName", LPCWSTR),
    ]


class PaintStruct(Structure):
    _fields_ = [
        ("hdc", HDC),
        ("fErase", BOOL),
        ("rcPaint", RECT),
        ("fRestore", BOOL),
        ("fIncUpdate", BOOL),
        ("rgbReserved", BYTE * 32),
    ]


class RawInputHeader(Structure):
    _fields_ = [
        ("dwType", DWORD),
        ("dwSize", DWORD),
        ("hDevice", HANDLE),
        ("wParam", WPARAM),
    ]


class RawHID(Structure):
    _fields_ = [
        ("dwSizeHid", DWORD),
        ("dwCount", DWORD),
        ("bRawData", BYTE),
    ]


class MouseStruct(Structure):
    _fields_ = [
        ("usButtonFlags", USHORT),
        ("usButtonData", USHORT)
    ]


class MouseUnion(Union):
    _fields_ = [
        ("ulButtons", ULONG),
        ("data", MouseStruct)
    ]


class RawMouse(Structure):
    _fields_ = [
        ("usFlags", USHORT),
        ("data", MouseUnion),
        ("ulRawButtons", ULONG),
        ("lLastX", LONG),
        ("lLastY", LONG),
        ("ulExtraInformation", ULONG),
    ]


class RawKeyboard(Structure):
    _fields_ = [
        ("MakeCode", USHORT),
        ("Flags", USHORT),
        ("Reserved", USHORT),
        ("VKey", USHORT),
        ("Message", UINT),
        ("ExtraInformation", ULONG),
    ]


class RawUnion(Union):
    _fields_ = [
        ("mouse", RawMouse),
        ("keyboard", RawKeyboard),
        ("hid", RawHID)
    ]


class RawInput(Structure):
    _fields_ = [
        ("header", RawInputHeader),
        ("data", RawUnion),
    ]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

过潦 2025-02-01 02:43:21

列表 [python.docs] >。

这个(修复程序)已经被涵盖为 [so]:使用Winapi从设备读取输入(@cristifati的答案)很难。

问题是 lpbyte pointer(c_byte))初始化:

  • 无参数,包装a null pointer pointer

  • 用参数(整数值)将其存储在尖端区域 not> not> not )将其用作尺寸)。
    更多,该区域将是 064bit (在实验中发现),这意味着试图在其外部进行索引触发触发 u u ndefined < strong> b ehavior ,即使程序没有崩溃(这是因为接下来的区域未由其他变量要求)


以分配一定尺寸的内存区域,使用 create_string_buffer (或数组 - 但是,将其传递给期望指针的函数时,您必须施加 cast )。

 &gt;&gt;&gt;导入CTYPE作为CT
&gt;&gt;&gt;导入ctypes.wintypes作为wt
&gt;&gt;&gt;
&gt;&gt;&gt;
&gt;&gt;&gt; pb0 = wt.lpbyte()
&gt;&gt;&gt;布尔(PB0)
错误的
&gt;&gt;&gt; PB0
Trackback(最近的最新电话):
  文件“&lt; stdin&gt;”,第1行,in&lt; module&gt;
ValueError:零指针访问
&gt;&gt;&gt;
&gt;&gt;&gt; ll = ct.c_longlong(0x010203040506070809)#将被截断(头部部分 - 由于很少的endianness)
&gt;&gt;&gt; pb1 = wt.lpbyte(ll)
&gt;&gt;&gt;布尔(PB1)
真的
&gt;&gt;&gt; pb1
C_BYTE(9)
&gt;&gt;&gt; [pb1 [e]对于e范围内(0,10)]#@todo -cfati:将genarate ub!
[9、8、7、6、5、4、3、2、0、0]
&gt;&gt;&gt;
&gt;&gt;&gt; buf = ct.create_string_buffer(12)
&gt;&gt;&gt;伦(buf)
12
&gt;&gt;&gt; buf [0]
B'\ x00'
&gt;&gt;&gt; BUF [12]
Trackback(最近的最新电话):
  文件“&lt; stdin&gt;”,第1行,in&lt; module&gt;
IndexError:无效索引
 

Listing [Python.Docs]: ctypes - A foreign function library for Python.

This (a fix) was already covered as part of [SO]: Having trouble using winapi to read input from a device (@CristiFati's answer).

The problem is LPBYTE (POINTER(c_byte)) initialization:

  • Without parameters, wraps a NULL pointer

  • With parameter (an integer value) it will store that value in the pointed area (and not use it as size).
    More, that area will be 064bit large (discovered experimentally) meaning that trying to index outside it triggers Undefined Behavior, even if the program doesn't crash (that is because the area right next isn't claimed by other variables)

To allocate a memory area of a certain size, use create_string_buffer (or an array - but you'll have to cast when passing it to functions expecting pointers).

>>> import ctypes as ct
>>> import ctypes.wintypes as wt
>>>
>>>
>>> pb0 = wt.LPBYTE()
>>> bool(pb0)
False
>>> pb0.contents
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: NULL pointer access
>>>
>>> ll = ct.c_longlong(0x010203040506070809)  # Will be truncated (head part - due to little endianness)
>>> pb1 = wt.LPBYTE(ll)
>>> bool(pb1)
True
>>> pb1.contents
c_byte(9)
>>> [pb1[e] for e in range(0, 10)]  # @TODO - cfati: will genarate UB !!!
[9, 8, 7, 6, 5, 4, 3, 2, 0, 0]
>>>
>>> buf = ct.create_string_buffer(12)
>>> len(buf)
12
>>> buf[0]
b'\x00'
>>> buf[12]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: invalid index
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文