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/)
-   -   Delphi Popup Fenster - stay on top (https://www.delphipraxis.net/137893-popup-fenster-stay-top.html)

Fisti 30. Jul 2009 15:09


Popup Fenster - stay on top
 
Hallo zusammen

Ich versuche folgendes zu kreieren:

Bei einem Klick auf einen Button soll ein Popup erscheinen. Dieses Popup soll immer im Vordergrung bleiben, auch wenn andere Programme (z.b. excel) geöffnet werden. Zudem soll es die Hauptapplikation nicht behindern, auf dieser soll normal weiter gearbeitet werden können. Das Popup soll sich erst schliessen, wenn der Benutzer beim Popup auf schliessen drückt.

Dies soll als Hinweis mit Hilfestellungen für den Benutzer dienen.


Bis jetzt habe ich folgenden Code:

Hauptapplikation
Delphi-Quellcode:
procedure TMainForm.Button1Click(Sender: TObject);
var
  _myForm: TForm1;
begin

  // irgendwelche Aktionen

  _myForm := TForm1.Create(self);
  _myForm.Show;


  // weiter Aktionen -> sollen weiter geführt werden, egal ob Popup offen ist oder nicht

end;

Popup Form
Delphi-Quellcode:
procedure TForm1.FormShow(Sender: TObject);
begin
  SetWindowPos( Handle,
                HWND_TOPMOST,
                0,
                0,
                0,
                0,
                SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
end;

Dies funktioniert aber noch nicht wunschgemäss. Wenn ich das Popup mit einem Klick auf "Schliessen" schliessen will, dann kack das ganze ab (wenn der Code in der Hauptapplikation noch am laufen ist, was er eigentlich immer ist)
Zudem bleibt das Popup nicht ewigs sichtbar. Zwar ist es immer im Vordergrund, aber es wird nach ein paar Sekunden und dem Öffnen anderer Programme weis und gibt keine Antwort mehr.

Ich nehme an, dass der Aufruf _myForm.Show wohl nicht ganz das Richtige ist.. :?

Kann mir da jemand weiter helfen?


Danke shcon im Voraus
Gruss Fisti

tomsson74 30. Jul 2009 15:16

Re: Popup Fenster - stay on top
 
Wenn ich Dich richtig verstanden habe, müsste dir der folgende Beitrag weiterhelfen (mit kleinen Umbauten ggf.):

Make a form Showmodal by using Show

Alternativ kannst du bei deinem Popup-Form die Eigenschaft FormStyle auf fsStayOnTop setzen und es von Deinem Hauptformular einfach mit Show aufrufen. Auf das SetWindowPos im Ereignis FormShow kannst Du dann verzichten.

Edit: Ups, habe übersehen, dass das immer oben bleiben soll, auch wenn Du andere Anwendungen startest. In diesem Fall sind meine Vorschläge nicht unbedingt zu gebrauchen :)

/Thomas

turboPASCAL 30. Jul 2009 15:23

Re: Popup Fenster - stay on top
 
Du musst dir selbst ein OnShow-Event basteln.
In diesem kannst du dann dein SetWindowPos verwenden.

Oder gleich bei dem erstellen deiner dyn. Form die richtigen Parameter setzen...

Fisti 31. Jul 2009 09:53

Re: Popup Fenster - stay on top
 
Erstmal danke für die schnellen Antworten :thumb:

Der Hinweis mit FormStyle auf fsStayOnTop setzen hat mir schon einmal geholfen, danke.


Mein aktueller Code:

Delphi-Quellcode:
procedure TMainForm.Button1Click(Sender: TObject);
var
  _myForm: TForm1;
begin

  _myForm := TForm1.Create(self);
  _myForm.UebergabeWert := 'blabla';
  _myForm.Show;

  //Externe Software starten
  if not CreateProcess( nil,_pAppName,nil,nil,False,CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,nil,nil,_StartupInfo,_ProcessInfo)
  then begin
    _lwResult := WAIT_FAILED;
    exit;
  end;

  //Warten bis externe Software beendet wurde
  _WaitResult := WaitForSingleObject(_ProcessInfo.hProcess, INFINITE);


  _myForm.Destroy;

end;

Da beim Starten der externen Software meine MainApp blockiert wird, wird auch mein Hinweis-Form "_myForm" blockiert (man sieht nur weis) und ich sehe nicht was da ausgegeben wird.

Das Ziel ist, dass ich während dem Laufen der externen Software eine Hinweis-Box/Form habe, die mir nützliche Informationen anzeigt.


Wie muss ich die Hinweis-Form "_myForm" kreieren und anzeigen, damit sie nicht auch blockiert wird?

ChrisE 31. Jul 2009 10:19

Re: Popup Fenster - stay on top
 
Hallo Fisti,

Zitat:

Zitat von Fisti
Mein aktueller Code:

Delphi-Quellcode:
procedure TMainForm.Button1Click(Sender: TObject);
var
  _myForm: TForm1;
begin
//...
  //Warten bis externe Software beendet wurde
  _WaitResult := WaitForSingleObject(_ProcessInfo.hProcess, INFINITE);
//...
end;

Da beim Starten der externen Software meine MainApp blockiert wird, wird auch mein Hinweis-Form "_myForm" blockiert (man sieht nur weis) und ich sehe nicht was da ausgegeben wird.

Ich würde dir ein Warten mit zusätzlichen Message raten anstatt von WaitForSingleObject

Delphi-Quellcode:
Fertig := FALSE;
repeat
  Erg := MsgWaitForMultipleObjects(1, _ProcessInfo.hProcess, FALSE, INFINITE, QS_ALLINPUT);
  if Erg <> WAIT_OBJECT_0 then
  begin
    // hier kam eine Windowsbotschaft
    Application.ProcessMessages;
   
    // Wurde die Anwendung selber terminiert?
    if Application.Terminated then Fertig := TRUE;

    // Irgendetwas anderes prüfen??
  end else
  begin
    // der Process ist beendet...
    Fertig := TRUE;
  end;
until Fertig;
Das sollte dich einen Schritt weiter bringen.

Gruß, Chris

[EDIT]begin vergessen -> Code ist nicht getestet ;-) [/EDIT]

Fisti 4. Aug 2009 10:47

Re: Popup Fenster - stay on top
 
Hallo Chris

Danke dir für deine Antwort. Dein Tipp MsgWaitForMultipleObjects zu verwenden hat mich wirklich weiter gebracht. Nun sehe ich meine Hinweisform und sie ist nicht mehr nur weis.

Nun ist dafür aber das Problem mit dem Stay-on-top wieder aufgetaucht. Die Hinweisform ist nicht mehr im Vordergrund.

Ich habe in der Hinweisform bisher folgendes gemacht:

Formstyle = fsStayOnTop

und im FormCreate
Delphi-Quellcode:
SetWindowPos(Handle,HWND_TOPMOST,0,0,0,0,SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);

Der komplette Code sieht so aus:

Delphi-Quellcode:
procedure TMainForm.Button1Click(Sender: TObject);
var
  _myForm: TForm1;
  ...
begin

  _myForm := TForm1.Create(self);
  _myForm.UebergabeWert := 'blabla';
  _myForm.Show;

  //Externe Software starten
  if not CreateProcess( nil,_pAppName,nil,nil,False,CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,nil,nil,_StartupInfo,_ProcessInfo)
  then begin
    _lwResult := WAIT_FAILED;
    exit;
  end;

  //Warten bis externe Software beendet wurde
  _RunFinished := false;
  repeat
    _WaitResult := MsgWaitForMultipleObjects(1, _ProcessInfo.hProcess, FALSE, INFINITE, QS_ALLINPUT);
    if _WaitResult <> WAIT_OBJECT_0 then begin
      Application.ProcessMessages;
      // Wurde die Anwendung selber terminiert?
      if Application.Terminated then _RunFinished := true;
    end else begin
      // der Process ist beendet...
      _RunFinished := true;
    end;
  until _RunFinished;


  _myForm.Destroy;

end;
Was mache ich noch falsch, dass die Hinweisform nicht ständig im Vordergrund ist?

Danke und Gruess
Fisti


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