Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi AV bei frmSettings.ComponentCount (https://www.delphipraxis.net/74323-av-bei-frmsettings-componentcount.html)

xZise 1. Aug 2006 12:26


AV bei frmSettings.ComponentCount
 
Ich bekomme eine AV in dieser Zeile:
Delphi-Quellcode:
for i := 0 to frmSettings.ComponentCount - 1 do begin
Code:

Delphi-Quellcode:
procedure TfrmSettings.FormCreate(Sender: TObject);
var Ini, Skin : TIniFile;
    s        : String;
    BackgrndFade : TColor;
    i : Integer;
begin
  Ini := TIniFile.Create(ExtractFilePath(application.exename) + 'settings.ini');
  try
    s := Ini.ReadString('Settings', 'Skin', ExtractFilePath(Application.ExeName) + 'skins\blue.dpsf');
  finally
    Ini.Free;
  end;

  if FileExists(s) then begin
    Skin := TIniFile.Create(s);
    try
      for i := 0 to frmSettings.ComponentCount - 1 do begin <:=-------- Diese Zeile
        if frmSettings.Components[i] is TXiPanel then begin
          (frmSettings.Components[i] as TXiPanel).ColorFace := StringToColor(Skin.ReadString('Backgrnd', 'Face', '$00FE9741'));
          if (frmSettings.Components[i] as TXiPanel).Name <> 'xiBg' then
            (frmSettings.Components[i] as TXiPanel).ColorGrad := StringToColor(Skin.ReadString('Backgrnd', 'Face', '$00FE9741'))
          else
            xiBg.ColorGrad := StringToColor(Skin.ReadString('Backgrnd', 'Grad', 'clSkyBlue'));

        end;
      end;


{      BackgrndFade := StringToColor(Skin.ReadString('Backgrnd', 'Face', '$00FE9741'));
      xiBg.ColorFace := BackgrndFade;
//      xiInUse.ColorFace := BackgrndFade;
    //  xiInUse.ColorGrad := BackgrndFade;
  //    xiSets.ColorFace := BackgrndFade;
      //xiSets.ColorGrad := BackgrndFade;

      xiBg.ColorGrad := StringToColor(Skin.ReadString('Backgrnd', 'Grad', 'clSkyBlue'));}
      lSkinName.Caption := Skin.ReadString('Skin', 'Name', '<unnamed>');
    finally
      Skin.Free;
    end;
    eSkinPath.Text := s;

  end else begin
    lSkinName.Caption := 'Blue';
    eSkinPath.Text := ExtractFilePath(Application.ExeName) + 'skins\blue.dpsf';
    Showmessage('Skinfile not found!');
  end;
end;
So sieht sie aus:
Code:
---------------------------
Debugger Exception Notification
---------------------------
Project DarkPlayerII.exe raised exception class EAccessViolation with message 'Access violation at address 0041A778 in module 'DarkPlayerII.exe'. Read of address 00000010'. Process stopped. Use Step or Run to continue.
---------------------------
OK  Help  
---------------------------

hoika 1. Aug 2006 12:35

Re: AV bei frmSettings.ComponentCount
 
Hallo,

lass das frmSettings mal komplett weg.
Wahrscheinlicb erzeugst du dein Formular ohne diese Variable.
Die wäre dann NIL, und damit bekommst du dann deine Schutzverletzung.

Heiko

xZise 1. Aug 2006 12:40

Re: AV bei frmSettings.ComponentCount
 
Zitat:

Zitat von hoika
Wahrscheinlicb erzeugst du dein Formular ohne diese Variable.

Also ich erzeuge sie so:
Delphi-Quellcode:
with TfrmSettings.Create(self) do
liegt das vielleicht daran?

[edit] Also so funktionierts (mit weglassen), aber warum funktionierts nicht andersherum?[/edit]

jfheins 1. Aug 2006 12:42

Re: AV bei frmSettings.ComponentCount
 
Ja. Wenn dann Self.xyz, aber nicht aus der Klasse auf die globale Variable zugreifen, die eigentlich das Objekt selbst beinhalten sollte (oder es wie hier eben nicht tut ^^) ;)

@edit: weil du die globale Variable frmSetting nicht belegst, sondern nur den Konstruktor usführt, und du somit nur auf zwei Wege auf das Objekt zugreifen kannst: 1. innerhalb der Klasse z.B. mit Self und 2. innerhalb des with Blicks.

xZise 1. Aug 2006 12:45

Re: AV bei frmSettings.ComponentCount
 
Also statt self USettings.TfrmSettings ?

jfheins 1. Aug 2006 12:47

Re: AV bei frmSettings.ComponentCount
 
NEIN :wall:

Also:
statt
Delphi-Quellcode:
frmSettings.ComponentCount
das:
Delphi-Quellcode:
Self.ComponentCount
da frmSettings nicht belegt ist. Da man das Self auch weglassen kann, geht es auch einfach so:
Delphi-Quellcode:
ComponentCount
Jetzt alles ok?

xZise 1. Aug 2006 12:49

Re: AV bei frmSettings.ComponentCount
 
Ja das ist schon klar... Ich meinte beim Create!

jfheins 1. Aug 2006 12:53

Re: AV bei frmSettings.ComponentCount
 
Aso ... das ist ein anderes Paar Schuhe ...

wenn du es so erzeugst:
Delphi-Quellcode:
with TfrmSettings.Create(self) do
dann ist das Objekt, in dessen Methode dies geschieht, der Oner. der Owner gibt das Objekt wieder frei. Der Owner ist über die Property Owner abrufbar.
Die globale Variable frmSettings hat nix damit zu tun. Du könntest die Variable auch entfernen, dann hast du solche Probleme nichtmehr :stupid:

xZise 1. Aug 2006 12:55

Re: AV bei frmSettings.ComponentCount
 
Ich habe nur gefragt, weil es ja diese zuweisung bei "application.CreateForm(X,Y)" gibt. Aber okay :D Ich frag mich gerade wozu man die überhaupt braucht...

hoika 1. Aug 2006 14:08

Re: AV bei frmSettings.ComponentCount
 
Hallo,

das Application.CreateForm erzeugt die Forms schon beim Start des
Programms (FormCreate wird also für jedes Form schon erzeugt).

Vorteil:
Die Forms können mit FormVar.ShowModal oder .Show sofort (schnell) angelegt werden.

Nachteil:
Deer Start dauert länger, Ressourcen werden verbraten.


Bei mir wird nur das Hauptform erzeugt.
Die globalen FormVars lösche ich.
Forms erzeuge ich immer in der folgenden Art:

Delphi-Quellcode:
procedure ExecuteForm_PEP__Main(AnOwner: TComponent);
var
  Form: TForm_PEP__Main;
begin
  try
    Form:= TForm_PEP__Main.Create(AnOwner);
    try
      Form.ShowModal;
    finally
      Form.Free;
    end;
  except
    on E: Exception do MBError(E.message);
  end;
end;
Die Variable ist hier unnütz, aber oft übergebe ich den Forms ja noch was
und speichere das in einer internen Form-Variable.


Heiko

[edit=SirThornberry]Delphi-Tags ergänzt - nächstes mal bitte selbst machen - Mfg, SirThornberry[/edit]

Flocke 1. Aug 2006 19:23

Re: AV bei frmSettings.ComponentCount
 
Zitat:

Zitat von xZise
Ich habe nur gefragt, weil es ja diese zuweisung bei "application.CreateForm(X,Y)" gibt.

Diese Routine prüft, ob es bereits ein Hauptformular gibt (Application.MainForm). Falls nicht, wird das gerade erzeugte Formular dafür genommen. Darum werden die automatischen Formulare in der DPR-Datei alle auf diese Weise erzeugt - das erste davon wird das Hauptformular.

alias5000 1. Aug 2006 19:30

Re: AV bei frmSettings.ComponentCount
 
Zitat:

Zitat von hoika
das Application.CreateForm erzeugt die Forms schon beim Start des
Programms (FormCreate wird also für jedes Form schon erzeugt).

Das stimmt so nicht ganz.
Delphi-Quellcode:
Application.CreateForm(...)
kann jederzeit verwendet werden und stellt normalerweise neben
Delphi-Quellcode:
MeineForm := TMeinForm.Create(...)
die einzigste vernünftige Weise dar, eine Form auf eine normale Weise zu erstellen (d.h. auch füllen der Variable MeineForm, damit man über die den Zugriff drauf hat). Beide Befehle können aber jederzeit ausgeführt werden!

CalganX 1. Aug 2006 19:45

Re: AV bei frmSettings.ComponentCount
 
Hi,
der Routine stammt ja aus der Unit mit dem frmSettings-Formular. D.h. er braucht das Formular nicht erzeugen. :zwinker:

Das Problem ist vielmehr, dass du, xZise, im OnCreate auf die Komponenten zugreifen willst. Das kann schonmal nicht funktionieren, da ja beim Erzeugen des Formulars die ganzen Komponenten, die auf dem Formular liegen, noch gar nicht erzeugt sind.
Lager das, was du jetzt im OnCreate stehen hast, in's OnShow aus und dann sollte es funktionieren.

Chris

alias5000 1. Aug 2006 19:53

Re: AV bei frmSettings.ComponentCount
 
Zitat:

Zitat von Chakotay1308
Das Problem ist vielmehr, dass du, xZise, im OnCreate auf die Komponenten zugreifen willst. Das kann schonmal nicht funktionieren, da ja beim Erzeugen des Formulars die ganzen Komponenten, die auf dem Formular liegen, noch gar nicht erzeugt sind.
Lager das, was du jetzt im OnCreate stehen hast, in's OnShow aus und dann sollte es funktionieren.

Tut mir Leid, nimms net persönlich, aber da muss ich widersprechen. Im OnCreate Ereignis sind bereits alle Komponenten der eigenen Form erstellt, bloß noch nicht angezeigt.

xZise 1. Aug 2006 20:23

Re: AV bei frmSettings.ComponentCount
 
Jap alias:

Alle Ereignisse in OI (OnCreate / OnShow/ OnChange/ OnMouseDown etc.) sind immer die letzten in der Schlange. D.h. davor wird alles andere nötige (createn, zeichen/anzeigen, ändern, kA ^^ etc.) ausgeführt... Du bist sozusagen letzter :D

Wenn ich schon was vor dem create machen will dann muss ich das so machen:
Delphi-Quellcode:
contructor TfrmSettings.Create(AOwner : TComponent);
begin
  {do stuff}
  inherited Create(AOwner) {*}
end;
{*} Es geht zwar auch ohne, also nur inherited, aber manchaml auch wieder nicht (*gg*)

Khabarakh 1. Aug 2006 21:16

Re: AV bei frmSettings.ComponentCount
 
Zitat:

Zitat von xZise
{*} Es geht zwar auch ohne, also nur inherited, aber manchaml auch wieder nicht (*gg*)

"Manchmal" könnte man auch durch "nur bei geerbten Methoden/Kon-/Destruktoren mit gleicher Signatur" ersetzen ;) .


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:23 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz