Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Herausfinden, ob Fenster sichtbar ist (https://www.delphipraxis.net/121310-herausfinden-ob-fenster-sichtbar-ist.html)

littleDave 25. Sep 2008 14:27


Herausfinden, ob Fenster sichtbar ist
 
Servus :hi:
Ich hab da mal ne Frage:

Gibt es eine Möglichkeit herauszufinden, ob ein Fenster bzw. ob ein Teil eines Fensters überhaupt sichtbar ist oder ob das Fenster komplett von einem anderen Fenster (nicht auf ein Programm beschrenkt) verdeckt wird? Ich suche nicht die Funktion IsWindowVisible.

Hintergrund:
Für meine Desktop Widget Engine verwende ich die Funktion UpdateLayeredWindow. Bevor diese Funktion jedoch ausgeführt wird, muss das Window-Bitmap erst erstellt werden - dies kann ziemlich viel Resourcen fressen. Nun wollt ich CPU-Resourcen sparen und erstmal schauen, ob das Update überhaupt für den User sichtbar ist. Daher bräuchte ich eine Funktion, die mir sagt, ob das Fenster überhaupt sichtbar ist.

Grüße
Dave

toms 25. Sep 2008 18:11

Re: Herausfinden, ob Fenster sichtbar ist
 
Hallo, dafür eignet sich die GetClipBox API.

Delphi-Quellcode:
type
  TVisibleStatus = (vsHidden, vsVisible, vsPartVisible);

function TForm1.GetVisibleStatus(wnd: HWND): TVisibleStatus;
var
  Clip: Integer;
  hDC: THandle;
  ClipRect, ClientRect: TRect;
begin
  hDC := GetDC(wnd);
  Clip := GetClipBox(hDC, ClipRect);
  case Clip of
    NULLREGION: Result := vsHidden; // Fenster ist komplett versteckt
    SIMPLEREGION:
      begin
        ClientRect := GetClientRect;
        if EqualRect(ClipRect, ClientRect) then // vollständig sichtbar
          Result := vsVisible //ClientRect ist sichtbar
        else //teils sichtbar
          Result := vsPartVisible; //ClientRect ist sichtbar
      end;
    COMPLEXREGION: // Region besteht aus mehr als einem Rechteck, Fenster ist teils sichtbar
      Result := vsPartVisible;
  end;
  ReleaseDC(Handle, hDC);
end;

littleDave 25. Sep 2008 18:50

Re: Herausfinden, ob Fenster sichtbar ist
 
Danke für den Code - der Funktioniert an sich sehr gut, nur leider nicht bei meinem Problem :-(.

Meine Fenster sind vom Style her WS_EX_LAYERED. Ich hab nach GetClipRgn + WS_EX_LAYERED gesucht und hab in einem C++Forum gefunden, dass diese Kombination nicht funktioniert - schade.

Hast du sonst noch ne Idee, wie ich das hinkriegen könnte?

a.def 22. Nov 2016 17:13

AW: Herausfinden, ob Fenster sichtbar ist
 
:hi: Ich benutze diese Funktion schon seit längerer Zeit und habe sie heute aus der Hauptform raus in eine neue Unit umgezogen. Leider funktioniert die Funktion dann nicht mehr, da eine Windows-Funktion statt der Funktion in Forms.pas verwendet wird:

Delphi-Quellcode:
ClientRect := GetClientRect;
Ein Forms.GetClientRect; oder Forms.TCustomForm.GetClientRect; funktioniert leider nicht. Was muss man hier schreiben, damit die Forms.pas-Funktion verwendet wird?

Der schöne Günther 22. Nov 2016 17:21

AW: Herausfinden, ob Fenster sichtbar ist
 
Das war schon richtig: Nur der vollständige Name der Unit aus welcher du das nehmen möchtest ist
Delphi-Quellcode:
Vcl.Forms
, nicht
Delphi-Quellcode:
Forms
. Es würde dementsprechend heißen
Delphi-Quellcode:
Vcl.Forms.TCustomForm.GetClientRect()
.

Konjunktiv, da
Delphi-Quellcode:
GetClientRect()
an eine
Delphi-Quellcode:
TCustomForm
-Instanz gebunden ist und keine statische Methode ist die man einfach so aufrufen kann: Du brauchst eine Form dafür, also z.B.
Delphi-Quellcode:
meinRect := meineForm.GetClientRect()
Das
Delphi-Quellcode:
meineForm
wirst du deiner Methode ja irgendwie übergeben, oder?
Kannst du vlt. die Unit mit der Methode wie du es momentan hast posten?

DeddyH 22. Nov 2016 17:22

AW: Herausfinden, ob Fenster sichtbar ist
 
Du rufst ja die Methode einer TCustomForm-Instanz auf, also musst Du auch diese Instanz mit angeben.
Delphi-Quellcode:
ClientRect := FormInstanz.GetClientRect;

a.def 22. Nov 2016 17:27

AW: Herausfinden, ob Fenster sichtbar ist
 
Meine aktuelle Funktion sieht momentan so aus. Ich habe nur die markierte Stelle geändert aber leider habe ich keinen Zugriff auf GetClientRect.

Delphi-Quellcode:
function GetVisibleStatus(const PForm: TForm): TVisibleStatus;
var
 Clip: Integer;
 hDC: THandle;
 ClipRect, ClientRect: TRect;
begin
 hDC := GetDC(PForm.Handle);
 Clip := GetClipBox(hDC, ClipRect);

 case Clip of
  NULLREGION:
   Result := vsHidden; // Fenster ist komplett versteckt
  SIMPLEREGION:
   begin
    ClientRect := PForm.GetClientRect; // nur das hier habe ich geändert

    if EqualRect(ClipRect, ClientRect) then // vollständig sichtbar
     Result := vsVisible // ClientRect ist sichtbar
    else // teils sichtbar
     Result := vsPartVisible; // ClientRect ist sichtbar
   end;
  COMPLEXREGION: // Region besteht aus mehr als einem Rechteck, Fenster ist teils sichtbar
   Result := vsPartVisible;
 end;

 ReleaseDC(Handle, hDC);
end;
Die letzte Zeile verstehe ich auch nicht. Müsste da nicht eigentlich PForm.Handle stehen und nicht Handle?

DeddyH 22. Nov 2016 17:37

AW: Herausfinden, ob Fenster sichtbar ist
 
Wie ist es so (ungetestet)?
Delphi-Quellcode:
function GetVisibleStatus(const PForm: TForm): TVisibleStatus;
var
 Clip: Integer;
 hDC: THandle;
 ClipRect, ClientRect: TRect;
begin
  Assert(Assigned(PForm), 'Keine TCustomForm-Instanz übergeben');
  hDC := GetDC(PForm.Handle);
  if hDC <> 0 then
    try
      Clip := GetClipBox(hDC, ClipRect);
     
      case Clip of
        NULLREGION:
          Result := vsHidden; // Fenster ist komplett versteckt
        SIMPLEREGION:
          begin
            ClientRect := PForm.ClientRect; // Property statt protected Getter
           
            if EqualRect(ClipRect, ClientRect) then // vollständig sichtbar
              Result := vsVisible // ClientRect ist sichtbar
            else // teils sichtbar
              Result := vsPartVisible; // ClientRect ist sichtbar
          end;
        COMPLEXREGION: // Region besteht aus mehr als einem Rechteck, Fenster ist teils sichtbar
          Result := vsPartVisible;
      end;
    finally
      ReleaseDC(PForm.Handle, hDC);
    end;
end;

a.def 22. Nov 2016 17:53

AW: Herausfinden, ob Fenster sichtbar ist
 
Das funktioniert jetzt glücklicherweise. Zwar nicht mit dem Hauptformular, aber da brauche ich die Funktion eh nicht.

Ist ein Fenster komplett sichtbar, kommt trotzdem vsPart zurück.
Ich rufe die Funktion eine Hand voll mal auf und vergleiche immer auf <> TVisibleStatus.vsHidden. Von daher ist es egal, ob vsVisible oder vsPart.

Benmik 27. Dez 2016 13:54

AW: Herausfinden, ob Fenster sichtbar ist
 
Schöne Sache, habe ich mir mal beiseite gelegt, kann ich bestimmt mal brauchen.

Die Frage sollte allerdings mal als "erledigt" gekennzeichnet werden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:54 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz