Script mit mehreren Mäusen bedienen

  • Hi

    Ich versuch das mal zu erklären:
    Für ein Programm benötige ich 2 Mäuse für die Bedienung
    Eine Maus steuert einen Cursor, welcher nur in einem Fenster agiert, und die zweite Maus benötigt man um gleichzeitig Einstellungen vorzunehmen.
    (Der erste Cursor könnte auch von einem Joystick gesteuert werden, den aber nicht jeder Benutzer besitzt - jedoch die meisten haben einen Laptop mit Touchpad und eine USB-Maus)
    Darüberhinaus soll das Programm im Extremfall aber auch mit nur einer Maus gesteuert werden können, dazu muß man die rechte Maustaste gedrückt halten, während man Einstellungen vornimmt, damit sich der erste Cursor nicht bewegt...

    Mehrere Mäuse können via RawInput gelesen werden, jedoch bewegen alle Mäuse den Mauszeiger bzw. alle Tastenklicks verursachen auch Mausklicks.
    Dies soll jedoch bei der "ersten" Maus nicht passieren.

    Meine Idee war ursprünglich folgende:
    Ich registriere einen Mausinput via RawInput und eintscheide dann, ob diese Aktion von Windows auch ausgeführt werden darf - wenn nicht, dann blockiere ich die Maus in einem $WM_MOUSE_LL-Hook

    Da gibt es jedoch ein großes Problem: $WM_MOUSE_LL-Hook wird VOR RawInput aufgerufen und ich hab keine Chance auf diesem Weg! ?(

    Nun mache ich es so: Ich blockiere grundsätzlich alle Mauseingaben und gebe nur die frei, die nicht von der "ersten" Maus stammen - Alles klar? :D
    Mausklicks leite ich jedoch nicht weiter, sondern muß sie via MouaseClick synthetisieren

    Die Lösung ist nicht ganz zufriedenstellend, aber für meine Zwecke reicht es fürs erste...
    Es wär jedenfalls viel einfacher und besser, wenn RawInput vor dem Hook passieren würde X(

    Naja, hier das TestScript:
    Die Radiobuttons auf der linken Seite sind für die Maus, die den normalen Mauszeiger bewegen soll.
    Die auf der rechten Seite sind für den GDI+-Cursor im Hauptfenster
    getestet bisher nur auf WinXP, allerdings bereits mit 4 Mäusen ^^

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <GDIPlus.au3>
    #include <GUIConstantsEx.au3>
    #include <WinAPI.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    Global $hGui_Map = GUICreate("MultiMouse Test Map", 600, 400, @DesktopWidth / 2 - 405, @DesktopHeight / 2 - 200, -1, $WS_EX_TOPMOST)
    GUISetOnEvent(-3, "_Exit")

    [/autoit] [autoit][/autoit] [autoit]

    Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui_Map)
    Global $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics(600, 400, $hGraphics)
    Global $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)
    _GDIPlus_GraphicsSetSmoothingMode($hGfxBuffer, 2)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hPen = _GDIPlus_PenCreate(0xFF00FF00, 3)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hGui_Set = GUICreate("MultiMouse Test Set", 200, 400, @DesktopWidth / 2 + 205, @DesktopHeight / 2 - 200, -1, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW), $hGui_Map)
    GUISetOnEvent(-3, "_Exit")
    Global $cButton1 = GUICtrlCreateButton("Test 1", 10, 10, 180, 25)
    GUICtrlSetOnEvent(-1, "_Test1")
    Global $cButton2 = GUICtrlCreateButton("Test 2", 10, 50, 180, 25)
    GUICtrlSetOnEvent(-1, "_Test2")

    [/autoit] [autoit][/autoit] [autoit]

    Global $aRadio_Normal[6]
    Global $aLabel[6]
    GUIStartGroup()
    For $i = 1 To 5
    $aLabel[$i] = GUICtrlCreateLabel("Maus " & $i, 80, 100 + ($i - 1) * 20, 120, 20, 0x0C)
    $aRadio_Normal[$i] = GUICtrlCreateRadio("", 10, 100 + ($i - 1) * 20, 20, 20)
    GUICtrlSetOnEvent(-1, "_ActivateMouse_Normal")
    Next
    Global $aRadio_Cursor[6]
    Global $aActive[6]
    GUIStartGroup()
    For $i = 1 To 5
    $aRadio_Cursor[$i] = GUICtrlCreateRadio("", 30, 100 + ($i - 1) * 20, 20, 20)
    GUICtrlSetOnEvent(-1, "_ActivateMouse_Cursor")
    $aActive[$i] = GUICtrlCreateLabel("", 50, 100 + ($i - 1) * 20, 20, 20)
    Next

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg($WM_PAINT, "WM_PAINT")
    GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND")
    GUIRegisterMsg(0x00FF, "WM_INPUT")
    GUISetState(@SW_SHOW, $hGui_Map)
    GUISetState(@SW_SHOW, $hGui_Set)

    [/autoit] [autoit][/autoit] [autoit]

    Global $aMice = _MM_GetMiceList()
    ;_ArrayDisplay($aMice)
    $aRadio_Normal[0] = 1
    $aRadio_Cursor[0] = 2
    GUICtrlSetState($aRadio_Normal[1], $GUI_CHECKED)
    GUICtrlSetState($aRadio_Cursor[2], $GUI_CHECKED)

    [/autoit] [autoit][/autoit] [autoit]

    If $aMice[0][0] < 2 Then
    $aRadio_Cursor[0] = 1
    GUICtrlSetState($aRadio_Cursor[1], $GUI_CHECKED)
    EndIf

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To 5
    If $i <= $aMice[0][0] Then
    GUICtrlSetData($aLabel[$i], $aMice[$i][1])
    Else
    GUICtrlSetState($aRadio_Normal[$i], $GUI_DISABLE)
    GUICtrlSetState($aRadio_Cursor[$i], $GUI_DISABLE)
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Global $aCursor[6] = [0, 0, 25, MouseGetPos(0), MouseGetPos(1), 0]
    _DrawCursor()

    [/autoit] [autoit][/autoit] [autoit]

    Global $aMouseStructs = _MM_CreateMouseStructs()
    _MM_RegisterMice($hGui_Map)

    [/autoit] [autoit][/autoit] [autoit]

    Global $Block = True

    [/autoit] [autoit][/autoit] [autoit]

    Global $hHook_Module_LL = _WinAPI_GetModuleHandle(0)
    Global $hMouse_Proc_LL = DllCallbackRegister("_MouseHook_Proc_LL", "int", "int;ptr;ptr")
    Global $hMouse_Hook_LL = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($hMouse_Proc_LL), $hHook_Module_LL, 0)
    OnAutoItExitRegister("_OnExit")

    [/autoit] [autoit][/autoit] [autoit]

    While 1

    [/autoit] [autoit][/autoit] [autoit]

    Sleep(100)
    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _MouseHook_Proc_LL($nCode, $wParam, $lParam)
    If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hMouse_Hook_LL, $nCode, $wParam, $lParam)

    [/autoit] [autoit][/autoit] [autoit]

    Local $iMouse_Event = BitAND($wParam, 0xFFFF)
    If $iMouse_Event = 512 Then Return 1
    If $Block Then Return 1

    [/autoit] [autoit][/autoit] [autoit]

    Return _WinAPI_CallNextHookEx($hMouse_Hook_LL, $nCode, $wParam, $lParam)
    EndFunc ;==>_MouseHook_Proc_LL

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _ActivateMouse_Normal()
    For $i = 1 To 5
    If @GUI_CtrlId = $aRadio_Normal[$i] Then $aRadio_Normal[0] = $i
    Next
    $aCursor[5] = 0
    EndFunc ;==>_ActivateMouse_Normal

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _ActivateMouse_Cursor()
    For $i = 1 To 5
    If @GUI_CtrlId = $aRadio_Cursor[$i] Then $aRadio_Cursor[0] = $i
    Next
    $aCursor[5] = 0
    EndFunc ;==>_ActivateMouse_Cursor

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _MM_CreateMouseStructs()
    Local $tMouse = DllStructCreate("dword dwType; dword dwSize; hwnd hDevice; uint_ptr wParam; ushort usFlags; ushort usButtonFlags; ushort usButtonData; ulong ulRawButtons; long lLastX; long lLastY; ulong ulExtraInformation;")
    Local $pMouse = DllStructGetPtr($tMouse)
    Local $iMouse = DllStructGetSize($tMouse)
    Local $tHeader = DllStructCreate("dword dwType; dword dwSize; hwnd hDevice; uint_ptr wParam;")
    Local $iHeader = DllStructGetSize($tHeader)
    Local $aReturn[4]
    $aReturn[0] = $tMouse
    $aReturn[1] = $pMouse
    $aReturn[2] = $iMouse
    $aReturn[3] = $iHeader
    Return $aReturn
    EndFunc ;==>_MM_CreateMouseStructs

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func WM_INPUT($hWnd, $Msg, $wParam, $lParam)
    Local $aResult = DllCall("user32.dll", "dword", "GetRawInputData", "hwnd", $lParam, "dword", 0x10000003, "ptr", $aMouseStructs[1], "dword*", $aMouseStructs[2], "uint", $aMouseStructs[3])
    If Not @error Then
    Local $hDevice = DllStructGetData($aMouseStructs[0], "hDevice")
    If Not $hDevice Then Return 'GUI_RUNDEFMSG'

    [/autoit] [autoit][/autoit] [autoit]

    Local $iX = DllStructGetData($aMouseStructs[0], "lLastX")
    Local $iY = DllStructGetData($aMouseStructs[0], "lLastY")
    Local $iButton = DllStructGetData($aMouseStructs[0], "usButtonData")

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $aMice[0][0]
    If $aMice[$i][0] = $hDevice Then
    GUICtrlSetBkColor($aActive[$i], 0x00FF00)
    Switch $i
    Case $aRadio_Cursor[0]
    If $iButton = 4 Or $iButton = 8 Then $aCursor[5] = $iButton
    If $aCursor[5] <> 4 Then
    $aCursor[0] += $iX
    $aCursor[1] += $iY
    If $aCursor[0] < 0 Then $aCursor[0] = 0
    If $aCursor[1] < 0 Then $aCursor[1] = 0
    If $aCursor[0] > 600 Then $aCursor[0] = 600
    If $aCursor[1] > 400 Then $aCursor[1] = 400

    [/autoit] [autoit][/autoit] [autoit]

    If $aRadio_Cursor[0] = $aRadio_Normal[0] Then
    Local $tPoints = DllStructCreate("int;int;")
    DllStructSetData($tPoints, 1, $aCursor[0])
    DllStructSetData($tPoints, 2, $aCursor[1])
    _WinAPI_ClientToScreen($hGui_Map, $tPoints)
    $aCursor[3] = DllStructGetData($tPoints, 1)
    $aCursor[4] = DllStructGetData($tPoints, 2)
    EndIf
    _DrawCursor()
    EndIf
    If $i = $aRadio_Normal[0] Then ContinueCase

    [/autoit] [autoit][/autoit] [autoit]

    Case Else
    $aCursor[3] += $iX
    $aCursor[4] += $iY
    If $aCursor[3] < 0 Then $aCursor[3] = 0
    If $aCursor[4] < 0 Then $aCursor[4] = 0
    If $aCursor[3] > @DesktopWidth Then $aCursor[3] = @DesktopWidth
    If $aCursor[4] > @DesktopHeight Then $aCursor[4] = @DesktopHeight

    [/autoit] [autoit][/autoit] [autoit]

    DllCall("user32.dll", "BOOL", "SetCursorPos", "int", $aCursor[3], "int", $aCursor[4])

    [/autoit] [autoit][/autoit] [autoit]

    If $iButton = 1 Then
    $Block = False
    MouseClick("left", $aCursor[3], $aCursor[4], 1, 0)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    EndSwitch
    Else
    GUICtrlSetBkColor($aActive[$i], 0xFF0000)
    EndIf
    Next
    EndIf
    $Block = True
    Return 'GUI_RUNDEFMSG'
    EndFunc ;==>WM_INPUT

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _MM_GetMiceList()
    Local $aMice[1][3] = [[0]]
    Local $tStruct = DllStructCreate("hwnd hDevice; dword dwType;")
    Local $aResult = DllCall("user32.dll", "dword", "GetRawInputDeviceList", "ptr", 0, "dword*", 0, "dword", DllStructGetSize($tStruct))
    If @error Then Return SetError(1, 1, $aMice)
    If Not $aResult[2] Then Return SetError(1, 2, $aMice)
    Local $iCnt = $aResult[2]

    [/autoit] [autoit][/autoit] [autoit]

    Local $sInfo = ""
    For $i = 1 To $iCnt
    $sInfo &= StringRegExpReplace("hwnd hDevice; dword dwType; ", "(\w+);", "${1}" & $i & ";")
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Local $tList = DllStructCreate($sInfo)
    $aResult = DllCall("user32.dll", "dword", "GetRawInputDeviceList", "ptr", DllStructGetPtr($tList), "dword*", $iCnt, "dword", DllStructGetSize($tStruct))
    If @error Then Return SetError(1, 3, $aMice)

    [/autoit] [autoit][/autoit] [autoit]

    Local $aInfo = _MM_Get_MiceInfo()

    [/autoit] [autoit][/autoit] [autoit]

    Local $iStep = 0
    Local $tName

    [/autoit] [autoit][/autoit] [autoit]

    Local $hDevice, $iSize, $sName_dbcc, $sName, $aRegExp
    For $i = 1 To $iCnt
    If DllStructGetData($tList, 'dwType' & $i) = 0 Then
    $hDevice = DllStructGetData($tList, "hDevice" & $i)

    [/autoit] [autoit][/autoit] [autoit]

    $aResult = DllCall("user32.dll", "dword", "GetRawInputDeviceInfo", "hwnd", $hDevice, "dword", 0x20000007, "ptr", 0, "dword*", 0)
    If @error Or Not IsArray($aResult) Then ContinueLoop
    $iSize = $aResult[4]
    $tName = DllStructCreate("char[" & $iSize & "];")

    [/autoit] [autoit][/autoit] [autoit]

    $aResult = DllCall("user32.dll", "dword", "GetRawInputDeviceInfo", "hwnd", $hDevice, "dword", 0x20000007, "ptr", DllStructGetPtr($tName), "dword*", $iSize)
    If @error Or Not IsArray($aResult) Then ContinueLoop

    [/autoit] [autoit][/autoit] [autoit]

    $sName_dbcc = DllStructGetData($tName, 1)
    $aRegExp = StringRegExp($sName_dbcc, "[\w\d&]+", 3)
    $sName = ""
    If UBound($aRegExp) > 2 And IsArray($aInfo) Then
    For $j = 1 To $aInfo[0][0]
    If StringInStr($aInfo[$j][2], $aRegExp[1]) Then
    $sName = $aInfo[$j][10]
    ExitLoop
    EndIf
    Next
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    If Not $sName Or StringInStr($sName_dbcc, "RDP_MOU") Then ContinueLoop

    [/autoit] [autoit][/autoit] [autoit]

    $iStep += 1
    ReDim $aMice[$iStep + 1][3]
    $aMice[$iStep][0] = $hDevice
    $aMice[$iStep][1] = $sName
    $aMice[$iStep][2] = $sName_dbcc

    [/autoit] [autoit][/autoit] [autoit]

    EndIf
    Next
    $aMice[0][0] = $iStep
    Return $aMice
    EndFunc ;==>_MM_GetMiceList

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _MM_Get_MiceInfo()
    Local $aMice[1][18] = [[0, 'Description', 'Device ID', 'Device Interface', 'Double Speed Threshold', 'Handedness', 'Hardware Type', 'INF File Name', 'INF Section', 'Manufacturer', 'Name', 'Number Of Buttons', 'PNP Device ID', 'Pointing Type', 'Quad Speed Threshold', 'Resolution', 'Sample Rate', 'Synch']]
    Local $iCnt = 0
    Local $oWMI = ObjGet('winmgmts:\\' & @ComputerName & '\root\cimv2')
    If Not @error And IsObj($oWMI) Then
    Local $cItems = $oWMI.ExecQuery('Select * from Win32_PointingDevice')
    Local $oItem, $Temp
    For $oItem In $cItems
    $iCnt += 1
    ReDim $aMice[$iCnt + 1][18]
    $aMice[$iCnt][1] = $oItem.Description
    $aMice[$iCnt][2] = $oItem.DeviceID
    $Temp = $oItem.DeviceInterface
    Switch $Temp
    Case 1
    $aMice[$iCnt][3] = "Other"
    Case 2
    $aMice[$iCnt][3] = "Unknown"
    Case 3
    $aMice[$iCnt][3] = "Serial"
    Case 4
    $aMice[$iCnt][3] = "PS/2"
    Case 5
    $aMice[$iCnt][3] = "Infrared"
    Case 6
    $aMice[$iCnt][3] = "HP-HIL"
    Case 7
    $aMice[$iCnt][3] = "Bus mouse"
    Case 8
    $aMice[$iCnt][3] = "ADB (Apple Desktop Bus)"
    Case 160
    $aMice[$iCnt][3] = "Bus mouse DB-9"
    Case 161
    $aMice[$iCnt][3] = "Bus mouse micro-DIN"
    Case 162
    $aMice[$iCnt][3] = "USB"
    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    $aMice[$iCnt][4] = $oItem.DoubleSpeedThreshold
    $aMice[$iCnt][5] = $oItem.Handedness
    $aMice[$iCnt][6] = $oItem.HardwareType
    $aMice[$iCnt][7] = $oItem.InfFileName
    $aMice[$iCnt][8] = $oItem.InfSection
    $aMice[$iCnt][9] = $oItem.Manufacturer
    $aMice[$iCnt][10] = $oItem.Name
    $aMice[$iCnt][11] = $oItem.NumberOfButtons
    $aMice[$iCnt][12] = $oItem.PNPDeviceID
    $aMice[$iCnt][13] = $oItem.PointingType
    $aMice[$iCnt][14] = $oItem.QuadSpeedThreshold
    $aMice[$iCnt][15] = $oItem.Resolution
    $aMice[$iCnt][16] = $oItem.SampleRate
    $aMice[$iCnt][17] = $oItem.Synch
    Next
    $aMice[0][0] = $iCnt
    Return $aMice
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Return SetError(1, 1, $aMice)
    EndFunc ;==>_MM_Get_MiceInfo

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _MM_RegisterMice($hGui)
    Local Const $RIDEV_INPUTSINK = 0x00000100

    [/autoit] [autoit][/autoit] [autoit]

    Local $tStruct = DllStructCreate("ushort usUsagePage; ushort usUsage; dword dwFlags; hwnd hwndTarget;")
    DllStructSetData($tStruct, "usUsagePage", 0x01)
    DllStructSetData($tStruct, "usUsage", 0x02)
    DllStructSetData($tStruct, "dwFlags", $RIDEV_INPUTSINK)
    DllStructSetData($tStruct, "hwndTarget", $hGui)
    Local $aResult = DllCall("user32.dll", "int", "RegisterRawInputDevices", "ptr", DllStructGetPtr($tStruct), "dword", 1, "dword", DllStructGetSize($tStruct))
    If @error Then Return SetError(1, 2, False)
    Return $aResult[0]
    EndFunc ;==>_MM_RegisterMice

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _DrawCursor()
    _GDIPlus_GraphicsClear($hGfxBuffer, 0xFF000000)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawLine($hGfxBuffer, $aCursor[0] - $aCursor[2], $aCursor[1], $aCursor[0] + $aCursor[2], $aCursor[1], $hPen)
    _GDIPlus_GraphicsDrawLine($hGfxBuffer, $aCursor[0], $aCursor[1] - $aCursor[2], $aCursor[0], $aCursor[1] + $aCursor[2], $hPen)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    EndFunc ;==>_DrawCursor

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Test1()
    ConsoleWrite("! Test1" & @CRLF)
    EndFunc ;==>_Test1

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Test2()
    ConsoleWrite("> Test2" & @CRLF)
    EndFunc ;==>_Test2

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func WM_PAINT($hWnd, $uMsgm, $wParam, $lParam)
    If $hWnd = $hGui_Map Then _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_PAINT

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func WM_ERASEBKGND($hWnd, $uMsgm, $wParam, $lParam)
    If $hWnd = $hGui_Map Then _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_ERASEBKGND

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hGfxBuffer)
    _GDIPlus_BitmapDispose($hBmpBuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_Exit

    [/autoit] [autoit][/autoit] [autoit]

    Func _OnExit()
    _WinAPI_UnhookWindowsHookEx($hMouse_Hook_LL)
    DllCallbackFree($hMouse_Proc_LL)
    EndFunc ;==>_OnExit

    [/autoit]

    Hat jemand eine Idee, wie man das anders/besser machen könnte?

    E

    • Offizieller Beitrag

    Da gibt es jedoch ein großes Problem: $WM_MOUSE_LL-Hook wird VOR RawInput aufgerufen und ich hab keine Chance auf diesem Weg!


    Dann verwende RawInput nicht und hol dir die Infos, die du damit erhalten willst aus dem Hook.
    Wenn ich richtig geschaut habe, sollte der Hook doch alle relevanten Infos liefern:

    Spoiler anzeigen
    [autoit]

    #include <WinAPI.au3>
    #include <WindowsConstants.au3>
    OnAutoItExitRegister('OnAutoItExit')
    HotKeySet('{ESC}', '_Exit')

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $HC_ACTION = 0
    Global $hStub_MouseProc = DllCallbackRegister("_MouseProc", "long", "int;wparam;lparam")
    Global $hmod = _WinAPI_GetModuleHandle(0)
    Global $hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($hStub_MouseProc), $hmod)

    [/autoit] [autoit][/autoit] [autoit]

    While True
    Sleep(50)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _MouseProc($nCode, $wParam, $lParam)
    Local $event, $info, $iX, $iY, $mouseData = "", $wheelData = "", $wheelCount
    $info = DllStructCreate("int X;int Y;dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo", $lParam)
    $iX = DllStructGetData($info, 1)
    $iY = DllStructGetData($info, 2)
    $mouseData = DllStructGetData($info, 3)
    If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    If $nCode = $HC_ACTION Then
    Switch $wParam
    Case $WM_MOUSEMOVE
    $event = "Mouse Move"
    Case $WM_MOUSEWHEEL
    $event = "Mouse Wheel"
    If _WinAPI_HiWord($mouseData) > 0 Then
    $wheelData = " Forward"
    Else
    $wheelData = " Backward"
    EndIf
    $wheelCount = _WinAPI_HiWord($mouseData)/120
    Case $WM_LBUTTONDOWN
    $event = "Left Down"
    Case $WM_LBUTTONUP
    $event = "Left Up"
    Case $WM_RBUTTONDOWN
    $event = "Right Down"
    Case $WM_RBUTTONUP
    $event = "Right Up"
    Case $WM_MBUTTONDOWN
    $event = "Wheel Down"
    Case $WM_MBUTTONUP
    $event = "Wheel Up"
    EndSwitch
    EndIf
    ConsoleWrite($iX & ', ' & $iY & ' ' & $event & $wheelData & ' count: ' & $wheelCount & @CRLF)
    Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func OnAutoItExit()
    _WinAPI_UnhookWindowsHookEx($hHook)
    DllCallbackFree($hStub_MouseProc)
    EndFunc ;==>OnAutoItExit

    [/autoit]
    • Offizieller Beitrag

    Die Lösung ist nicht ganz zufriedenstellend, aber für meine Zwecke reicht es fürs erste...

    Habs nochmal angeschaut, gibt wohl keinen anderen Weg als
    - Mouse Events auffangen und blocken
    - Input Device abfragen
    - gewollte Events senden

    Es ist recht aufwändig - aber weshalb nicht zufriedenstellend?

  • Maus A soll nur für mein Programm funktionieren und Maus B ganz normal, also auch für andere Anwendungen.
    Es ist einfacher nur eine Maus zu blockieren, als alle Mäuse und nur die gewünschten Events zu simulieren.
    (Synthetisierte Events klappen auch nicht immer so, wie die originalen Events?!)

    Kann ich die Events im Hook zwischenspeichern und später (nach RawInput) erst weiterleiten?

    Am besten wäre, wenn ich Windows mitteilen könnte, daß z.B. Maus A nicht als Maus behandelt werden soll.
    Dazu müsste ich aber einen Filtertreiber schreiben, der für USB und PS/2 funktioniert und das kann/will ich nicht!

    Ich glaube mal gelesen zu haben, daß mein Vorhaben mit DirectInput gehen könnte - weiß jemand mehr?

    thx

  • Ich glaub, ich hab mir da eben die Lösung selber geschrieben!

    Ich speichere einfach die Events im Hook in globale Variablen und führe sie erst beim nächsten mal aus.

    [autoit]

    Func _MouseHook_Proc_LL($nCode, $wParam, $lParam)
    If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hMouse_Hook_LL, $nCode, $wParam, $lParam)

    [/autoit][autoit][/autoit][autoit]

    Local $iMouse_Event = BitAND($wParam, 0xFFFF)
    ;If $iMouse_Event = 512 Then Return 1
    If $Block Then Return 1

    [/autoit][autoit][/autoit][autoit]

    Local $Return=_WinAPI_CallNextHookEx($hMouse_Hook_LL, $_nCode, $_wParam, $_lParam)
    $_nCode = $nCode
    $_wParam = $wParam
    $_lParam = $lParam

    [/autoit][autoit][/autoit][autoit]

    Return $Return
    EndFunc ;==>_MouseHook_Proc_LL

    [/autoit]

    Das scheint mal ganz gut zu klappen, obwohl die Events eigentlich um 1 hinterherhinken ^^
    Werd das mal austesten...

    Edit: falscher Alarm :( das kann ja nicht klappen :wacko:

    Edit 2: könnte man die Events mit JournalRecord und JournalPlayback Hooks aufzeichnen, filtern und dann abspielen?