AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Komponente mit TStrings Property erstellen

Ein Thema von GuenterS · begonnen am 9. Sep 2006 · letzter Beitrag vom 19. Jan 2014
Antwort Antwort
Seite 1 von 2  1 2   
Benutzerbild von GuenterS
GuenterS

Registriert seit: 3. Mai 2004
Ort: Österreich > Bad Vöslau
760 Beiträge
 
Turbo Delphi für Win32
 
#1

Komponente mit TStrings Property erstellen

  Alt 9. Sep 2006, 08:59
Hallo,

wie der Titel schon aussagt, habe ich ein kleines Problem beim Erstellen einer Komponente, welche ein TStrings Objekt als Property im OI anbieten soll.

Ich habe mich beim Erstellen, an diverse Tutorials gehalten (zumindest versucht) aber jedesmal, wenn ich die Komponente dann auf ein Formular ziehe, der Property SQL (das ist die TStrings Property) einen String zuweise und das ganze dann noch ein zweites mal versuche, bekomme ich Zugriffsverletzungen, so, dass nur noch das Beenden von Delphi hilft.

Ich verwende Delphi 7 Professional.

Delphi-Quellcode:
unit GSQuery;

interface

uses
  SysUtils, Classes;

type
  TGSQuery = class(TComponent)
  private
    FSQL: TStringList;
    procedure setSQL(const Value: TStringList);
    { Private-Deklarationen }
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    constructor Create(aOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Published-Deklarationen }
    property SQL: TStringList read FSQL write setSQL;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('GS', [TGSQuery]);
end;

{ TGSQuery }

constructor TGSQuery.Create(aOwner: TComponent);
begin
  inherited;
  FSQL := TStringList.Create;
end;

destructor TGSQuery.Destroy;
begin
  FSQL.Free;
  inherited;
end;

procedure TGSQuery.setSQL(const Value: TStringList);
begin
  FSQL := Value;
end;

end.
Was mache ich da nur falsch?
Günter
Pünktlichkeit ist die Fähigkeit vorherzusagen um wieviel sich der Andere verspäten wird.
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#2

Re: Komponente mit TStrings Property erstellen

  Alt 9. Sep 2006, 09:35
Hallo Günter,

der Fehler steckt in der Setter-Methode. Durch die direkte Zuweisung überschreibst du die im Constructor initialisierte Referenz auf das TStringList-Objekt mit einem neuen Zeiger, was zunächst nur zu einem Speicherleck führt. Gleichzeitig übernimmt aber nun das Query-Objekt die Verantwortung für die übergebene Liste, die du vermutlich nach der Zuweisung zur SQL-Eigenschaft freigibst. Damit ist dann der Zeiger innerhalb des Query-Objekts ungültig!

Besser ist es, im Setter den Inhalt der Liste zu kopieren:

FSQL.Assign(Value); Noch ein Vorschlag: ändere den Datentyp von FSQL ab in TStrings. Dadurch kannst du später beliebige TStrings-Nachfolger (z.B. TMemo.Lines) zuweisen. Im Constructor von TGSQuery muß natürlich weiterhin ein TStringList-Objekt instanziiert werden, da TStrings abstrakte Methoden enthält.

Gruß Hawkeye
  Mit Zitat antworten Zitat
Benutzerbild von GuenterS
GuenterS

Registriert seit: 3. Mai 2004
Ort: Österreich > Bad Vöslau
760 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: Komponente mit TStrings Property erstellen

  Alt 9. Sep 2006, 09:54
Danke

Wenn ich Assign verwende klappt es, ein Query Objekt kommt aber nicht wirklich vor, das ist wirklich der komplette Quelltext der Komponente ... die Query kommt erst später dazu


Das mit TStrings habe ich aber nicht hinbekommen, da meckert der Compiler immer über inkompatible Typen.

Delphi-Quellcode:
unit GSQuery;

interface

uses
  SysUtils, Classes;

type
  TGSQuery = class(TComponent)
  private
    FSQL: TStringList;
    procedure setSQL(const Value: TStrings);
    { Private-Deklarationen }
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    constructor Create(aOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Published-Deklarationen }
    property SQL: TStrings read FSQL write setSQL;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('GS', [TGSQuery]);
end;

{ TGSQuery }

constructor TGSQuery.Create(aOwner: TComponent);
begin
  inherited;
  FSQL := TStringList.Create;
end;

destructor TGSQuery.Destroy;
begin
  FSQL.Free;
  inherited;
end;

procedure TGSQuery.setSQL(const Value: TStrings);
begin
  FSQL.Assign(Value);
end;

end.
Günter
Pünktlichkeit ist die Fähigkeit vorherzusagen um wieviel sich der Andere verspäten wird.
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#4

Re: Komponente mit TStrings Property erstellen

  Alt 9. Sep 2006, 10:04
Du mußt die Deklaration im private-Abschnitt ebenfalls ändern:

Delphi-Quellcode:
private
  FSQL: TStrings;
Falls du innerhalb der Komponente einmal auf die TStringList-Eigenschaften zugreifen mußt, benötigst du einen TypeCast:

TStringList(FSQL).Sorted := True; Bei der SQL-Eigenschaft sehe ich diese Notwendigkeit aber nicht.

PS: mit "Query-Objekt" meinte ich eine Instanz deiner TGSQuery-Klasse.

Gruß Hawkeye
  Mit Zitat antworten Zitat
Benutzerbild von GuenterS
GuenterS

Registriert seit: 3. Mai 2004
Ort: Österreich > Bad Vöslau
760 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: Komponente mit TStrings Property erstellen

  Alt 9. Sep 2006, 10:23
Dankeschön, jetzt funktioniert das mal soweit wie ich es wollte.
Günter
Pünktlichkeit ist die Fähigkeit vorherzusagen um wieviel sich der Andere verspäten wird.
  Mit Zitat antworten Zitat
Poolspieler

Registriert seit: 9. Aug 2004
156 Beiträge
 
Delphi XE7 Professional
 
#6

AW: Komponente mit TStrings Property erstellen

  Alt 18. Mär 2013, 20:29
Hallo zusammen,
das Thema ist zwar schon älter - ich habe aber bei gleichem Source-Code folgendes Problem:

Im OI kann ich schön Strings in die Stringliste eintragen (mit dem automatisch öffnenden String-Listen-Editor).
Soweit so gut.

Wenn ich das Programm aber starte, dann sind die eingetragenen Werte nicht mehr vorhanden --> gibt es da einen Trick?
Wo sollen die auch her kommen?

Code:
constructor TGSQuery.Create(aOwner: TComponent);
begin
   inherited;
   FSQL := TStringList.Create;
end;
Im Konstruktor wird FSQL erzeugt --> ist also LEER.
WIE komme ich nun an die zur Designzeit eingetragenen Werte?

Wäre schön, wenn jemand eine Antwort für mich hätte.

Viele Grüße,

Poolspieler
Andreas
  Mit Zitat antworten Zitat
Poolspieler

Registriert seit: 9. Aug 2004
156 Beiträge
 
Delphi XE7 Professional
 
#7

AW: Komponente mit TStrings Property erstellen

  Alt 18. Mär 2013, 21:15
Hallo,
ich bin ein bisschen weiter:

In FSQL sind die Werte schon vorhanden. Allerdings erst nach einem noch unbekannten Zeitpunkt.

Problem ist, dass ich versuche, diese Werte im CONSTRUCTOR einer Combobox zuzuweisen.
Und zum Zeitpunkt des Konstruktors ist FSQL tatsächlich noch LEER!

Code:
constructor TGSQuery.Create(aOwner: TComponent);
 begin
    inherited;
    FSQL := TStringList.Create;
 end;
combobox.Items.Assign(FSQL);
Frage:
WANN werden die Werte nach FSQL geladen?
Ich habe schon das Ereignis AfterConstruction probiert --> da ist FSQL noch LEER!
Mit dem Debugger konnte ich den Zeitpunkt auch noch nicht finden.

Hat jemand eine Idee?

Viele Grüße,

Poolspieler
Andreas
  Mit Zitat antworten Zitat
Volker Z.

Registriert seit: 3. Dez 2012
Ort: Augsburg, Bayern, Süddeutschland
419 Beiträge
 
Delphi XE4 Ultimate
 
#8

AW: Komponente mit TStrings Property erstellen

  Alt 18. Mär 2013, 21:33
Hallo,

hast Du denn einen Setter für FSQL in Deiner Klasse TGSQuery? Schau Dir mal den Quellcode in Post #3 an; da sollte die Lösung stehen.

Gruß
Volker Zeller
  Mit Zitat antworten Zitat
Poolspieler

Registriert seit: 9. Aug 2004
156 Beiträge
 
Delphi XE7 Professional
 
#9

AW: Komponente mit TStrings Property erstellen

  Alt 18. Mär 2013, 21:49
Hallo Volker,
danke für Deine Antwort!

Ja, habe ich schon.

Allerdings stand ich auch gerade ganz schön auf der Leitung:

Im Konstruktor muss es natürlich heißen:
Code:
constructor TGSQuery.Create(aOwner: TComponent);
  begin
     inherited;
     ...
     combobox := TComboBox.Create(Self);
     ...
     FSQL := combobox.Items;
     // und NICHT:
     //FSQL := TStringList.Create;
  end;
Was will ich denn mit ZWEI Listen????????
Es ist halt doch schon spät...

Viele Grüße,

Poolspieler
Andreas
  Mit Zitat antworten Zitat
Gutelo

Registriert seit: 29. Sep 2013
152 Beiträge
 
#10

AW: Komponente mit TStrings Property erstellen

  Alt 19. Jan 2014, 07:37
Noch eine weiterfuehrende Frage,

ich habe auch eine TStrings Liste in den Properties einer eigenen Komponente. Zur Designzeit werden die eingetragenen Werte in der Liste durch eine Setter procedure uebernommen. Nun werden die eigentragenen Werte in der Stringliste dazu verwendet ein Array zu fuellen (wird ebenfalls in der Setter procedure erledigt). Das funktioniert waehrend des Designs prima, allerdings ist das Array zur Laufzeit wieder leer.

Die Komponente ist von TPaintBox abegeleitet. Da das Array vom Typ record ist und einige werte zur Laufzeit geaendert werden kann ich das Erstellen des Arrays nicht einfach in die paint procedure packen, da sonst jedesmal standardwerte im Array stehen.

Gibt es eine procedure die nur einmal nach dem constructor ausgefuehrt wird?

Gutelo


Edit: Habs jetzt so geloest in der paint procedure auch wenns nich ganz optimal ist:

if Length(Arr) = 0 then FillArr(SList, Arr);

Arr ist das Array, SList ist TStrings mit Werten und FillArr eine Prozedur die die Werte aus SList in Arr eintraegt.

Geändert von Gutelo (19. Jan 2014 um 08:08 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:10 Uhr.
Powered by vBulletin® Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2019 by Daniel R. Wolf