Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Anzeige eines Forms im OnShow-Ereigniss abbrechen

72 views
Skip to first unread message

Martin Specht

unread,
Nov 29, 2006, 5:48:16 PM11/29/06
to
Hallo zusammen,

ich habe hier ein Form, dass einige Properties übergeben bekommt.
Beim Aufruf von des Fensters via ShowModal wollte ich im OnShow
Handler die Paramater auf Plausibilität prüfen und bei einer Fehler-
Erkennung die Anzeige des Forms abbrechen. Leider funktioniert
die Close-Anweisung im OnShow-Handler nicht. Wie kann das
Schliessen des Fensters gemacht werden? Gibt es überhaupt eine
"saubere" Lösung?

Vielleicht wäre es besser, diese Plausibilitätsprüfung vorher zu
machen, bevor überhaupt das Formular angezeigt wird. Ich finde es
jedoch sinnvoll, wenn die Prüflogik im Formular selbst untergebracht
wird und nicht im Parent-Formular, dass das Form via Show aufruft.
Meine Idee wäre eine Art Ready-Property (read-only), welches beim
Setzten der anderen (zu überprüfenden) Properties entsprechend gesetzt
wird und beim beenden des Forms (wie andere Properties
auch) entsprechend zurückgesetzt wird. Ist das ein brauchbarer
Ansatz oder gibt es (wie so oft) eine bessere Methode?

Grüße
Martin Specht


Martin Specht

unread,
Nov 29, 2006, 6:17:43 PM11/29/06
to

>Meine Idee wäre eine Art Ready-Property (read-only) ...

btw Initialisierung im OnCreate-Ereigniss war doch richtig?
Oder muss der Contructor Create überschrieben werden?

Christian Gudrian

unread,
Nov 30, 2006, 1:19:59 AM11/30/06
to
Martin Specht wrote:

> Wie kann das
> Schliessen des Fensters gemacht werden?

Wie soll der Aufrufer von ShowModal etwas davon mitbekommen, dass das
Anzeigen aufgrund einer fehlerhaften Parametrierung fehlgeschlagen ist?

Zwei Alternativen fallen mir spontan ein:

A) Füge eine Methode dem Formular hinzu, über die der Aufrufer
ermitteln kann, ob seine Parametrierung gültig ist (Rückgabewerte True)
oder nicht (False).

B) Sorge dafür, dass das Formular niemals in einen ungültig
parametrierten Zustand gerät. Dazu führst Du die Plausbilitätstests in
den Setter-Methoden durch und passt ggf. andere Eigenschaften auf
verträgliche Werte an.

Christian

Hans-Peter Diettrich

unread,
Nov 29, 2006, 10:46:51 PM11/29/06
to
Martin Specht wrote:

> ich habe hier ein Form, dass einige Properties übergeben bekommt.
> Beim Aufruf von des Fensters via ShowModal wollte ich im OnShow
> Handler die Paramater auf Plausibilität prüfen und bei einer Fehler-
> Erkennung die Anzeige des Forms abbrechen.

IMO wird das schwierig, weil ShowModal in Delphi alle Fenster
beeinflußt, nicht nur das anzuzeigende. Schau mal nach, was beim Aufruf
von ShowModal so alles abläuft.

Die Prüfung müßte daher erfolgen, bevor überhaupt ShowModal aufgerufen
wird. Ich würde dafür eine neue Methode einführen, CheckedShowModal oder
so, die zuerst die Prüfmethode der Form aufruft, und nur bei Erfolg auch
noch das ShowModal.

DoDi

Heiko Luettge

unread,
Nov 30, 2006, 2:42:43 AM11/30/06
to
Hallo,

Nimm FormActivate.
Zum Abbrechen PostMessage(Handle, WM_CLOSE, 0, 0);

Du musst nur Aufpassen:
- kein Application.ProcessMessages vorher
sonst wird das Form kurz angezeigt
- FormAtivate kann mehrfach vorkommen
setze in FormCreate eine Variable (bFirstInForm:= True)
die ersten zwei. Zeilen in FormActivate ist

if not bFirstInForm then Exit;
bFirstInForm:= False;

Ich habe das in eine eigenes Form ausgelagert und leite meine eigenen Forms
davon ab.


Heiko


Martin Raible

unread,
Nov 30, 2006, 3:12:41 AM11/30/06
to
Hallo Martin

> ich habe hier ein Form, dass einige Properties übergeben bekommt.
> Beim Aufruf von des Fensters via ShowModal wollte ich im OnShow
> Handler die Paramater auf Plausibilität prüfen und bei einer Fehler-
> Erkennung die Anzeige des Forms abbrechen. Leider funktioniert
> die Close-Anweisung im OnShow-Handler nicht. Wie kann das
> Schliessen des Fensters gemacht werden? Gibt es überhaupt eine
> "saubere" Lösung?

>...

ich handhabe das immer so

TMyForm=classs(TForm)
...
protected
FMyData:TMyData;

function Valid:boolean;
procedure Init;
procedure Done;
public
function Execute(AMyData:TMyData):boolean;
end;


//kapselt die Aufruflogik und nur diese
function TMyForm.Execute(AMyData:TMyData):boolean;
begin
FMyData:=AMyData;
if Valid then
begin
Init;
result:=ShowModal=mrOK;
if result then Done;
end;
end;

function TMyForm.Valid:boolean;
begin
//bei ungültigen Daten wird weder Init noch
//ShowModal aufgerufen
result:=//MyData ist gültig oder nicht
end;

procedure TMyForm.Init;
begin
//hier werden alle Dialogelemente
//mit den Informationen aus FMyData
//gefüllt.
end;

procedure TMyForm.Done;
begin
//wird nur aufgerufen, wenn der Dialog mit OK beendet wurde
//Daten der Dialogelemente wieder in FMyData übertragen
end;

Die einzelnen Bereiche sind eindeutig voneinander getrennt.
"Execute" ist ausschließlich für die Aufruflogik zuständig
"Valid" übernimmt die Prüfung
"Init" setzt die Dialogelemente
"Done" liest die Dialogelemente wieder aus.

Ach ja der Aufruf im Programm erfolgt dann so:

procedure Form1.Button1Click(Sender:TObject);
begin

if MyForm.Execute(MyData) then
begin
//es wurde etwas verändert
//die Oberfläche muss nun angepasst werden
end;
end;


Gruß
Martin


Marian Aldenhövel

unread,
Nov 30, 2006, 3:24:59 AM11/30/06
to
Hi,

> Vielleicht wäre es besser, diese Plausibilitätsprüfung vorher zu
> machen, bevor überhaupt das Formular angezeigt wird.

Auf jeden Fall.

> Ich finde es jedoch sinnvoll, wenn die Prüflogik im Formular selbst
> untergebracht wird und nicht im Parent-Formular, dass das Form via
> Show aufruft.

Auf jeden Fall.

Aber das eine schließt das andere ja nicht aus:

Du kannst eine Methode wie CanShow():boolean einführen und die vor dem
Show explizit aufrufen.

Das ist die flexibelste Methode. Dein Formular weiß ja nur, daß es im
Moment nicht angezeigt werden soll, vielleicht weiß es auch warum genau
nicht (Zu großer Schneckelwert beim aktuellen Protonenfluß), aber es
weiß nicht, was der Aufrufer stattdessen machen will.

Deshalb kann Code beim Aufrufer wie:

if F.CanShow
then F.ShowModal
else // Andere Möglichkeiten?

Unter "andere Möglichkeiten" die passende hinschreiben. Eine Meldung anzeigen,
den Wert korrigieren, ein bestimmtes Steuerelement sichtbar machen und
fokussieren... Sachen die der modale Dialog halt nicht kann.

Du kannst auch ShowModal überschreiben und Dein neues CanShow() daraus
aufrufen:

function TMyForm.ShowModal:integer;
begin
if not CanShow()
then
begin
Showmessage('is nicht weil...');
Result:=mrCancel; // oder sonst was angemessenes
end
else Result:=inherited ShowModal;
end;

Jetzt kann man das Formular nicht mehr versehentlich doch falsch modal
anzeigen aber der Aufrufer hat keine direkte Möglichkeit zu reagieren.
Er bekommt halt ein mrCancel und muss das interpretieren. Also brauchst
Du eigentlich einen neuen Wert mrInvalidParameters für ModalResult. Kann
man machen ist aber ungewöhnlich.

Und natürlich kannst Du auch noch in OnShow/DoShow() gegen falsche
Verwendung sichern:

procedure TMyForm.FormShow(..)
begin
if not CanShow then
raise EMyFormError('Falsche Parameter, kann nicht anzeigen.');
end;

Ciao, MM
--
Marian Aldenhövel, Rosenhain 23, 53123 Bonn
http://www.marian-aldenhoevel.de
"If the hawk had lice, would it increase his parasite drag?"

0 new messages