Rubrik: Oberfläche · Sonstiges | VB-Versionen: VB6 | 06.06.11 |
Hat die eigene Anwendung den Fokus? Fokusermittlung per Subclassing: WM_ACTIVATEAPP | ||
Autor: Ralf Schlegel | Bewertung: | Views: 10.088 |
www.vb-zentrum.de | System: Win2k, WinXP, Win7, Win8, Win10, Win11 | Beispielprojekt auf CD |
Mit den Prozeduren Form_GotFocus und Form_LostFocus können wir ermitteln, ob die aktuelle Form gerade aktiv ist (den Fokus hat). Manchmal wäre es jedoch besser zu wissen, ob die gesamte Anwendung den Fokus hat, oder nicht. So lassen sich z.B. aufwendigere Hintergrundarbeiten erledigen, wenn der Beutzer gerade mit einer anderen Anwendung arbeitet.
Hierfür stellt uns das Windows API die Konstante WM_ACTIVATEAPP zur Verfügung, die wir über das Subclassing unserer Hauptform als Message erhalten. Wir benötigen also den folgenden Code in einem neuen Modul (z.B.: appFocus.bas):
Option Explicit Private Declare Function CallWindowProc Lib "user32" _ Alias "CallWindowProcA" ( _ ByVal lpPrevWndFunc As Long, _ ByVal hWnd As Long, _ ByVal Msg As Long, _ ByVal wParam As Long, _ ByVal lParam As Long) As Long Private Declare Function SetWindowLong Lib "user32" _ Alias "SetWindowLongA" ( _ ByVal hWnd As Long, _ ByVal nIndex As Long, _ ByVal dwNewLong As Long) As Long Private Const GWL_WNDPROC = -4 Private Const WM_ACTIVATEAPP = &H1C ' Locale Variablen: Private mainOldProc As Long ' Pointer auf original Fensterprozedur Global glbAppActive As Boolean ' globale Überwachungsvariable
' Subclassing initialisieren: Public Sub MainHook(ByVal hWnd As Long) glbAppActive = True ' Wenn wir starten, sind wir die aktive Anwendung mainOldProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf winMain) End Sub
' Subclassing beenden: Public Sub MainUnHook(ByVal hWnd As Long) SetWindowLong hWnd, GWL_WNDPROC, mainOldProc End Sub
' Unsere Erweiterung der Fensterprozedur: Private Function winMain(ByVal hWnd&, ByVal uMsg&, _ ByVal wParam&, ByVal lParam&) As Long Select Case uMsg Case WM_ACTIVATEAPP If wParam Then ' Anwendung wurde aktiviert glbAppActive = True Else ' Anwendung wurde deaktiviert glbAppActive = False End If End Select winMain = CallWindowProc(mainOldProc, hWnd, uMsg, wParam, lParam) End Function
In der Hauptform unserer Anwendung rufen wir dann in der Load Anweisung die Funktion 'MainHook' und in der QueryUnload Anweisung UNBEDINGT 'MainUnHook' auf, sonst stürzt die IDE ab! Das war schon alles.
Die globale Variable glbAppActive kann dann z.B. über einen Timer abgefragt werden. Bei der Initialisierung des Hooking muß die Variable glbAppActive zunächst 'manuell' auf True gesetzt werden: da wir beim Programmstart schon die aktive Anwendung sind, wird nämlich kein weiteres WM_ACTIVATEAPP Ereignis ausgelöst.
Verfügt Ihre Anwendung bereits über ein Hooking, so ist es noch einfacher:
legen Sie in Ihrem Modul die globale Variable glbAppActive und die Konstante WM_ACTIVATEAPP an und erweitern Sie in Ihrer Hooking Funktion (hier winMain) die Abfrage von uMsg wie oben im Quellcode zu sehen.