2017-10-31 4 views
0

Ich möchte alle Fenster überwachen ist global angelegt. Die nächstgelegene API gefunden ist SetWinEventHook auf EVENT_OBJECT_CREATE, ist es jedoch nicht nur Haken Fenster zur Erstellung, sondern auch kontrolliert. Ich frage mich, ob es irgendeinen Weg gibt, der nicht zu viel kostet, und nicht nur CBT-Windows einhängen kann.Globale Haken für Fenster Erstellung/maximieren/minimieren etc in C#

Ich habe versucht, IsWindow() zu verwenden, um festzustellen, ob der Callback-HWND ein Fenster HWND ist, aber es scheint immer True zurückgegeben, unabhängig davon, ob das HWND ein Fenster oder ein Steuerelement ist.

Ich würde es vorziehen verwaltete api verwenden, anstatt das Hinzufügen anderen dlls, obwohl, wenn es absolut notwendig ist, es noch eine offene Option.

Schließlich, wie kann ich einhaken die Fenster maximieren, minimieren und Ereignisse wieder herstellen? Versucht EVENT_OBJECT_STATECHANGE, aber es scheint nicht der richtige zu sein. Versucht EVENT_SYSTEM_MOVESIZESTART und EVENT_SYSTEM_MOVESIZEEND, erfasst aber auch nicht die Max/Min/Restore-Ereignisse.

private List<IntPtr> _hooks; 
private User32ex.WinEventDelegate _delegate; 

private void StartService() { 
    _delegate = WinEventProc; 
    _hooks.Add(User32ex.SetWinEventHook(User32.WindowsEventHookType.EVENT_OBJECT_CREATE, User32.WindowsEventHookType.EVENT_OBJECT_DESTROY, IntPtr.Zero, _delegate, 0, 0, User32.WindowsEventHookFlags.WINEVENT_OUTOFCONTEXT)); 
    // Other hooks 
} 

private void WinEventProc(IntPtr hWinEventHook, User32.WindowsEventHookType eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) { 
    if (hwnd == IntPtr.Zero || !User32.IsWindow(hwnd)) return; 

    switch (eventType) { 
     case User32.WindowsEventHookType.EVENT_OBJECT_CREATE: 
      Debug.Print($"Create: {hwnd}"); 
      // Do something - here captures all objects not only windows but also controls etc 
      break; 
     case User32.WindowsEventHookType.EVENT_OBJECT_STATECHANGE: 
      Debug.Print($"State change: {hwnd}"); 
      // Do something 
      break; 
     // Other cases 
    } 
} 

im Voraus Vielen Dank:

Teilcode kann wie folgt gesehen werden!

+0

Sie müssten wahrscheinlich überprüfen, welche Fenster Stile auf das Handle angewendet werden. – Lloyd

+0

Die übliche Antwort auf eine vage Frage wie diese finden Sie im System.Windows.Automation-Namespace. –

+0

@Lloyd Danke. Welcher WS würde Windows und Controls definitiv trennen? Vielen Dank! –

Antwort

1

Willkommen in der schönen Welt der Windows-API! Der Grund, warum Ihr Hook nicht nur "Windows", sondern auch "Steuerelemente" hakt, ist, dass in Windows sowohl "Windows" als auch "Steuerelemente" nur Fenster sind. Es kann verschiedene Arten von Fenstern geben, die anders aussehen und sich anders verhalten; Steuerelemente sind nur Fenster mit bestimmten Aussehen und spezifischen Verhaltensweisen.

Da alle von ihnen nur Fenster, können Sie nicht nur Haken auf „Fenster“ auf „Kontrollen“ zur gleichen Zeit nicht einhaken. Wenn Sie jedoch bereits mit einem verknüpft sind, können Sie feststellen, ob es sich bei dem Fenster, an das Sie sich gebunden haben, um das Fenster handelt, das Sie haken möchten. Wie in den Kommentaren vorgeschlagen, können Sie Fenster Stile verwenden:

// this is a pretty crude and basic way to sort out "controls" 
BOOL isControl_KindOf = GetWindowLong(hwnd, GWL_STYLE) & WS_CHILD; 
+0

Danke. Wie wäre es mit MDI Kind? Hat es auch WS_CHILD? –

+0

Ich konnte mich nicht daran erinnern, also musste ich msdn googlen. Anscheinend benötigen Sie einen anderen Ausdruck, um mdi Kinderfenster zu identifizieren, dh (GetWindowLong (hwnd, GWL_STYLE_EX) & WS_EX_MDICHILD). – rs232

+0

Danke, ich werde es versuchen :) –