jeg har en ini fil hvor jeg gemmer mine config. jeg loader dem så på min form1.oncreate, og hvis den er sand så skal den checkke en checkbox på form2. men det kan jeg ikke da den ikke er created inu så jeg får fejl. og den skal ikke stå i form2.oncreate.
Jeg synes en mere korrekt tilgang er at lave en klasse (måske nedarvet fra TIniFile, måske bare fra TObject) der indeholder ini-filens informationer. Objektet skal være synligt i hele programmet og det skal automatisk oprette og slette sig selv ved hjælp af initialization og finalization.
På den måde undgår uskikken at en form skal pille i en anden.
uses IniFiles;
type TIniData = class private fFileName : string; fNavn : string; public constructor Create(aFileName : string); procedure SaveData; destructor Destroy; override; property FileName : string read fFileName; property Navn : string read fNavn write fNavn; end;
var IniData : TIniData;
implementation
const IniFile = 'data.ini';
constructor TIniData.Create(aFileName : string); begin inherited Create; fFileName := aFileName; with TIniFile.Create(fFileName) do try fNavn := ReadString('Navn','John Doe'); finally Free; end; end;
destructor TIniData.Destroy; begin try SaveData; finally Inherited; end; end;
procedure TIniData.SaveData; begin with TIniFile.Create(fFileName) do try WriteString('Navn',fNavn); finally Free; end; end;
initialization
IniData := TIniData.Create(FileName);
finalization
IniData.Free;
end.
Ikke testet, kun tampet ind inden chefen opdager hvad jeg laver...
I praksis betyder dette, at "MainForm" skabes først, hvilket udløser MainForms OnCreated-metode. Første et stykke tid efter bliver Form2 skabt!
Dette medfører problemet med at kommandoer i TFormMain.Create skal bruge controller på Form2, som ikke har nået at blive oprettet - som du selv er inde på!
Derfor følgende rettelse til dit projekt:
Fjern linien "Application.CreateForm(TForm2, Form2)" fra din drp-fil! (Nu bliver Form2) ikke autocreated - bliver slet ikke skabt!) Indsæt følgende linie som nr. 1 i din mainforms OnCreate:
Generelt: Man skal aldrig lade Delphi AutoOprette andre forme end MainForm: Det er dårlig programmering og man kan slå det fra under Tools/Environment Options/Designer "Auto create forms & data modules".
Delphi burde have denne option slået fra som default sådan at man specifikt angiver om en form skal oprettes automatisk. Jeg har set for meget kode hvor formene blev oprettet to gange (men kun den ene vist).
Af samme grund burde man også slette den variabel der altid står nedenfor formens definition, eksempelvis: var frmUnderDialog : TfrmUnderDialog. Den har kun relevans ved ikke-modale forme (se nedenfor).
Skal man rode med autokreerende forme, så kan man gøre som Lars eller bruge Project/Options/Forms (Skift-Ctrl-F11).
Når formene skal vises kan man for modale forme (vist ovenpå de andre) bruge noget lignende disse to eksempler:
1. Den pædagogiske hvor en variabel indeholder formen
var frmUnderDialog : TfrmUnderDialog; begin frmUnderDialog := TfrmUnderDialog.Create(self); try if frmUnderDialog.ShowModal = mrOK then begin // Gør et eller andet end; finally frmUnderDialog.Free; // Alternativt: frmUnderDialog.Release end; end;
2. Den nørdede hvor man ikke har en variabel tilknyttet formen:
with TfrmUnderDialog.Create(self) do try if ShowModal = mrOK then begin // Gør et eller andet end; finally Free; // Alternativt: Release - frigiv formen igen end;
For forme der ikke er modale (hvor man kan skifte til andre vinduer i ens program), er der en anden tilgang:
1. Den besværlige (Man benytter variablen i underformen – den som jeg altid sletter):
// I MainFormen: begin if not assigned(frmUnderForm) then // Vi vil ikke have mere end én frmUnderForm := TfrmUnderForm.Create(self);
frmUnderForm.Show; end;
I Underformen skal OnClose og OnDestroy-eventene bruges:
procedure TfrmUnderForm.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; // Sørger for at frigive data igen end;
procedure TfrmUnderForm.FormDestroy(Sender: TObject); begin frmUnderForm := nil; // Sætter variablen til nil så "if assigned()" fortsat virker end;
2. Den lette:
// I MainFormen: begin // TfrmUnderForm.Create(self).Show; - den nørdede tilgang hvis man bare skal vise formen
with TfrmUnderForm.Create(self) do begin // Hvis data skal sættes forinden // Sæt variabler og lignende Show; end; end;
I Underformen skal kun OnClose-eventen bruges:
procedure TfrmUnderForm.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; // Sørger for at frigive data igen end;
Endelig er der snakken om MDI-børn - men den springer jeg over. Temaet om at åbne forme stopper her.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.