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/)
-   -   Erkennen ob ein Fenster verdeckt wird (https://www.delphipraxis.net/209260-erkennen-ob-ein-fenster-verdeckt-wird.html)

dataspider 16. Nov 2021 13:14

Erkennen ob ein Fenster verdeckt wird
 
Hallo

Beispiel:
Ich habe auf einem cxPageControl 2 Tabs mit jeweils einem Form drauf.
Kann ich beim Wechsel der aktiven Page im Formular mitbekommen (z.B. WndProc o.a.),
dass das eine Formulat quasi nicht mehr sichtbar ist, dafür aber das Andere?

Ich weiss, embedded Forms war nicht die beste Idee, will ich aber jetzt nicht mehr ändern.
Ausserdem habe ich eigentlich alles gelöst, ausser eben dieses Problem.

Danke, Frank

venice2 16. Nov 2021 13:19

AW: Erkennen ob ein Fenster verdeckt wird
 
Zitat:

Kann ich beim Wechsel der aktiven Page im Formular mitbekommen (z.B. WndProc o.a.),
Hmmm..
Prüfe doch einfach welches Tab\Seite aktiv ist dann weist du es doch.

Klaus01 16. Nov 2021 13:22

AW: Erkennen ob ein Fenster verdeckt wird
 
.. kannst Du dazu nicht das Ereignis onHide der Form hernehmen?
Das sollte doch gefeuert werden wenn die Form verdeckt wird -oder?

Grüße
Klaus

venice2 16. Nov 2021 13:23

AW: Erkennen ob ein Fenster verdeckt wird
 
Zitat:

Zitat von Klaus01 (Beitrag 1497649)
.. kannst Du dazu nicht das Ereignis onHide der Form hernehmen?
Das sollte doch gefeuert werden wenn die Form verdeckt wird -oder?

Grüße
Klaus

Kann mir nicht vorstellen das eine Form unsichtbar wird nur weil eine andere Seite des Tabs aktiviert wird.
Diese wird lediglich in den Hintergrund gesetzt mit dem nicht aktiven Tab.
Und nein. Nur weil eine Form bedeckt\verdeckt wird muß diese nicht gleich unsichtbar sein.

Klaus01 16. Nov 2021 13:38

AW: Erkennen ob ein Fenster verdeckt wird
 
.. dann könnte das Event onDeactivate/onActivate das richtige sein?

Grüße
Klaus

dataspider 16. Nov 2021 13:40

AW: Erkennen ob ein Fenster verdeckt wird
 
Zitat:

Zitat von venice2 (Beitrag 1497648)
Zitat:

Kann ich beim Wechsel der aktiven Page im Formular mitbekommen (z.B. WndProc o.a.),
Hmmm..
Prüfe doch einfach welches Tab aktiv ist dann weist du es doch.

Das kann man machen, würde ich aber gern vermeiden.
Ich bin soweit, dass ich die ganze Steuerung (aktives Form, aktives Datasource etc.) quasi an einer zentralen Stelle habe.
Ich hätte es gern so, dass ich dann, wenn ich ein PageControl mit Forms verwende, nich daran denken muss, das Event OnPageChanged zu setzten,
zumal ich dieses evtl. anderweitig bräuchte.
Es muss dann einfach funktionieren.

Frank

dataspider 16. Nov 2021 13:41

AW: Erkennen ob ein Fenster verdeckt wird
 
Zitat:

Zitat von Klaus01 (Beitrag 1497651)
.. dann könnte das Event onDeactivate/onActivate das richtige sein?

Grüße
Klaus

Das ist ja mein Problem, dass dies bei embedded Forms nicht funktioniert.

Delphi.Narium 16. Nov 2021 13:42

AW: Erkennen ob ein Fenster verdeckt wird
 
Kurzer Test mit 'nem Form, 'nem Button, 'nem TPageControl mit zwei Tabs und auf jedem Tab ein Panel.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  if Panel1.Visible then ShowMessage('Panel1'); // ist immer erfüllt, egal welcher Tab aktiv
  if Panel2.Visible then ShowMessage('Panel2'); // ist immer erfüllt, egal welcher Tab aktiv
  if Panel1.Parent.Visible then ShowMessage('Parent Panel1'); // ist nur erfüllt, wenn Tab 1 sichtbar
  if Panel2.Parent.Visible then ShowMessage('Parent Panel2'); // ist nur erfüllt, wenn Tab 2 sichtbar
end;
Es könnte also (mit etwas Glück) ausreichen, auf die Sichtbarkeit des Parents der Formulare abzufragen.

venice2 16. Nov 2021 13:47

AW: Erkennen ob ein Fenster verdeckt wird
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1497654)
Kurzer Test mit 'nem Form, 'nem Button, 'nem TPageControl mit zwei Tabs und auf jedem Tab ein Panel.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  if Panel1.Visible then ShowMessage('Panel1'); // ist immer erfüllt, egal welcher Tab aktiv
  if Panel2.Visible then ShowMessage('Panel2'); // ist immer erfüllt, egal welcher Tab aktiv
  if Panel1.Parent.Visible then ShowMessage('Parent Panel1'); // ist nur erfüllt, wenn Tab 1 sichtbar
  if Panel2.Parent.Visible then ShowMessage('Parent Panel2'); // ist nur erfüllt, wenn Tab 2 sichtbar
end;
Es könnte also (mit etwas Glück) ausreichen, auf die Sichtbarkeit des Parents der Formulare abzufragen.

So ist es.
Es reicht einfach wie im ersten Beitrag schon gesagt die aktive Seite vom Tab abzufragen alles andere ist Sinnlos.

Denn nur weil das Child Window in dem Fall als bsp. das Panel auf dem alle Komponenten abgelegt sind unsichtbar\in den Hintergrund geschaltet wird
bleiben die anderen Komponente trotzdem sichtbar.
Das betrifft also auch deine Formen die dort abgelegt sind.

Wenn ich meine Küchentür öffne dann sehe ich die Küche wird sie hingegen geschlossen dann sehe ich sie nicht mehr.
Bedeutet aber nicht das diese nun nicht mehr sichtbar ist. Es wird einem nur die Sicht darauf genommen.

dataspider 16. Nov 2021 14:08

AW: Erkennen ob ein Fenster verdeckt wird
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe mal mein "Spiel - Projekt" angehangen. (erfordert DevExpress)
So ist es vielleicht besser verständlich.
Der Code ist natürlich nicht sauber...

Ich verwende einen MouseHook, Screen.OnActiveContolChange und WMMouseActivate der BasisForm.
Damit kann ich fast alles bekommen.
Wenn ich mich aber z.B. mit der Tab - Taste bis zum Aktivieren einer Page vorarbeite,
kann ich mit den Cursortasten die aktive Page wechsel und bekomme davon nichts mit.
Daher wäre es ideal, wenn die Form irgendeine Nachricht erhalten würde.

Frank

venice2 16. Nov 2021 14:17

AW: Erkennen ob ein Fenster verdeckt wird
 
Ich versuche es noch einmal.

Du hast keine Möglichkeit auf die Form hin zu prüfen ob diese Sichtbar\Verdeckt ist oder nicht.
Denn Sichtbar ist sie immer auch im verdeckten zustand.
Außer wie @Delphi.Narium schon sagte über den Visible Status des entsprechenden Panels oder direkt über Tab\Seite.
Was hält dich davon ab einfach eine Variable BOOL mit welchen Namen auch immer einzusetzen und den Stand daraufhin zu prüfen welche Seite gerade aktiv ist.

Mein Rat!
Lasse dir diesbezüglich etwas anderes einfallen.

Bsp.
EDIT:
Delphi-Quellcode:
const
  F_VISIBLE = WM_USER + 100;
var
  bVisibleState: BOOL;
...
// Bei jedem Klick auf ein Panel ob über Tasten oder Maus sendest du eine Message an deine Winproc
// Auf bVisibleState hin prüfen und welche Tab Seite aktiv ist

SendMessage(Self.Handle, F_VISIBLE, bVisibleState, LParam);

// In der Winproc wertest du jetzt aus.
  case (Msg) of
    F_VISIBLE:
      //tu was
oder du erstellst dein eigenes Event.

Bin raus..

Delphi.Narium 16. Nov 2021 14:35

AW: Erkennen ob ein Fenster verdeckt wird
 
Mir ist (vermutlich) die Fragestellung noch nicht klar geworden:

Möchtest Du im Formular nachfragen, ob das Formular für den Anwender sichtbar ist, sich also auf der aktiven Seite des PageControl befindet?

Oder möchtest Du beim Wechsel der aktiven Seite des PageControls im Formular quasi eine Reaktion der Art "Ups, ich bin gerade sichtbar geworden" bzw. "och nö, man kann mich ja garnichtmehr sehen" auslösen?

Das Erste sollte mit meinem Vorschlag funktionieren.

Das zweite könntest Du eventuell durch das Schicken einer eigenen Message beim Seitenwechsel auslösen. Kommt diese Message, prüfen die empfangenden Formulare jeweils analog zu meinem Vorschlag.

Als "Versandort" für diese Message fiele mir da nur das OnChange-Ereignis des PageContols ein.

dataspider 16. Nov 2021 14:55

AW: Erkennen ob ein Fenster verdeckt wird
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1497662)

Oder möchtest Du beim Wechsel der aktiven Seite des PageControls im Formular quasi eine Reaktion der Art "Ups, ich bin gerade sichtbar geworden" bzw. "och nö, man kann mich ja garnichtmehr sehen" auslösen?

Genau das...
Sorry, dass das nicht verständlich rüber kam.
Ich hatte die Hoffnung, dass ich mir die Zuweisung des OnActivePageChanged bei jedem PageControl ersparen kann.

Vielen Dank an alle Beteiligten!

Frank

Delphi.Narium 16. Nov 2021 15:01

AW: Erkennen ob ein Fenster verdeckt wird
 
Zitat:

Ich hatte die Hoffnung, dass ich mir die Zuweisung des OnActivePageChanged bei jedem PageControl ersparen kann.
Wieviele hast Du denn davon?

Ein abgeleitetes PageControl machen, das schon das entsprechende Ereignis (mit allem Drum und Dran) enthält?

Ok, das hieße dann auch einmal durch den gesamten Quelltext durch und entsprechend anpassen.

Oder das Ereignis zur Laufzeit zuweisen, im FormCreate (o. ä.).

dataspider 16. Nov 2021 16:36

AW: Erkennen ob ein Fenster verdeckt wird
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1497667)
Zitat:

Ich hatte die Hoffnung, dass ich mir die Zuweisung des OnActivePageChanged bei jedem PageControl ersparen kann.
Wieviele hast Du denn davon?

Ein abgeleitetes PageControl machen, das schon das entsprechende Ereignis (mit allem Drum und Dran) enthält?

Ok, das hieße dann auch einmal durch den gesamten Quelltext durch und entsprechend anpassen.

Oder das Ereignis zur Laufzeit zuweisen, im FormCreate (o. ä.).

Ist überschaubar - vielleicht 20.
Ich hab halt gern Zusammengehörendes an einer Stelle, wenn dies möglich ist. Das erleichtert die Fehlersuche.
Ich hatte schon ab und zu die Situation, wo ich Fehlerursachen nicht gefunden habe,
weil der verursachende Code dort war, wo ich ihn nie vermutet hätte.

Also, Danke noch mal.
Ich benutze das Event des PageControls.

Frank

Blup 17. Nov 2021 08:45

AW: Erkennen ob ein Fenster verdeckt wird
 
Leite deine Unterformulare von einer gemeinsamen Klasse ab, die das entsprechende Ereignis einführt:
Delphi-Quellcode:
type
  TMyPageForm = class(TForm)
  public
    procedure FormChanging(AForm: TForm; var AllowChange: Boolean); virtual;
  end;

procedure TMyPageForm.FormChanging(AForm: TForm; var AllowChange: Boolean);
begin
  {macht in der Basisklasse erst mal nichts, kann überschieben werden}
end;
Ich gehe davon aus, jede Seite des PageControls hat nur ein Formular.
Im Ereignis des PageControls dann die einzelnen Formulare benachrichtigen:
Delphi-Quellcode:
procedure TForm1.cxPageControl1PageChanging(Sender: TObject; NewPage: TcxTabSheet; var AllowChange:
  Boolean);

  function FindMyPageForm(AWinControl: TWinControl): TMyPageForm;
  var
    i: Integer;
    c: TControl;
  begin
    if Assigned(AWinControl) then
    begin
      for i := 0 to AWinControl.ControlCount - 1 do
      begin
        c := NewPage.Controls[i];
        if c is TMyPageForm then
          Exit(TMyPageForm(c));
        {Rekursion}
        if c is TWinControl then
        begin
          Result := FindMyPageForm(TWinControl(c));
          if Result <> nil then
            Exit;
        end;
      end;
    end;
    Result := nil;
  end;

var
  F, NewForm: TMyPageForm;
  Page: TcxTabSheet;
  i: Integer;
begin
  NewForm := FindMyPageForm(NewPage);

  for i := 0 to TcxPageControl(Sender).PageCount - 1 do
  begin
    Page := TcxPageControl(Sender).Pages[i];
    F := FindMyPageForm(Page);
    if Assigned(F) then
      F.FormChanging(NewForm, AllowChange);
  end;
end;
ungetestet

Sinspin 17. Nov 2021 11:41

AW: Erkennen ob ein Fenster verdeckt wird
 
Zitat:

Zitat von Blup (Beitrag 1497709)
Leite deine Unterformulare von einer gemeinsamen Klasse ab, die das entsprechende Ereignis einführt

So mache ich das auch. Alle meine Dialoge haben eine gemeinsame Basisklasse.
Die kümmert sich um alle Benachrichtigungen gemeinsam mit einem Pagemanager der das PageControl betreibt.
Verhaltensänderungen sind dann gleichzeitig an allen Forms wirksam.
Ich habe über 200 Formulare die sich darüber verwalten lassen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:34 Uhr.

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