Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form (https://www.delphipraxis.net/169142-showmessage-oder-auch-form-showmodal-verschwindet-manchmal-hinter-form.html)

Poolspieler 2. Jul 2012 12:29

Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form
 
Hallo zusammen,
manchmal kommt es vor, dass ein simples showmessage('bla'), oder auch ein mein_Fenster.showmodal; HINTER dem Hauptformular verschwindet.
Man hat dann (fast) keine Möglichkeit mehr, das Fenster in den Vordergrund zu holen.
Das Thema wurde 2006 hier http://www.delphipraxis.net/65588-me...ntergrund.html schon mal angesprochen - allerdings ohne so eine richtige Lösung.

Wenn ich anstatt form1.showmodal folgendes schreibe, dann scheint es nicht aufzutreten:
Code:
hauptform.enabled := false;
form1.show;
form1.bringtofront;
Dann muss man aber aufpassen, dass beim Schliessen von form1 das hauptform wieder auf enabled=true gesetzt wird...
form1 muss dann natürlich auf stayontop gestellt sein...
--> bei Anwendungen mit ganz vielen Formularen (die auch noch gleichzeitig offen sein können) wird das aber schnell recht kompliziert...

Es sieht so aus, als ob das Problem vor allem auftritt, wenn zwischen dem Button-Click und dem showmessage viel gemacht wird (z.B. umfangreiche Datei-IO, etc.).

Pseudocode:
Code:
procedure TForm.button1Click(Sender: TObject);
begin
  // Viel Datei-IO
  ...
  showmessage('ich bin fertig! Hoffentlich siehst Du diese Nachricht auch! Oder bin ich wohl versteckt?');
end;
Weiß jemand, woran das liegt - und was man vor allem dagegen tun kann?
Oder muss ich mir wirklich einen eigenen showmessage-Dialog basteln?

Gruß,

Poolspieler

DeddyH 2. Jul 2012 12:55

AW: Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form
 
Hilft dieser Thread evtl. weiter? http://www.delphipraxis.net/166408-m...de-wartet.html

Poolspieler 2. Jul 2012 13:16

AW: Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form
 
Hallo DeddyH,
vielen Dank für Deine Antwort!

Der Thread geht in die gleiche Richtung.
Aber eine wirkliche Lösung für das Problem habe ich nicht gefunden.

Wie sollte man messages (showmessage) ausgeben - muss man wirklich einen eigenen Dialog basteln?

Viele Grüße,

Poolspieler

ChrisE 2. Jul 2012 13:31

AW: Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form
 
Hallo Poolspieler,

ist Deine Angabe zu Deinem Nutzerkonto korrekt - also das du Delphi XE2 verwendest? Ich kenne das merkwürdige Verhalten von modalen Fenstern / Dialogen nämlich noch von Delphi 2007. Es scheint aber nicht mehr vorhanden zu sein bei Delphi XE2.

Dann aber noch etwas anderes, was mir gerade einfällt: Suche mal nach GhostingWindow bei google. Da gibt es ein ganz blödes verhalten von Windows, um nicht reagierende Anwendungen für den Benutzer zumindest minimal Bedienbar zu halten. Da du viel I/O erwähnt hast, könnte das der Fall sein bei Dir. Windows legt hier ein neues bedienbares Fenster für das vermeintlich "hängende" Fenster an und versteckt das echte hängende Fenster. Beim "zurück schalten" kann tatsächlich etwas schief gehen und der Dialog landet hinter dem Fenster. Das GhostingWindow-Problem beschränkt sich aber meines Wissens nach auf Windows XP. Kannst du ja mal suchen.

Gruß, Chris

himitsu 2. Jul 2012 13:32

AW: Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form
 
In ShowMessage stecken weitere Funktionen, da kann man sich den Message-Dialog erzeugen lassen und bevor man ihn anzeigt, könnte man noch etwas am PopupMode und PopupParent rumspielen und notfalls auch noch mit dem FormStyle.
z.B. könnte man sich die oberste Form suchen und den Dialog damit verbinden, damit Delphi den Dialog noch vor dieser Form darstellt.


Du könntest aber natürlich auch dafür sorgen, daß deine Anwendung garnicht erst hängen bleibt. :angle2:
(z.B. Threads und Co.)

Poolspieler 2. Jul 2012 13:54

AW: Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form
 
Hallo Zusammen,
danke für Eure Antworten!

Ja, ich nutze Delphi XE2 Update4.
Unter Win7 habe ich das Problem (noch...) nicht gesehen.
Es tritt aber unter WinXP auf. Mit und ohne Delphi-IDE.

Meine Anwendung nutzt bereits Threads für die UDP-Kommunikation und allem was dazu gehört.
Jede kleine (oder auch größere...) Datei-IO und vor allem die Bedienung des UDP-Threads in einen Thread auszulagern fand ich nicht sinnvoll - oder liege ich da falsch?

Beispiel:
Code:
if OpenDialog.Execute then begin
  ...
  // Dateiinhalt auf konsistenz prüfen (CRC, etc.) --> dauert ca. 2 Sekunden
  if _fehler then begin
    showmessage('Es ist ein Fehler aufgetreten!'); // dieser Dialog bleibt manchmal im Hintergrund
  end;
end;
--> warum sollte man dies in einen Thread verpacken? Ist das nicht zu viel Aufwand?

Viele Grüße,

Poolspieler

ChrisE 2. Jul 2012 14:00

AW: Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form
 
Hallo Poolspieler,

ich glaube, dass es relativ wenig Aufwand ist bei XE2, eine vorhandene Methode in einem Thread ausführen zulassen. Man sollte nur irgendwie evtl. prüfen, ob hier VCL-Sachen gemacht werden. Und ein Versuch wäre es Wert.

Die Methode mit dem GhostingWindow heißt übrigens DisableProcessWindowsGhosting und das Problem existiert SEIT XP und nicht nur bei XP. In welchem Zusammenhang die Delphiversion steht, kann ich natürlich nicht sicher beantworten. Ich hatte damals große Probleme mit Delphi2007 und ein XE-Benutzer hatte die Probleme glaub ich nicht.

Gruß, Chris

Poolspieler 2. Jul 2012 14:13

AW: Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form
 
Hallo ChrisE,
vielen Dank für den guten Hinweis - so tritt das Problem (offensichtlich...) nicht mehr auf.

Hier der Code von http://stackoverflow.com/questions/1...odal-is-called:
Code:
procedure DisableProcessWindowsGhosting;
var
  DisableProcessWindowsGhostingProc: procedure;
begin
  DisableProcessWindowsGhostingProc := GetProcAddress( 
    GetModuleHandle('user32.dll'),
    'DisableProcessWindowsGhosting');
  if Assigned(DisableProcessWindowsGhostingProc) then
    DisableProcessWindowsGhostingProc;
end;
"Dumme" Frage:
Welche tolle Möglichkeit hat man denn unter XE2 eine beliebige Routine in einem eigenen Thread laufen zu lassen?
Vor allem, wenn man trotzdem synchronisiert z.B. showmessage nutzen muss?

Gruß,

Poolspieler

taveuni 2. Jul 2012 15:05

AW: Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form
 
Zitat:

Zitat von Poolspieler (Beitrag 1173170)
Welche tolle Möglichkeit hat man denn unter XE2 eine beliebige Routine in einem eigenen Thread laufen zu lassen?
Vor allem, wenn man trotzdem synchronisiert z.B. showmessage nutzen muss?

z.b. anonyme Prozeduren in anonymen Threads

Delphi-Quellcode:
procedure MySynchProcedure(Param1: String; Param2: TObject; Param3: TDictionary<Integer, TMyObject>);
begin
  TThread.Queue(Nil,
  procedure
  begin
    // do anything synchronized here
  end);
end;

procedure DoAnythingTimeConsuming;
var
  Thrd: TThread;
begin
  Thrd: TThread.CreateAnonymousThread(
  procedure
  begin
    // do anything time consuming stuff here
    sleep(100000);
   
    MySynchProcedure(Param1, Param2, Param3);
  end);
  Thrd.FreeOnTerminate:= True;
  Thrd.Start;
end;

ChrisE 2. Jul 2012 15:43

AW: Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form
 
Hallo,

genau sowas, wie das Beispiel von taveuni hab ich gemeint.

Und das jetzt das DisableProcessWindowsGhosting funktioniert, zeigt ja, dass hier etwas stattfindet im Mainthread, dass eigentlich ausgelagert werden sollte in einen Thread. Denn es blockt den Mainthread so sehr, dass Windows denkt, die Anwendung wäre abgestürzt bzw. würde fest hängen.

Gruß, Chris

himitsu 2. Jul 2012 16:22

AW: Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form
 
Das FreeOnTerminate ist nicht nötig, da es im Constructor des TAnonymousThread schon auf true gesetzt wird.
Delphi-Quellcode:
TThread.CreateAnonymousThread(procedure
  begin
    ...
  end).Start;

// oder

TAnonymousThread.Create(procedure
  begin
    ...
  end).Start;
Man könnte aber auch das FreeOnTerminate auf false setzen und eine Warteschleife (ähnlich dem DelayDelay) anhängen, welche auf den Thread wartet, aber die GUI sich aktualisieren läßt.

Die anonymen Methoden können sogar Variablen hin und her verwalten.
Delphi-Quellcode:
proedure Test;
var
  xyz: string;
begin
  xyz := 'abc';

  TThread.CreateAnonymousThread(procedure
    var
      i: Integer;
    begin
      for i := 0 to 29 do begin
        xyz := xyz + IntToStr(i mod 10);
        Sleep(1000);
      end;
      TThread.Synchronize(nil, procedure
        begin
          ShowMessage(xyz);
        end;
    end).Start;
end;
Und das Schöne, man sieht hier sogar direkt den Programmablauf, was sich aber eher nur für kurze Methoden eignet, also für längeren Code sollte man besser eine getrennte Prozedur/Methode übergeben.

taveuni 2. Jul 2012 16:48

AW: Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form
 
Zitat:

Zitat von himitsu (Beitrag 1173185)
Delphi-Quellcode:
// oder

TAnonymousThread.Create(procedure
  begin
    ...
  end).Start;

Wie kriegst Du denn das kompiliert?
Das ist ja in der Klassenfunktion TThread.CreateAnonymousThread drin.

himitsu 2. Jul 2012 18:07

AW: Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form
 
Das ist eine anonyme Methode. :zwinker:
Sie wird einfach an Ort und Stelle deklariert, wo man sie verwenden will.

Die gibt es seit Delphi 2009. (genauer, seitdem es die Generics gibt)

- Unicode
- Record-Methoden (schau dir z.B. mal Delphi-Referenz durchsuchenTRect an)
- Record-Operatoren
- Generics
- anonyme Methoden
- ...
Es gab halt in letzer Zeit einige Neuerungen. :angle:



Der Parameter des CreateAnonymousThread/Create wurde als
Delphi-Quellcode:
procedure of
deklariert, womit man dort alles mögliche übergeben kann.
Delphi-Quellcode:
type
  TMyProcedure = procedure; // nimmt nur Prozeduren auf
  TMyMethod = procedure of object; // nimmt nur Methoden auf
  TMyAnonymus = reference to procedure; // nimmt alles auf (dahinter versteckt sich ein geheimes generisches Interface)

messie 2. Jul 2012 18:54

AW: Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form
 
Zitat:

Zitat von himitsu (Beitrag 1173199)
Das ist eine anonyme Methode. :zwinker:
Sie wird einfach an Ort und Stelle deklariert, wo man sie verwenden will.

Die gibt es seit Delphi 2009. (genauer, seitdem es die Generics gibt)

- Unicode
- Record-Methoden (schau dir z.B. mal Delphi-Referenz durchsuchenTRect an)
- Record-Operatoren
- Generics
- anonyme Methoden
- ...
Es gab halt in letzer Zeit einige Neuerungen. :angle:



Der Parameter des CreateAnonymousThread/Create wurde als
Delphi-Quellcode:
procedure of
deklariert, womit man dort alles mögliche übergeben kann.
Delphi-Quellcode:
type
  TMyProcedure = procedure; // nimmt nur Prozeduren auf
  TMyMethod = procedure of object; // nimmt nur Methoden auf
  TMyAnonymus = reference to procedure; // nimmt alles auf (dahinter versteckt sich ein geheimes generisches Interface)

:thumb::thumb::thumb: (weil es den DANKE-Button immer noch nicht gibt :wink:)

taveuni 3. Jul 2012 07:38

AW: Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form
 
Zitat:

Zitat von himitsu (Beitrag 1173199)
Das ist eine anonyme Methode. :zwinker:
[...]
Der Parameter des CreateAnonymousThread/Create wurde als
Delphi-Quellcode:
procedure of
deklariert, womit man dort alles mögliche übergeben kann.[...]

Danke. Mittlerweile kenne ich all diese Features auch. Ich hatte ja weiter oben den Threadersteller darauf hingewiesen.
Meine Frage bezog sich auch nicht auf die Anonyme Methode welche Du übergibst sondern:

Delphi-Quellcode:
TThread.CreateAnonymousThread()
ist ja eine Klassenfunktion und da ist auch alles o.k.

Du hast aber geschrieben es gehe auch:
Delphi-Quellcode:
TAnonymousThread.Create()
Und dies kann ich meinem Delphi XE2 Upd3 nicht beibringen. Du schon?

himitsu 3. Jul 2012 08:57

AW: Showmessage oder auch Form.showmodal verschwindet manchmal hinter Form
 
Arg, ich hatte mich verguckt.

Delphi-Quellcode:
class function TThread.CreateAnonymousThread(const ThreadProc: TProc): TThread;
begin
  Result := TAnonymousThread.Create(ThreadProc);
end;
Nur daß mal wieder jemand auf die saublöde Idee gekommen ist und diese Klasse versteckt in der Implementation deklariert hat. :wall:
Haben die noch nie was von Vererbung gehört und daß es eventuell jemanden geben könnte, der davon mal ableiten wöllte?
Eine Funktion wie CreateAnonymousThread hatte ich mir ja schon vorher (bevor die mir die Idee geklaut hatten), selbst implementiert. (Hier im Forum suchenRunAsThread)

Nja, ich hätte da eher noch die die edde gehabt, für eine Wartefunktion, aber egal, häng ich die halt via Class-Helper an TThread dran.
(CreateAnonymousThreadAndWait)


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:04 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