Delphi Gebruikersgroep

 

Home    Up

Ruzie met Tstrings

Hallo, 

Ik heb ruzie met variabelen van het type Tstrings. Waarschijnlijk doe ik iets niet goed, maar ik kan niet vinden wat. Hieronder een voorbeeldcode: 

unit Unit1; 

interface 

uses 
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; 

type 
TForm1 = class(TForm) 
procedure FormCreate(Sender: TObject); 
private 
{ Private declarations } 
public 
{ Public declarations } 
end; 

var 
Form1: TForm1; 

implementation 

{$R *.DFM} 

Type 
TEmailbericht = Record 
Body: tstrings; 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
var 
Emailbericht: Temailbericht; 
begin 
Emailbericht.Body.add('Test'); 
end; 

end. 

form1 is gewoon een leeg formulier. Het gaat fout bij de toewijzing Emailbericht.Body.add('Test'); Ik krijg hier de volgende exception: EAccessViolation. 

Een zelfde soort probleem krijg ik wanneer ik via Tinifile.ReadSection de waarden in een Tstring probeer te zetten. Ik heb het tijdelijk opgelost door het in een memo te zetten, maar het is natuurlijk niet de mooiste oplossing. 

Wie kan mij helpen? 

Richard Bonkestoter

--

Het probleem waar je mee worstelt is het feit dat je je TStrings niet hebt gecreëerd. Nou kent deze ook geen constructor. Gelukkig kent TStringList deze wel. 

Voorbeeldje: 
[code] 
var 
SL: TStringList; 

procedure TForm1.Form1Create(Sender: TObject); 
begin 
SL:=TStringList.Create; 
SL.Add('Test'); 
end; 

procedure TForm1.Form1Destroy(Sender: TObject); 
begin 
SL.Free; 
end; 
[/code]

--

Hoi Richard, 

Ruzie maken met componenten is een slechte gewoonte (ze winnen namelijk altijd dmv een AV). 

Je probleem is het volgende Tstrings is een verzamel groep die je niet rechtstreeks kun aanspreken. ze worden gebruikt in heel veel tekst afhandelende componenten oa Tmemo,TStringList,items in een tcombobox enz.(Daarom lukt je code met het memo wel!!) 

Verder kun je Tstrings niet in een record gebruiken want je moet iets creeëren waar de tstrings inzit. 

Wat je zou kunnen doen is een component maken waar dit in zit, of gebruik maken van een Frame. en die gebruiken als een component. 

In beide gevallen maak je een property aan van het type Tstrings Zie voorbeeld source voor uitleg tevens wordt er een Tinifile gebruikt om de laatste waarde vast te houden. 
Onder staand unit1.PAS+DFM & unit2.PAS+DFM 

suc6 Roelof 
UNIT1.DFM 
object Form1: TForm1 
Left = 394 
Top = 176 
Width = 484 
Height = 328 
Caption = 'Form1' 
Color = clBtnFace 
Font.Charset = DEFAULT_CHARSET 
Font.Color = clWindowText 
Font.Height = -11 
Font.Name = 'MS Sans Serif' 
Font.Style = [] 
OldCreateOrder = False 
OnCreate = FormCreate 
OnDestroy = FormDestroy 
PixelsPerInch = 96 
TextHeight = 13 
object Button1: TButton 
Left = 400 
Top = 264 
Width = 75 
Height = 25 
Caption = 'Button1' 
TabOrder = 0 
onclik = Button1Click 
end 
end 

UNIT1.PAS 
unit Unit1; 

interface 

uses 
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
Dialogs,Unit2, StdCtrls, inifiles; 
type 
TForm1 = class(TForm) 
Button1: TButton; 
procedure FormCreate(Sender: TObject); 
procedure FormDestroy(Sender: TObject); 
procedure Button1Click(Sender: TObject); 
private 
{ Private declarations } 
Teller : Integer; 
EmailBodyText : TStringList; 
EmailFrame : Tfrm_Email; 
end; 
var 
Form1: TForm1; 
implementation 
{$R *.dfm} 
procedure TForm1.FormCreate(Sender: TObject); 
var 
Aini : TInifile; 
Tekst : string; 
begin 
Aini := TInifile.Create(IncludeTrailingBackslash(ExtractFilePath(ParamStr(0)))+'Data.ini'); 
try 
Tekst := Aini.ReadString('Email','Laatste data','Test'); 
finally 
Aini.Free; 
end; 
// maak een stringlist; 
EmailBodyText := TStringList.Create; 
// vul de stringlist; 
EmailBodyText.Add(Tekst); 
// maak het frame die de email moet tonen 
EmailFrame := Tfrm_Email.Create(self); 
EmailFrame.Top := 10; 
EmailFrame.Left := 10; 
EmailFrame.Parent := self; 
// geef de tekst door aan het frame; 
EmailFrame.EmailBody := EmailBodyText; 
Teller := 0; 
end; 

procedure TForm1.FormDestroy(Sender: TObject); 
var 
Aini : TInifile; 
begin 
Aini := TInifile.Create(IncludeTrailingBackslash(ExtractFilePath(ParamStr(0)))+'Data.ini'); 
try 
Aini.WriteString('Email','Laatste data',EmailBodyText.Text); 
finally 
Aini.Free; 
end; 
EmailBodyText.Free; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
inc(Teller); 
EmailBodyText.Clear; 
EmailBodyText.add('Test '+ IntToStr(Teller)); 
EmailFrame.EmailBody := EmailBodyText; 
end; 

end. 

UNIT2.DFM 
object frm_Email: Tfrm_Email 
Left = 0 
Top = 0 
Width = 320 
Height = 240 
TabOrder = 0 
end 

UNIT2.PAS 
unit Unit2; 

interface 

uses 
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
StdCtrls; 

type 
Tfrm_Email = class(TFrame) 
private 
FEmailBody: TStrings; 
Amemo : Tmemo; 
procedure SetEmailBody(const Value: TStrings); 
{ Private declarations } 
public 
{ Public declarations } 
property EmailBody : TStrings read FEmailBody write SetEmailBody; 
end; 
// bewust geen memo in design time er op geplaats 
// zodat duidelijk wordt hoe het werkt 

implementation 

{$R *.dfm} 

{ Tfrm_Email } 

procedure Tfrm_Email.SetEmailBody(const Value: TStrings); 
begin 
// hou de waarde vast in een private variabele 
FEmailBody := Value; 
// maak een memo als die er niet is 
if not assigned(Amemo) then 
begin 
Amemo := TMemo.Create(Self); 
Amemo.Parent := Self; 
Amemo.Top := 10; 
Amemo.Left := 10; 
Amemo.Height := Self.Height - 20; 
Amemo.Width := Self.Width - 20; 
end; 
// vul het memo met de ontvangen tekst; 
Amemo.Lines.Assign(FEmailBody); 
end; 

end.