Einzelnen Beitrag anzeigen

Perlsau
(Gast)

n/a Beiträge
 
#1

Record-Variable in Klasseninstanz setzen

  Alt 9. Dez 2012, 12:39
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;
...
  Mit Zitat antworten Zitat