*Mausklick* ohne Klickbefehl in Windoof auszuführen via hooking

  • He HE,

    ich hab mal gehört bzw. irgendwo gelesen, dass man einen Mausklick via hooking abfangen kann ohne das er selber ausgeführt wird.
    Statt dessen soll ein anderer Algorythmus ausgeführt werden (das hab ich aber soweit schon selber hinbekommen).

    Hab schon sehr viel gegooglet und das Forum durchforstet, bin über Hilfe sehr dankbar.

    gruß ABe

    • Offizieller Beitrag

    Hi,
    ich hab dir mal ein Bsp. gemacht.
    Immer schön aufpassen, dass der Hook nur für ein bestimmtes Ctrl /GUI gültig ist. Ansonsten schießt du dir die Maus ab. :D

    [autoit]

    #include <WinAPI.au3>
    #include <WindowsConstants.au3>
    #include <StructureConstants.au3>

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

    Global Const $HC_ACTION = 0
    Global Const $WM_LBUTTONDOWN = 0x201

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

    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)
    Global $gui, $btn1, $btn2

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

    $gui = GUICreate('Mouse-Hook', 400, 300)
    GUICtrlCreateLabel('Der Klick auf den Button 1 bleibt wirkungslos', 10, 10, 380)
    $btn1 = GUICtrlCreateButton('Button 1', 20, 40, 100, 20)
    $btn2 = GUICtrlCreateButton('Button 2', 150, 40, 100, 20)
    GUISetState()

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

    While 1
    $msg = GUIGetMsg()
    Switch $msg
    Case -3
    Exit
    Case $btn1
    MsgBox(0, '', 'Button 1 geklickt')
    Case $btn2
    MsgBox(0, '', 'Button 2 geklickt')
    EndSwitch
    WEnd

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

    Func _MouseProc($nCode, $wParam, $lParam)
    If $nCode < 0 Or (Not _MouseOverCtrl($gui, $btn1)) Then
    Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    EndIf
    If $nCode = $HC_ACTION And $wParam = $WM_LBUTTONDOWN Then
    ; hier kann Ersatzfunktion aufgerufen werden
    Return -1 ; Mausklick wird ignoriert
    EndIf
    Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    EndFunc

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

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

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

    Func _MouseOverCtrl($GUI, $ID)
    If Not BitAND(WinGetState($GUI), 8) Then Return False
    Local $old = Opt('MouseCoordMode', 2)
    Local $posM = MouseGetPos()
    Opt('MouseCoordMode', $old)
    Local $posC = ControlGetPos($gui, '', $ID)
    If ($posM[0] >= $posC[0] And $posM[0] <= $posC[0]+$posC[2]) And _
    ($posM[1] >= $posC[1] And $posM[1] <= $posC[1]+$posC[3]) Then
    Return True
    Else
    Return False
    EndIf
    EndFunc

    [/autoit]
  • Sorry aber ich verstehe es nicht so ganz.
    Wie einen Klick ausführen, wenn man ihn gar nicht macht ?( 8|

    • Offizieller Beitrag

    Wie einen Klick ausführen, wenn man ihn gar nicht macht


    Stimmt, du hast es völlig falsch verstanden. ;)
    Es geht darum, bei einem Mausklick die zugehörige Aktion abzufangen und durch eine andere zu ersetzen. Dieses Abfangen nennt man Hook. In meinem Bsp. Kannst du mit der Maus auf Button1 klicken so oft du willst - der Button wird einfach nicht betätigt, der Klick landet in diesem Fall im Nirvana.

  • "Früher" hat man Interrupts verbogen bzw abgefangen, heute macht man das mit einem Hook. Die Vorgehensweise ist dieselbe. Ein Ereignis wird vor der Abarbeitung der Ereignis-Funktion abgefangen und statt dessen eine eigene Funktion ausgeführt. Nun kann man noch auswählen, ob die ursprünglich gedachte Ereignis_Funktion nach der eigenen ausgeführt wird oder nicht.
    Siehe dazu auch Callback und in AutoIt in der Hilfe nach $GUI_RUNDEFMSG.