Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi falsches Fenster im Vordergrund (https://www.delphipraxis.net/202496-falsches-fenster-im-vordergrund.html)

rokli 11. Nov 2019 06:07

falsches Fenster im Vordergrund
 
Guten Morgen zusammen,

seid langem habe ich zwischendurch immer wieder den Effekt, dass sich die Fenster nicht in der Reihenfolge verhalten, wie ich das erwarte. Dazu folgendes Beispiel:

Form1 => MainForm
Form2 => mit Form2.ShowModal geöffnet

In der Form2 wird nun gearbeitet, z. b. wird eine Excel-Tabelle geöffnet und deren Inhalt wird in eine Datenbank geschrieben. Oder auf Form2 sind z. b. einige Buttons, die nacheinander abgearbeitet werden müssen.

Irgend wann wechseln dann die Fenster und die MainForm ist auf dem Bildschirm das "obere" Fenster, und das modale Fenster liegt dadrunter. Die MainForm kann und will ich dann natürlich nicht bedienen, da ich ja Form2 Modal geöffnet habe. Ein Klick auf die Form2 und es ist wieder so, wie es sein soll. An sich keine große Sache, aber wenn in Form2 gearbeitet wird, ohne das der Bildschirm zu jedem Zeitpunkt im Blick ist, dann ist das nicht gut, denn der Anwender muss möglicherweise seine Eingaben wiederholen.

Mit StayOnTop habe ich schon mal experimentiert, aber leider erfolglos. Das Verhalten der Fenster hat sich dadurch nicht verbessert. Ach ja, programmiert ist das sowohl in XE2 als auch in D10 Seattle

Hat jemand von Euch klugen Köpfen eine Idee, was man da machen könnte?

Dank für Eure Mühe und einen guten Wochenstart!

hoika 11. Nov 2019 06:21

AW: falsches Fenster im Vordergrund
 
Hallo,
Zitat:

Irgend wann wechseln dann die Fenster
Wann das genau passiert, musst Du erst mal herausfinden.
Hast Du ein Minimalbeispiel, was Du uns zeigen kannst?

Das beschriebene Verhalten gab es mal in D5/D6/D2007+Vista, sollte aber längst behoben sein.

Delbor 11. Nov 2019 07:04

AW: falsches Fenster im Vordergrund
 
Hi rokli

Du verwendest Showmodal offensichtlich nicht so, wie Delphi das vorsieht. Zumindest, wenn ich dich richtig verstanden habe, öffnest du Form2 wie folgt:
Delphi-Quellcode:
Form2.Showmodal
und erwartest dann, dass es Modal offen bleibt, bis du es schliesst. Wenn dem so wäre: das wäre falsch. Form2 mag zwar geöffnet werden, aber du hast eventuell keine Kontrolle darüber, wie lange es modal bleibt.
Zitat:

Irgend wann wechseln dann die Fenster und die MainForm ist auf dem Bildschirm das "obere" Fenster, und das modale Fenster liegt dadrunter
Das Embarcadero-Wicki enthält da ein Beispiel zur Verwendung von Modalen Formularen.
In Form1 würdest du also schreiben:
Delphi-Quellcode:
  Form2.Showmodal;
  if Form2.ModalResult = mrOkay then
  begin
    // Modalresult hat hier den Wert, der beim Klick
    // auf einen Button von Form2 festgelegt wurde.
    // Ein OK-Button hätte zum Beispiel den
    // Modalresult-Wert mrOK
    // Hier kannst du z.B. Propertys
    // von Form2 weiterverarbeiten
    // oder sonst was tun
  end;
Auch wenn du erst Bearbeitungen in Form2 durchführen willst: der obige Code wird unterbrochen, solange Form2 geöffnet ist und kehrt erst nach schliessen von Form2 zurück.

Gruss
Delbor

Incocnito 11. Nov 2019 07:15

AW: falsches Fenster im Vordergrund
 
Ich denke auch, ohne Minimalbeispiel wird das hier wohl nicht gehen.
Wir hatten beispielsweise damals ein Drucksystem, welches ein Handle in
einer Methode haben wollte. Das Drucksystem lag mit seinen Komponenten
auf einem DataModule-Fenste-Dings. Da das Drucksystem eigene Fenster
anzeigte, wurde das Handle wohl so verwendet, dass es dieses als
Ausgangspunkt für "ShowModal" verwendet hat (zumindest vom Prinzip her).
Hierdurch sind dann sämtliche Fenster im laufenden Betrieb ständig
in den Hintergrund gewandert. Der Fenstermanager von Windows hat dann wohl
einen Knacks weg bekommen. Meistens dann auch zig Fenster später.
Einfgache Meldungen (ShowMessage), die im Hintergrund gelandet sind usw..
Lösung war es, dass das Modul, welches die Druckfunktionen nutzen wollte
immer ein Fensterhandle mitgeben musste (natürlich das vom aktuellen Fenster dann).
Ab dann wurde es schlagartig besser. Aus Unwissenheit hatten wir es erst
auf die bekannte Problematik von Windows geschoben.
Vielleicht hilft dir diese "Geschichte" ja schon als Denkanstoß.

MfG Incocnito

rokli 12. Nov 2019 07:30

AW: falsches Fenster im Vordergrund
 
Guten Morgen zusammen!

Leider war gestern soviel los, dass ich nicht eher antworten konnte.

Also das ist schon richtig so, dass ich erreichen will, dass der Anwender ausschließlich in dem Fenster Form2 arbeiten kann, bis er damit fertig ist, dass Fenster dann schließt und anschließend mit der Anwendung in der Form1 weiter macht.

Zitat aus Beschreibung im docwiki http://docwiki.embarcadero.com/Libra...Form.ShowModal

"... Da bei einem modalen Formular die Anwendung unterbrochen wird, bis der Benutzer das Fenster wieder schließt, ..." Daraus habe ich abgeleitet, dass die Form1 nicht verwendet werden kann (=> und im Hintergrund bleibt!!), bis Form2 wieder geschlossen worden ist. Und in der Zwischenzeit soll nur in Form2 gearbeitet werden.

Die Anwendung sieht tatsächlich so ähnlich aus, wie Delbor das geschrieben hat. Allerdings verwende ich den ModalResult nicht, da ich den für meinen Ablauf gar nicht benötige. Innerhalb von Form2 befinden sich zwei Buttons, bei denen bei beiden der ModalResult = mrNone ist. Geschlossen wird Form2 über das rote Kreuz oben rechts. Die fiktive Form2 ist in der echten Anwendung das Programm frmHandlager.

Delphi-Quellcode:
procedure TfrmMain.bbtHandlagerClick(Sender: TObject);
{-------------------------------------------------------------------------------
   Handlager starten
-------------------------------------------------------------------------------}
begin
   p_ProtoWrite('');
   p_ProtoWrite('Aufruf Handlager aus frmMain');
   frmHandlager.ShowModal;
   p_ProtoWrite('Handlager beendet');
end;
Und wenn die Situation eintritt, dass das Fenster von Form1 nach vorne kommt, kann darin nicht geklickt werden (da die Form1 ja unterbrochen ist), sondern für den Anwender fühlt sich das son an, als wenn die Anwendung sich aufgehängt hat, bzw. das "sein Programm" (=> Form2) verschwunden ist. Mit dem ModalResult habe ich bisher nicht gearbeitet, weil ich damit keine Steuerung bauen wollte, sondern über den Mechanismus
Delphi-Quellcode:
Form2.ShowModal
sicherstellen wollte, dass der Anwender nur das "richtige" Fenster 2 verwendet.

Ich hoffe mal, dass mein Vorgehen nun etwas genauer herausgearbeitet ist.

Delbor 12. Nov 2019 12:27

AW: falsches Fenster im Vordergrund
 
Zitat:

Zitat von rokli (Beitrag 1451182)
"... Da bei einem modalen Formular die Anwendung unterbrochen wird, bis der Benutzer das Fenster wieder schließt, ..." Daraus habe ich abgeleitet, dass die Form1 nicht verwendet werden kann (=> und im Hintergrund bleibt!!), bis Form2 wieder geschlossen worden ist. Und in der Zwischenzeit soll nur in Form2 gearbeitet werden.

Ich habe mal einem meiner Testprogramme ein neues Formuzlarverpasst und zeige dieses bei einem Buttonclick an:
Delphi-Quellcode:
procedure TMainPage.TlbModalClick(Sender: TObject);
begin
  Modalform.ShowModal;
end;
Auf der Modalform hab ich einen Button und ein Edit:
Delphi-Quellcode:
procedure TModalform.BitBtn1Click(Sender: TObject);
begin
  Edit1.Text := HelpTestMain.MainPage.PageControl1.ClassName
end;
Irgendwie hatte ich den Verdacht, dass ein Zugriff auf die Hauptform diese aktivieren könnte - wobei mein Zugriff sehr minimal ist und so (noch?) keinen Einfluss hat.

Ausserdem hab ich getestet, wie sich die Form verhält, wenn sie über das x rechts oben geschlossen wird:
Delphi-Quellcode:
procedure TModalform.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Showmessage('OnClose!');
end;

procedure TModalform.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
Showmessage('FormCloseQuery!');
end;

procedure TModalform.FormDeactivate(Sender: TObject);
begin
  Showmessage('FormDeactivate!')
end;
Also der selbe Ablauf, wie über einen schliessen-Button oder wasauch immer.

Zitat:

Und wenn die Situation eintritt, dass das Fenster von Form1 nach vorne kommt, kann darin nicht geklickt werden (da die Form1 ja unterbrochen ist), sondern für den Anwender fühlt sich das son an, als wenn die Anwendung sich aufgehängt hat, bzw. das "sein Programm" (=> Form2) verschwunden ist. Mit dem ModalResult habe ich bisher nicht gearbeitet, weil ich damit keine Steuerung bauen wollte, sondern über den Mechanismus
Delphi-Quellcode:
Form2.ShowModal
sicherstellen wollte, dass der Anwender nur das "richtige" Fenster 2 verwendet.

Ich hoffe mal, dass mein Vorgehen nun etwas genauer herausgearbeitet ist.
Ja, das ist es. Wie Hoika geschrieben hat, solltest du herausfinden, wann und möglichst warum dieses Verhalten auftritt. Ich verwende dazu eine Stringliste, die ich beim Beenden abspeichere, so dass ich nach Beenden der Anwendung nachlesen kann, was in welcher Reihenfolge und mit welchen Werten abgearbeitet wurde.

Gruss
Delbor

DeddyH 12. Nov 2019 12:48

AW: falsches Fenster im Vordergrund
 
Bringt vielleicht TModalFix etwas?

rokli 12. Nov 2019 15:34

AW: falsches Fenster im Vordergrund
 
Vielen Dank für die vielen Anregungen ... komme aber erst wieder morgen dazu, das auszuprobieren!

Beste Grüße

Incocnito 12. Nov 2019 16:20

AW: falsches Fenster im Vordergrund
 
Das du auf das Hauptform zugreifst ist natürlich schon maximal verdächtig.
Hier könnte es sein, dass du mit "frmMain.Edit1.Text := '4711';" vermeintlich harmlos
nur den Wert ändern willst, aber durch OnChange vom Editfeld alles vermichtet wird
woran der Anwender solange gearbeitet hat. ... Was auch immer du an das Hauptform
zurück geben willst (in dem Fall nun den Wert, der im Editfeld landen soll),
würde ich anders an das Hauptform zurück geben.
Bei mir sieht das meist so aus, dass das Form in solch einem Fall eine Funktion hat
vom Prinzip her:
Delphi-Quellcode:
Function TForm2.DoSomething() : TSomeValues;
Begin
  FPrivateValue := TSomeValues.Create();
  InitForm();
  ShowModal(); // Durch das Form wird dann FPrivateValue beschrieben.
  Result := FPrivateValue;
End;
Nach dem Aufruf muss dann halt alles aus dem Objekt verarbeitet werden.
Denk aber daran, dass das erzeugte Objekt auch wieder freigegeben werden muss.
Vielleicht bietet sich (bei kleineren Daten) auch ein Record (statt eines Objektes) an.

MfG Incocnito

rokli 13. Nov 2019 07:58

AW: falsches Fenster im Vordergrund
 
Hallo und guten Morgen!

@Delbor: Das werd ich wohl erst mal machen, das ich versuche zu protokollieren, wann das eigentlich passiert. Denn das liegt bisher im Dunklen.

@DeddyH: Scheint ja so, als ob auch andere damit schon zu kämpfen hatten. Auch für den Tipp vielen Dank - schau ich mir an.

@Incocnito: Ich will keine Daten zwischen den Fenstern austauschen. Ich will eigentlich "nur" sicherstellen, dass in in keiner anderen Form gearbeitet wird, solange die Form2 auf ist. Vielen Dank für Deine Mühe.

Güße


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:04 Uhr.
Seite 1 von 2  1 2      

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