Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Fenster automatisch schliessen


Sidi - Sa 18.10.08 22:27
Titel: Fenster automatisch schliessen
Hallo zusammen,

ich habe ein Fenster das mit Form1.showmodal geöffnet wird. Im Ereignis Form1.onShow werden Befehle abgearbeitet und der Fortschritt in einer TProgressbar dargestellt.

Wenn ich nun am Ende der Anweisungen, also noch im Ereignis Form1.onShow, die Anweisung Form1.close eingebe, wird diese Anweisung nicht ausgeführt.

Wie kann ich ein Fenster automatisch nach Abarbeitung der Anweisungen schließen??

Gruß
Sidi


Boldar - Sa 18.10.08 22:46

Meines wissens geht das nicht. Verwende onactivate oder Stelle einen Timer ein.


Sidi - Sa 18.10.08 22:52

in Form1.onActivate habe ich es auch schon versucht, mit dem selben Ergebnis :cry:


Boldar - So 19.10.08 00:38

Dann stelle in .show einen Timer auf enabled und im Timer.ontimer das self.hide, stelle Intervall sehr kurz ein und dann sollte es den Gewünschten effect geben.


martin300 - So 19.10.08 01:45

Von dort wo Form1.showmodal geöffnet wird sollte es auch
wieder zugemacht werden.
Bsp:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
Unit8 Hauptfenster;
Unit9 Fenster das aufgemacht werden soll;

procedure TForm8.Button1Click(Sender: TObject);
begin
Form9.ShowModal;
timer1.Interval := 1000;
end;

procedure TForm8.Timer1Timer(Sender: TObject);
begin
Form9.close;
end;


Xentar - So 19.10.08 02:57

Man könnte das Formular auch einfach dynamisch erzeugen.
Sollte dann natürlich nicht vergessen, dies in den Projektoptionen aus den automatisch erzeugten Formularen rauszunehmen.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
Form2 := TForm2.Create;
try
  Form2.ShowModal;
finally
  FreeAndNil(Form2);
end;


jaenicke - So 19.10.08 09:52

Wie wäre es, wenn du das Fenster einfach nur mit Show anzeigst und einfach dein anderes Fenster derweil mit Enabled := False unbenutzbar machst? Dann kannst du deine Fortschrittsanzeige direkt von dort aktualisieren wo du auch Show aufrufst und dort kannst du dann das Fenster auch wieder verstecken und dein anderes Fenster wieder aktivieren.

Kleines Beispiel im Anhang.


Boldar - So 19.10.08 10:31

mach einfach in der mit showmodal aufgerufenen Form


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
Tformmodal.formshow
begin
dosomething;
timer1.interval := 100;
timer1.enabled := true;
end;
...
Tformmodal.Timer1timer (sender: Tobjekt);
begin
self.hide;
end;


jaenicke - So 19.10.08 11:19

user profile iconBoldar hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
Tformmodal.Timer1timer (sender: Tobjekt);
begin
self.hide;
end;
Da fehlt dann noch das Deaktivieren des Timers.

Delphi-Quelltext
1:
2:
3:
4:
5:
Tformmodal.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled := False;
  Hide;
end;
Trotzdem finde ich die Timerlösung nicht besonders sinnvoll, denn ShowModal ist eben nicht für diesen Zweck gedacht.


Lannes - So 19.10.08 11:26

Hallo,

die Reihenfolge der Ereignisse:
• OnCreate
• OnShow
• OnActivate
• OnPaint

Du brauchst :arrow:
• OnAfterActivate

Kleines Beispiel:

MainForm:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;
type
  TMainForm = class(TForm)
    ButtonLaden: TButton;
    procedure ButtonLadenClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
var
  MainForm: TMainForm;
implementation

uses Unit2;
{$R *.DFM}

procedure TMainForm.ButtonLadenClick(Sender: TObject);
begin
  SubForm.ShowModal;
end;

end.


SubForm:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
unit Unit2;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ComCtrls;
const
  WM_AFTER_ACTIVATE = WM_USER + 300;
type
  TSubForm = class(TForm)
    ProgressBar1: TProgressBar;
    procedure FormActivate(Sender: TObject);
  private
    { Private-Deklarationen }
  procedure WmAfterActivate(var Msg: TMessage); message WM_AFTER_ACTIVATE;
  public
    { Public-Deklarationen }
  end;
var
  SubForm: TSubForm;
implementation

{$R *.DFM}
procedure TSubForm.WmAfterActivate(var Msg: TMessage);
begin
  close;
end;

procedure TSubForm.FormActivate(Sender: TObject);
var z : Integer;
begin
  //Application.ProcessMessages;   <--- eventuell
  for z := 0 to 20000 do
    begin
    ProgressBar1.Position := ProgressBar1.Position+1;
    Caption := IntToStr(z);
    end;
  PostMessage(Self.Handle, WM_AFTER_ACTIVATE, 00);
end;

end.


martin300 - So 19.10.08 12:28

Kopie aus der Delphi Hilfe:

Warnung:
Sie dürfen eine Komponente nie in einer ihrer eigenen Ereignisbehandlungsroutinen oder in einer Ereignisbehandlungsroutine eines untergeordneten Objekts freigeben. Geben Sie beispielsweise auf keinen Fall eine Schaltfläche oder ihr übergeordnetes Formular in der OnClick-Ereignisbehandlungsroutine der Schaltfläche frei.


Um ein Formular freizugeben, ruften Sie seine Methode Release auf. Dadurch wird sichergestellt, dass das Formular erst aus dem Speicher entfernt wird, wenn die Ausführung seiner eigenen und der Ereignisbehandlungsroutinen seiner Komponenten beendet ist.

Das Bsp von Xentar finde ich recht gut.