Finde alle Fenster unter einem Punkt

8

Ich möchte alle Top-Level-Fenster (Kinder des Desktops) unter einem bestimmten Punkt auf dem Desktop finden. Ich kann keine API dafür finden.

Mein Szenario ist, dass ich ein Fenster über den Bildschirm ziehe und es in ein anderes (bekanntes) Fenster fallen lassen möchte. Ich kann die Grenzen des Zielfensters testen, aber das sagt mir nicht, ob es durch ein anderes (unbekanntes) Fenster verdeckt ist. Die Verwendung von WindowFromPoint und Freunden funktioniert nicht, da sich das Fenster, das gezogen wird, notwendigerweise direkt unter der Maus befindet. Ich frage mich also, ob ich alle Fenster an der Mausposition abrufen kann und sie überprüfen kann, ob eines der Fenster, die ich tracking, direkt unter dem Fenster ist, das ich schleppe.

Gibt es eine Möglichkeit, dies zu tun, ohne bei jedem Mausziehen auf EnumDesktopWindows / GetWindowRect zurückgreifen zu müssen? Oder vielleicht gibt es eine andere Lösung, die ich vermisse.

    
Drew Noakes 25.05.2016, 20:08
quelle

2 Antworten

4

Wenn Sie freundlich fragen, ignoriert WindowFromPoint Ihr Fenster (das gerade gezogene Fenster) und gibt das nächste Fenster zurück. Dies ist, was Internet Explorer tut, wenn Sie eine Registerkarte ziehen.

Um das zu tun:

  1. Behandle WM_NCHITTEST im Fenster, das gezogen wird
  2. Gibt HTTRANSPARENT beim Ziehen zurück. Rufen Sie andernfalls das Standard-Fenster-Proc auf.
  3. WindowFromPoint ignoriert HTTRANSPARENT windows, aber nur diejenigen, die zum Aufrufer gehören Faden. Dies sollte kein Problem für Sie sein, da Sie sowieso WindowFromPoint vom Fenstereigenthread aufrufen sollten.
  4. Stellen Sie sicher, dass keine untergeordneten Fenster an einem Punkt an WindowFromPoint übergeben werden oder behandeln Sie auch WM_NCHITTEST für diese untergeordneten Fenster.

Fehlerbehebung (wenn Sie Ihr Fenster immer noch von WindowFromPoint erhalten)

  1. Testen Sie GetCurrentThreadID() == GetWindowThreadProcessId(WindowFromPoint(), 0) , um sicherzustellen, dass Sie vom richtigen Thread
  2. aus anrufen
  3. In WM_NCHITTEST , teste, dass der hwnd Parameter dem entspricht, was du von WindowFromPoint() bekommst

Beispiel (der Bereich innerhalb des Rechtecks ​​gibt das zugrunde liegende Fenster von WindowFromPoint zurück):

%Vor%     
Codeguard 25.11.2016, 23:06
quelle
3

Richtig, Sie wissen bereits, was WindowFromPoint () zurückgeben soll, sollte das sein, das Sie ziehen. Dann verwenden Sie GetWindow () mit uCmd = GW_HWNDNEXT um den einen darunter in der Z-Reihenfolge zu bekommen. GetWindowRect (), um seine Grenzen zu erhalten, IntersectRect (), um die Überlappung zu berechnen.

Rufen Sie GetWindow () auf, um weitere überlappende Fenster zu finden. Bis es NULL zurückgibt oder die Überlappung gut genug ist. Wenn nicht, dann bevorzugen Sie normalerweise denjenigen mit dem größten Ergebnis-Rechteck von IntersectRect ().

    
Hans Passant 22.11.2016 15:35
quelle

Tags und Links