Moin allerseits,
ich bin offensichtlich noch nicht so der Held in der Erstellung und Verwendung von Klassen, deshalb hab ich damit auch noch ein paar Verständnis-Probleme ... ich arbeite übrigens bis Ende des Jahres an einem Win7-Kundenrechner mit RadStudio XE2 Architect und nicht wie gewohnt im RadStudio 2009 pro ...
In einer Klasse, die hauptsächlich auf die Mainform zugreift und dort Dinge wie Statusbar und diverse Label-Captions verändern soll, habe ich einen Record definiert:
Delphi-Quellcode:
unit Main_Zugriff;
INTERFACE
USES
Vcl.Forms, System.Classes, System.SysUtils, JvRichEdit, JvDBRichEdit;
TYPE
TMain_Zugriff =
CLASS
PRIVATE
PUBLIC
TYPE
TTab_User =
RECORD
Titel_Index : Integer;
Titel_SortIndex : Integer;
Titel_SortOrder : Boolean;
Titel_SortText :
String;
END;
VAR
User_Tab : TTab_User;
CONSTRUCTOR Create();
DESTRUCTOR Destroy;
override;
PROCEDURE Set_FormMain(
Const Links, Oben, Breit, Hoch : Integer;
Const Maximiert : Boolean);
PROCEDURE Get_FormMain(
Var Links, Oben, Breit, Hoch : Integer;
Var Maximiert : Boolean);
PROCEDURE Set_StatusBar(
Const Spalte : Integer;
Const Wert :
String);
END;
IMPLEMENTATION
USES
UnitMain;
Wenn ich nun in einer AfterScroll-Ereignisbehandlung, die sich in der
Unit zur Form
DatMod (Datamodule) befindet, die Variable User_Tab.Titel_Index setzen möchte, erhalte ich eine Zugriffsverletzung:
Im Projekt MovieBase3.exe ist eine Exception der Klasse $C0000005 mit der Meldung 'c0000005 ACCESS_VIOLATION' aufgetreten.
Delphi-Quellcode:
...
VAR
DatMod: TDatMod;
IMPLEMENTATION
{%CLASSGROUP 'System.Classes.TPersistent'}
{$R *.dfm}
USES
Main_Zugriff;
VAR
MainZu : TMain_Zugriff;
procedure TDatMod.DataModuleCreate(Sender: TObject);
begin
MainZu := TMain_Zugriff.Create;
end;
procedure TDatMod.DataModuleDestroy(Sender: TObject);
begin
FreeAndNil(MainZu);
end;
procedure TDatMod.Aset_TitelAfterScroll(DataSet: TDataSet);
VAR
Idx_Titel : Integer;
begin
Idx_Titel := Aset_Titel.FieldByName('Idx_Titel').AsInteger;
MainZu.Set_StatusBar(0,'Idx: ' + IntToStr(Idx_Titel));
MainZu.Set_StatusBar(1,'Anzahl: ' + IntToStr(Aset_Titel.RecordCount));
MainZu.Set_StatusBar(2,'RecNo: ' + IntToStr(Aset_Titel.RecNo));
MainZu.User_Tab.Titel_Index := Idx_Titel; // hier wird die Zugriffsverletzung ausgelöst
end;
Ein weitgehend ähnliches Konstrukt im selben Projekt funktioniert aber einwandfrei:
Delphi-Quellcode:
UNIT MainTools;
INTERFACE
USES
System.SysUtils, System.Classes,
Vcl.Dialogs, Data.DB, Data.Win.ADODB,
Datasnap.DBClient, Data.DBXFirebird, Data.SqlExpr, Data.FMTBcd, Datasnap.Provider;
TYPE
TMainTools =
CLASS
PRIVATE
CONST
K = '
;';
Km = '
,';
cPROV_Name = '
SQLOLEDB.1';
cDB_Name = '
FILME';
cServer_Name = '
SPEEDY';
cInt_Secur = '
SSPI';
cUser_Name = '
MsMasterAdmin';
cApp_Name = '
MovieBase3';
VAR
PROV_Name,
DB_Name,
Server_Name,
Int_Secur,
User_Name,
App_Name,
Verbindung :
String;
PUBLIC
TYPE
TRec_User =
RECORD
Pfad_Main,
Name,
Pass :
String;
END;
VAR
Rec_User : TRec_User;
SuchText :
String;
CONSTRUCTOR Create();
DESTRUCTOR Destroy;
override;
FUNCTION Verbinden_Datenbank : Boolean;
PROCEDURE Trennen_Datenbank;
FUNCTION Verbinden_Datasets : Boolean;
PROCEDURE Trennen_Datasets;
PROCEDURE Einstellungen_Setzen;
PROCEDURE Einstellungen_Speichern;
END;
IMPLEMENTATION
USES
UnitData, Main_Zugriff;
VAR
MZGF : TMain_Zugriff;
Wenn ich hier vom Hauptformular aus z.B. die Variable
Rec_User.Pfad_Main setze, gibt's keine Zugriffsverletzung:
Delphi-Quellcode:
...
var
FormMain: TFormMain;
IMPLEMENTATION
{$R *.dfm}
USES
MainTools, UnitData;
VAR
MNTL : TMainTools;
procedure TFormMain.FormCreate(Sender: TObject);
begin
MNTL := TMainTools.Create;
MNTL.Rec_User.Pfad_Main := ExtractFilePath(ParamStr(0));
// keine Access Violation
MNTL.SuchText := '
';
// keine Access Violation
end;
...