Event - OnFocusChange

  • Hallo zusammen,

    ich bräuchte wieder mal Eure Hilfe. Habe mit der Suchfunktion und Google leider nichts gefunden.

    Ich muss mit meinem Programm überprüfen, ob der Fensterfokus geändert hat.
    Also beim starten meines Programms (welches keine GUI hat) ist der Fokus auf einem beliebigen Fenster. Wenn ich nun mit der Maus oder mit der Tastatur (oder durch einen Systemgenerierten Event wie Geplanter Task) ein neues Fenster öffne oder einfach nur den Fokus auf ein beliebiges anderes Fenster setze, dann möchte ich mit meinem Programm in eine Funktion springen!

    Bis jetzt löse ich das so, dass ich mit AdlibRegister alle 200ms den aktiven Fenstertitel abfrage. Wenn der Titel anders ist, als bei der letzten Prüfung, dann werden diverse Dinge ausgeführt.
    Dies funktioniert zwar gut, jedoch mit zwei Einschränkungen:

    • Wenn ich schneller als 200ms reagieren möchte, dann nimmt die CPU Last auf älteren PCs deutlich zu.
    • Wenn ich mit Alt+Tabulator (Win7) den Fensterfokus ändere, dann wird oft das "Fenster" Programmumschaltung als neues Fenster detektiert. Dies soll aber verhindert werden. (Und zwar nicht nur im deutschsprachigen Windows, sondern auch in allen anderen Sprachen!!)

    Wie könnte man einen Event generieren, der nur bei Fenster-Fokusänderungen eine Funktion aufruft?
    Bei GUIRegisterMsg habe ich leider nichts entsprechendes gefunden.

    Vielen Dank für Eure Hilfe!
    Veronesi

    Einmal editiert, zuletzt von veronesi (7. April 2011 um 14:06)

  • Hi Eukalyptus

    Bei Fragen einfach melden! :)

    Naja, vielleicht liegt es auch daran, dass ich momentan wirklich FAST keine Zeit für dieses Thema habe.... Aber ich verstehe die Funktion momentan nicht wirklich. Es ist aufwändiger als ich dachte.

    OT:
    Aber Dein IconDock ist sehr gelungen! Ich erlaube mir einfach mal Ideen daraus (rein optische, keine Softwareteile) für mich zu übernehmen. Ich versuche dann mal an einem Wochenende so etwas selber zu programmieren.

    Trotzdem danke. Ich werde wohl aus Zeitgründen momentan bei meiner Lösung bleiben (müssen).
    Gruss Veronesi

  • Hier ein kurzes Beispiel:

    [autoit]

    OnAutoItExitRegister("_DeRegister")

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

    HotKeySet("{ESC}", "_Exit")

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

    Global Const $EVENT_SYSTEM_FOREGROUND = 0x03
    Global $hProc, $hHook

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

    _RegisterWinEvent()

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

    While 1
    Sleep(5000)
    WEnd

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

    Func _RegisterWinEvent()
    Local $hProc = DllCallbackRegister("_WinEventProc", "none", "hwnd;int;hwnd;long;long;int;int")
    Local $aRet = DllCall("User32.dll", "hwnd", "SetWinEventHook", "uint", $EVENT_SYSTEM_FOREGROUND, "uint", $EVENT_SYSTEM_FOREGROUND, "hwnd", 0, "ptr", DllCallbackGetPtr($hProc), "int", 0, "int", 0, "uint", 0x2)
    If Not @error And IsArray($aRet) Then $hHook = $aRet[0]
    EndFunc ;==>_RegisterWinEvent

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

    Func _WinEventProc($hHook, $iEvent, $hWnd, $idObject, $idChild, $iEventThread, $iEventTime)
    Switch $iEvent
    Case $EVENT_SYSTEM_FOREGROUND
    Switch $hWnd
    Case 0
    Case Else
    ToolTip("Fenster: " & $hWnd & " Hat den Fokus", 10, 10)
    EndSwitch
    EndSwitch
    EndFunc ;==>_WinEventProc

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

    Func _DeRegister()
    DllCall("user32.dll", "int", "UnhookWinEvent", "hwnd", $hHook)
    DllCallbackFree($hProc)
    EndFunc ;==>_DeRegister

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

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

    [/autoit]

    E

  • Hey, super! Vielen Dank!
    Alles läuft einwandfrei!

    Allerdings wäre ich nie auf die Idee gekommen, dass in der User32.dll so ein Fenter-Hook erzeugt werden kann.
    Wie kommt man darauf?
    Und was gibt es sonst noch so spannendes dort? Du arbeitetst ja mit $Event_System_Foreground = 0x03
    Hast Du einen Link, wo ich Informationen darüber finde?

    Besten Dank!
    Grüsse Veronesi