[Delphi] Public var in TForm vanuit een procedure

Pagina: 1
Acties:

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Sorry voor de vage titel, is moeilijk te omschrijven:

Omdat ik veel dezelfde code gebruik om meerdere Form's te openen wil ik er een procedure voor maken:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
procedure TMainForm.ShowSubWindow(Form: TForm; FrmAction: Integer; ControlToFocus: TWinControl);
begin
  with Form do begin
    FormAction := FrmAction;
    if Visible = True then begin
    BringToFront;
    OnShow(nil);
    end else begin
    Show;
    end;
    FocusControl(ControlToFocus);
  end;
end;

Maar nu zit er een probleem in de FormAction. Dit is een public declaration die is sommige form's voorkomt. Zoals het hierboven staat werkt het dus niet, om TForm geen FormAction heeft.

Hoe los ik dit op dat de bovenstaande procedure wel werkt voor een aantal Form's die een FormAction variable hebben?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Ik weet niet precies hoe je je formaction gedeclareerd hebt.
Als alle Forms die een formaction hebben overerven van een speciale form is het makkelijk op te lossen.
Je moet dus eerst een TFormWithA declareren als volgt
code:
1
2
3
4
5
6
7
8
type
  TFormWithA = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
    FormAction : SomeType;
  end;

Nu kan je alle forms die een action nodig hebben niet van TForm laten aferven, maar van TFormWithA

Als je dat zo hebt gedaan kan je vervolgens in je eigen code de regel
code:
1
FormAction := FrmAction;

vervangen voor
code:
1
If Form is TFormWithA then TFormWithA(Form).FormAction := FrmAction;

Deze if match alleen als de form ook een action heeft en anders gebeurt er niks.

Ok ik hoop dat ik duidelijke genoeg geweest ben? Anders moet je misschien ook even de declaratie posten van een Form met een action.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Niet alle Form's hebben een FormAction. FormAction is een integer variable die bepaalde of een Form is geopend door de gebruiker om de gegevens toe te voegen of om ze te wijzigen (bijvoorbeeld klant gegevens).

Een verkleinde versie:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
type
  TKlantenForm = class(TForm)
    btnOK: TButton;
    btnAnnuleren: TButton;
    GroupGegevens: TGroupBox;
    edtNaam: TEdit;
    edtVoorvoegsel: TEdit;
    edtAdres: TEdit;
    edtWoonplaats: TEdit;
    edtTelefoon: TEdit;
    edtPostcode: TMaskEdit;
    edtKoopman: TEdit;
    procedure btnAnnulerenClick(Sender: TObject);
    procedure btnOKClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    FormAction: Integer;
  end;

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Ja en als je dit
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
type
  TKlantenForm = class(TForm)
    btnOK: TButton;
    btnAnnuleren: TButton;
    GroupGegevens: TGroupBox;
    edtNaam: TEdit;
    edtVoorvoegsel: TEdit;
    edtAdres: TEdit;
    edtWoonplaats: TEdit;
    edtTelefoon: TEdit;
    edtPostcode: TMaskEdit;
    edtKoopman: TEdit;
    procedure btnAnnulerenClick(Sender: TObject);
    procedure btnOKClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    FormAction: Integer;
  end;

nu eens vervangt door
code:
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
type
  TFormWithA = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
    FormAction: Integer;
  end;
  TKlantenForm = class(TFormWithA)
    btnOK: TButton;
    btnAnnuleren: TButton;
    GroupGegevens: TGroupBox;
    edtNaam: TEdit;
    edtVoorvoegsel: TEdit;
    edtAdres: TEdit;
    edtWoonplaats: TEdit;
    edtTelefoon: TEdit;
    edtPostcode: TMaskEdit;
    edtKoopman: TEdit;
    procedure btnAnnulerenClick(Sender: TObject);
    procedure btnOKClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

dan kan je in je procedure dus altijd makkelijk checken of er een FormAction aanwezig is, door de boolean
code:
1
  Form is TFormWithA

te evalueren.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Oke, thanks. Ik snap het idee. :)

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Je kunt ook dit doen, als FormAction published is [procedures komen uit TypeInfo]:
code:
1
2
if TypeInfo.IsPublishedProp(Form, 'FormAction') then
  TypeInfo.SetPropValue(Form, 'FormAction', FrmAction);

En je kunt volgens mij ShowSubWindow beter in de sub-forms zetten dan in de MainForm.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Op maandag 21 januari 2002 13:51 schreef DiFool het volgende:
[..]

En je kunt volgens mij ShowSubWindow beter in de sub-forms zetten dan in de MainForm.
Daar zit wat in. :)


Edit: heb dat maar gedaan, dus in bijna elk Form een procedure die het openen voor zijn rekening neemt.

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

BTW voor modalforms maak ik meestal dit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
TMyModalForm = class(TForm)
public
  class function Execute([Eventuele vars]): Boolean;
end;

[..]

class function TMyModalForm([Eventuele vars]).Execute: Boolean;
begin
  with TMyModalForm.Create(nil) do
  try
    // Init met [Eventuele vars]
    Result := ShowModal = mrOk;
  finally
    Free; { Of Release }
  end;
end;

Dan kun je zeggen:
code:
1
2
if TMyModalForm.Execute then
  { Doe iets }

  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

Even een vraagje voor DiFool.


Ik ben bekend met het statement class voor een procedure, functie of variabele. Voor iedereen die dit niet weet: De procedure, functie of variabele gedifinieerd met class werkt niet op het object maar op de klasse. Hiermee kun je bijvoorbeeld bij houden hoeveel instanties van het object gecreëerd zijn.


De vraag: waarom gebruik je class voor de execute van het formulier? De execute heeft toch alleen invloed op het gecreërde venster?
:?

www.fendt.com | Nikon D7100 | PS5


Verwijderd

FendtVario: De execute heeft toch alleen invloed op het gecreërde venster?

Ja, dat klopt :)

Voordelen van deze methode:
  • De Create..try..finally..Free is triviaal, maar neemt wel veel plaats inbeslag, op deze manier staat in de code alleen TMyForm.Execute, boeie hoe dat geimplementeerd wordt. [jaja, Separation of Concerns]
  • Bij gebruik van variabele [Execute(var1, var2, var3) etc.] is meteen duidelijk welke variabele gebruikt worden.
  • Code wordt niet gekopieerd; als Execute vaker in de code wordt aangeroepen,
  • dus makkelijker onderhoudbaar [ff aanpassingen maken in Execute, compileren, compiler zegt waar het verder aangepast moet worden :)]
  • Ik vind het wel een grappig truukje :)
Maar misschien bedoel je waarom ik niet gewoon een functie ShowMyModalForm ofzo gebruik ipv de class method. Kwestie van smaak denk ik :9 Ik heb het niet zo op functies zonder object die eigenlijk wel op een object slaan...de class method methode geeft dan ook mooi aan op welke classe het slaat etc.
Pagina: 1