Entwickler-Ecke

Sonstiges (Delphi) - Zugriffsverletzung 0040... Warum?


DaKirsche - So 09.09.12 12:58
Titel: Zugriffsverletzung 0040... Warum?
Hallo,

Wenn ich mein Programm bei mir starte läuft alles wunderbar.
Da habe ich es jemandem zum Testen zugemailt und bekam eine E-Mail zurück mit einem Bild als Anhang, wo ich nicht nachvollziehen kann, wobei der Fehler zustande kommt:

clip_image002

Ich habe daraufhin den Code des entsprechenden Forms durchsucht aber nix gefunden. Kann mir jemand vll. sagen, wie ich den Fehler identifizieren kann?

Hier der Code des Forms:


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:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
unit loader;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, IniFiles, ExtCtrls, jpeg, Translation;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Timer1: TTimer;
    label_moduleLoading: TLabel;
    Label7: TLabel;
    Image1: TImage;
    Bevel1: TBevel;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure load();
  public
  const version   = '1.0.1.4';
  const built     = 100014;
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  timerCnt: Integer;
  t: TTranslation;
implementation

uses menuSelector, DesktopIniSettings, settings;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
t:= TTranslation.Create();
label4.Caption:= version;
t.translateFormElements(Form1);
end;

procedure TForm1.FormShow(Sender: TObject);
begin
 load();
end;

procedure TForm1.load();
var i  : Integer;
begin
  timerCnt := 0;
  Timer1.Enabled := true;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if (timerCnt = 1then
begin
end;
  if timerCnt = 2 then
  begin
  //creates the Forms
    
    Label_moduleLoading.Caption:= 'SettingsForm';
    Application.ProcessMessages();
    Application.CreateForm(TForm4, Form4);
    Label_moduleLoading.Caption:= 'MainmenueForm';
    Application.ProcessMessages();
    Application.CreateForm(TForm2, Form2);
    Label_moduleLoading.Caption:= 'DesktopIniCreator';
    Application.ProcessMessages();
    Application.CreateForm(TForm3, Form3);
  end;

  if timerCnt = 3 then
  begin
    Label_moduleLoading.Caption:= 'SettingLoader';
    Application.ProcessMessages();
    Form4.initialize();
    Label_moduleLoading.Caption:= 'LanguageLoader';
    Application.ProcessMessages();
    t:= TTranslation.Create();    
    t.translateFormElements(Form4);
    t.translateFormElements(Form2);
    t.translateFormElements(Form3);
  end;

  if timerCnt = 4 then
  begin                
    Label_moduleLoading.Caption:= 'initialize...';
    Application.ProcessMessages();
  //initializes Forms if nessecary
    Form3.setUp();

  end;

  if timerCnt = 5 then
  begin
    Form2.Show();
    Form2.init(Form1);
    Timer1.Enabled := false;
    Form1.Hide;
  end;

  timerCnt := timerCnt + 1;
end;

end.


und die zugehörige Translator


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:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
unit Translation;

interface
uses IniFiles, Forms, SysUtils, Buttons, StdCtrls, ComCtrls, Classes;

type
TTranslation = class
  private
  progPath: String;

  
  public                      
  Constructor Create; overload;
  procedure translateFormElements(selectedForm: TForm);
  function translate(aToTrans: String):String;
end;

implementation
Constructor TTranslation.Create();
begin
   progPath:= ExtractFilePath(ParamStr(0));
   if progPath[Length(progPath)]<>'\' then
      progPath := progPath + '\';
end;

//Function to getTranslation of some String from langfile
function TTranslation.translate(aToTrans: String):String;
var f_conf  : TIniFile;
    f_lang  : TIniFile;
    lang    : String;
begin
   if (FileExists(progPath + 'data\conf\settings.ini')) then
      begin
        f_conf := TIniFile.Create(progPath + 'data\conf\settings.ini');
        with f_conf do begin
          lang := ReadString('config','language','de');
        end;
      end
      else lang := 'de';

  if (FileExists(progPath + 'data\lang\' + lang + '.ini')) then
  f_lang := TIniFile.Create(progPath + 'data\lang\' + lang + '.ini');

  with f_lang do begin
     aToTrans := ReadString('translations',aToTrans,'no_translation');
     aToTrans := StringReplace(aToTrans,'\n',sLineBreak,[rfReplaceAll]);
  end;

  Result:= aToTrans;
end;


procedure TTranslation.translateFormElements(selectedForm: TForm);
var f_conf  : TIniFile;
    f_lang  : TIniFile;
    c_tmp   : Integer;
    c_tmpClass: TClass;
    lang    : String;
    i,a       : Integer;
    sList   : TStrings;
begin
with selectedForm do begin
   if (FileExists(progPath + 'data\conf\settings.ini')) then
      begin
        f_conf := TIniFile.Create(progPath + 'data\conf\settings.ini');
        with f_conf do begin
          lang := ReadString('config','language','de');
        end;
      end
      else lang := 'de';

  if (FileExists(progPath + 'data\lang\' + lang + '.ini')) then
  f_lang := TIniFile.Create(progPath + 'data\lang\' + lang + '.ini');

  with f_lang do begin
    for i := 0 to (ComponentCount - 1do
      if (Components[i].ClassType = TLabel) then
        begin
          with (Components[i]) as TLabel do
          begin
            lang := Caption;
            if (Pos('text_',lang) > 0then
              begin
                lang := StringReplace(lang,'text_','',[rfReplaceAll]);
                lang := ReadString('translations',lang,'');
                lang := StringReplace(lang,'\n',sLineBreak,[rfReplaceAll]);
                if (lang <> ''then
                  Caption:= lang;
              end;
          end;
        end
        else if (Components[i].ClassType = TGroupBox) then
        begin
          with (Components[i]) as TGroupBox do
          begin
            lang := Caption;
            if (Pos('text_',lang) > 0then
              begin
                lang := StringReplace(lang,'text_','',[rfReplaceAll]);
                lang := ReadString('translations',lang,'');
                if (lang <> ''then
                  Caption:= ' ' + lang + ' ';
              end;
          end;
        end
        else if (Components[i].ClassType = TEdit) then
        begin
          with (Components[i]) as TEdit do
          begin
            lang := Text;
            if (Pos('text_',lang) > 0then
              begin
                lang := StringReplace(lang,'text_','',[rfReplaceAll]);
                lang := ReadString('translations',lang,'');
                lang := StringReplace(lang,'\n',sLineBreak,[rfReplaceAll]);
                if (lang <> ''then
                  Text:= lang;
              end;
          end;
        end
        else if (Components[i].ClassType = TSpeedButton) then
        begin
          with (Components[i]) as TSpeedButton do
          begin
            lang := Caption;
            if (Pos('text_',lang) > 0then
              begin
                lang := StringReplace(lang,'text_','',[rfReplaceAll]);
                lang := ReadString('translations',lang,'');
                lang := StringReplace(lang,'\n',sLineBreak,[rfReplaceAll]);
                if (lang <> ''then
                  Caption:= lang;
              end;
          end;
        end
        else if (Components[i].ClassType = TRadioButton) then
        begin
          with (Components[i]) as TRadioButton do
          begin
            lang := Caption;
            if (Pos('text_',lang) > 0then
              begin
                lang := StringReplace(lang,'text_','',[rfReplaceAll]);
                lang := ReadString('translations',lang,'');
                lang := StringReplace(lang,'\n',sLineBreak,[rfReplaceAll]);
                if (lang <> ''then
                  Caption:= lang;
              end;
          end;
        end
        else if (Components[i].ClassType = TCheckBox) then
        begin
          with (Components[i]) as TCheckBox do
          begin
            lang := Caption;
            if (Pos('text_',lang) > 0then
              begin
                lang := StringReplace(lang,'text_','',[rfReplaceAll]);
                lang := ReadString('translations',lang,'');
                lang := StringReplace(lang,'\n',sLineBreak,[rfReplaceAll]);
                if (lang <> ''then
                  Caption:= lang;
              end;
          end;
        end
        else if (Components[i].ClassType = TTabControl) then
        begin
          with (Components[i]) as TTabControl do
          begin
          for a := 0 to (Tabs.Count - 1do begin
            lang := Tabs.Strings[a];
            if (Pos('text_',lang) > 0then
              begin
                lang := StringReplace(lang,'text_','',[rfReplaceAll]);
                lang := ReadString('translations',lang,'');
                lang := StringReplace(lang,'\n',sLineBreak,[rfReplaceAll]);
                if (lang <> ''then
                  Tabs.Strings[a]:= lang;
              end;
          end;
          end;
        end;
  end;
end;
end;

end.


Dann werden nocht die Form3.setUp() aufgerufen:

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:
[...]
//Initialize the Icons from Executeable or Library
procedure TForm3.setUp();
var i: Integer;
begin
i:= 0;
while (i < 25do
begin
      imageC[i]:= TImage.Create(GroupBox9);
      imageC[i].Parent:=GroupBox9;
      imageC[i].Name:='iconimage'+inttostr(i);
      imageC[i].OnClick:=ImageCClick;
      imageC[i].Hint:=IntToStr(i);
      imageC[i].Visible:=false;
      imageC[i].width:=32;
      imageC[i].height:=32;
      imageC[i].Center:=True;
      imageC[i].Cursor:= crHandPoint;
      imageC[i].Top:=(i mod 5)*34 + 20;
      imageC[i].Left:=(i div 5)*34 + 10;
      i:= i+1;
end;
end;
[...]


und die Form2.init()

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
[...]
procedure TForm2.init(fromForm : TForm);
begin
  if fromForm.Visible then
    fromForm.hide();
    //If there is a new Updater Program we need to replace the old one
if FileExists(ExtractFilePath(ParamStr(0)) + 'data\bin\newWSUpdater.exe'then
begin
    DeleteFile(ExtractFilePath(ParamStr(0)) + 'data\bin\WSUpdater.exe');
    RenameFile(ExtractFilePath(ParamStr(0)) + 'data\bin\newWSUpdater.exe',ExtractFilePath(ParamStr(0)) + 'data\bin\WSUpdater.exe');
end;
end;
[...]


Moderiert von user profile iconNarses: Bild als Anhang hochgeladen.


jaenicke - So 09.09.12 16:04

Wo wird Form2 denn erstellt? Das wird ja im Formular aufgerufen.

Um herauszufinden wo der Fehler auftritt kannst du z.B. [url="http://madshi.net/madExceptDescription.htm"]madExcept[/url] benutzen oder mit der Unit JclDebug aus der JEDI JCL selbst einen Stacktrace erstellen. Dafür kannst du ein TApplicationEvents auf das Formular legen und auf OnException reagieren um beim AUftreten einer Exception einen Stacktrace zu haben. Du solltest dann mit Debuginformationen kompilieren (Projektoptionen).


Gerd Kayser - Mo 10.09.12 01:11


Delphi-Quelltext
1:
t:= TTranslation.Create();                    


Das wird zweimal aufgerufen: in TForm1.FormCreate und bei TimerCnt = 3. Da würde ich zuerst mal einen Blick darauf werfen. Ich sehe auch kein "Free".


OlafSt - Di 11.09.12 16:30

Das Problem ist eindeutig in der Timer-Routine zu suchen. Nur so erscheint derselbe Fehler immer wieder in aufgestackten Fenstern.

Leider wurde uns der Inhalt selbiger Routine vorenthalten :-(


DaKirsche - Di 11.09.12 19:56

Wieso vorenthalten^^
Steht doch alles da:


Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if (timerCnt = 1then
[...]


Aber das Problem war tatsächlich der doppelte Kontruktor.

Danke für die schnelle Hilfe.