AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Allgemeine Frage zu Zuweisungen von Instanzen

Ein Thema von guidobrose · begonnen am 14. Jun 2007 · letzter Beitrag vom 15. Jun 2007
Antwort Antwort
Seite 1 von 2  1 2      
guidobrose
(Gast)

n/a Beiträge
 
#1

Allgemeine Frage zu Zuweisungen von Instanzen

  Alt 14. Jun 2007, 14:29
Hallo, ich habe zwar grad ein Tutorial durchgelesen, aber es werfen sich doch noch Fragen auf.

Ich habe zwei Instanzen z.B.
Delphi-Quellcode:
var Liste1, Liste2: TStringlist;

Liste1:=TStringlist.Create;
Liste2:=TStringlist.Create;
Durch diese Zuweisungen wird jetzt der notwendige Speicher für die Listen reserviert und der Zeiger darauf in "Liste1" und "Liste2" gespeichert, oder?
Liste2:=Liste1; Dies bewirkt nun das der Zeiger auf den Speicher von Liste1 auf Liste2 kopiert wird. Damit greifen beide Variablen nun auf den selben Speicherbereich (auf die gleiche Liste) zu. Der vorher zugewiesene Speicherbereich von Liste2 ist damit zwar noch im Speicher vorhanden, aber nicht mehr erreichbar (und damit verwaist), oder?

Delphi-Quellcode:
var Liste1, Liste2: TStringlist;

Liste1:=TStringlist.Create;
Liste2:=Liste1;
Das sollte demnach auch funktionieren, da ja durch die Variablendeklaration der Speicher für den Zeiger auf eine Liste erzeugt wurde und nun der Inhalt von Liste1 auch über Liste2 erreichbar ist, oder?

Jetzt noch eine etwas spezieller auf mein eigentliches Problem zugeschnittene Frage:
Ich möchte eine Klasse von TEdit ableiten und dieser eine Funktion Autocomplete verpassen. Für diese Funktion benötige ich natürlich auch eine Liste, die die Strings enthält, in denen gesucht wird. Also ungefähr so:
Delphi-Quellcode:
  TXTEdit = class(TEdit)
  private
    FAutocomplete: Boolean;
    FSearchList: TStringlist;
  protected
    procedure DoAutocomplete;
    procedure CMChanged(var Message: TMessage); message CM_CHANGED;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    property Autocomplete: Boolean read FAutocomplete write FAutocomplete default False;
    property Searchlist: TStringlist read FSearchlist write FSearchlist;
  end;
Meine Idee ist, irgendwo im aufrufenden Programm zu schreiben:
Delphi-Quellcode:
  MyEdit.Searchlist:=EineStringliste;
  MyEdit.Autocomplete:=True;
wobei EineStringliste einiges sein kann, z.B. EinStringGrid.Cols[0] oder EineListbox.Items

Leider funktioniert das nicht so ganz wie ich will, sondern führt noch zu einer Zugriffsverletzung. Eigentlich sollte es doch nicht notwendig sein eine Instanz von FSearchlist im constructor zu erzeugen, mir reicht es ja, den Zeiger auf die zugewiesenen Liste zu haben, oder? Ich habe zwar beide Varianten bereits ohne Erfolg ausprobiert, aber mir gehts darum grundsätzlich zu verstehen, ob das so gehen müsste.

Ich hoffe, jemand kann mir auf meine Anfängerfragen eine Antwort geben. Es ist echt tragisch, man glaubt, jetzt kann ich genug, um ohne Hilfe weiter zu kommen und schon stößt man auf das nächste Problem.

Guido
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#2

Re: Allgemeine Frage zu Zuweisungen von Instanzen

  Alt 14. Jun 2007, 14:33
Delphi-Quellcode:
property Searchlist: TStringlist read FSearchlist write FSearchlist; // Falsch
property Searchlist: TStrings read FSearchlist write FSearchlist; // Besser
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.639 Beiträge
 
#3

Re: Allgemeine Frage zu Zuweisungen von Instanzen

  Alt 14. Jun 2007, 14:36
Also beide Annahmen oben stimmen.
Die 'verwaiste' TStringList aus der ersten Annahme nennt man übrigens ein Speicherleck. -> Speicher der angefordert wird aber nie freigegeben wird.

property Searchlist: TStringlist read FSearchlist write FSearchlist; Pfui.

Delphi-Quellcode:
[...]
function getSearchList:TStringlist;
[...]
property Searchlist: TStringlist read getSearchList write FSearchlist;
Und dann weiter:
Delphi-Quellcode:
function TXTEdit.getSearchList: TStringList;
begin
  if not Assigned(FSearchList) then
    FSearchList := TStringList.Create();

  result := FSearchList;
end;

destructor TXtEdit.Destory;
begin
  if Assigned(FSearchList) then
    FreeAndNil(FSearchList);

  inherited;
end;
Somit bekommst Du die Instanz der Searchlist genau dann, wenn Du das erste mal drauf zugreifst und räumst sie wieder auf, wenn Dein Edit zerstört wird.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
guidobrose
(Gast)

n/a Beiträge
 
#4

Re: Allgemeine Frage zu Zuweisungen von Instanzen

  Alt 14. Jun 2007, 14:51
Delphi-Quellcode:
property Searchlist: TStringlist read FSearchlist write FSearchlist; // Falsch
property Searchlist: TStrings read FSearchlist write FSearchlist; // Besser
Mit TStringlist und TStrings bin ich mir im Gebrauch nicht immer sicher, aber da TListbox.Items auch vom Typ TStrings ist, wird es wohl so sein.

Delphi-Quellcode:
[...]
function getSearchList:TStrings;
[...]
property Searchlist: TStrings read FSearchList write SetSearchlist;
Sollte es nicht so herum sein. Ich erzeuge doch die Liste, wenn ich an Searchlist etwas zuweise, oder?

ABER Warum muss ich diese Liste überhaupt erzeugen? Der Speicher für die Liste ist doch bereits durch die Liste vorhanden, die ich an das XTEdit zuweisen möchte. Mir würde ja ein Zeiger darauf ausreichen (Annahme 2) UND erzeuge ich da nicht ein Speicherleck, wenn ich für FSearchlist Speicher reserviere und dieser dann meine "externe" Liste zuweise? Oder bin ich voll daneben?
  Mit Zitat antworten Zitat
Hawkeye219

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

Re: Allgemeine Frage zu Zuweisungen von Instanzen

  Alt 14. Jun 2007, 15:05
Hallo Guido,

Zitat:
Ich möchte eine Klasse von TEdit ableiten und dieser eine Funktion Autocomplete verpassen.
hast du schon einmal daran gedacht, eine TComboBox mit Delphi-Referenz durchsuchenTComboBox.Style = csSimple zu verwenden?

Gruß Hawkeye
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.639 Beiträge
 
#6

Re: Allgemeine Frage zu Zuweisungen von Instanzen

  Alt 14. Jun 2007, 15:13
Zitat von guidobrose:
Oder bin ich voll daneben?
Ja, denn Du willst einem Control für die interne Verwendung externe Objekte zuweisen.

Sorry, aber als Entwickler erwarte ich von einem Control, das es alles mitbring was es braucht.

Wäre ja noch schöner, wenn ich eine ComboBox auf mein Formular ziehe, dass ich dem dann die StringListe in denen die Items stecken auch noch selber ezeugen und zuweisen müsste. Nein, so Dinger hat das Control mitzubringen, und ich muss mich nur noch drum kümmern, dass das richtige da drin steht.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#7

Re: Allgemeine Frage zu Zuweisungen von Instanzen

  Alt 14. Jun 2007, 15:13
Eine Gegenfrage...warum willst du die Liste außerhalb der Componente erzeugen, wenn sie eh nur von der Componente benutzt wird ?

Das mit dem direkten Zuweisen der Zeiger funktioniert deshalb nicht, weil es eben Objekt sind und die nicht nur Daten enthalten. Hinzu kommt, das deine Liste in der Komponente eine Property ist, d.h. da spielt dann noch das Streaming-System für VCL-Komponenten mit rein (wichtig um das z.B. in DFM-Dateien zu speichern) sowie die RTTI.

Ich gehe mal davon aus das du später diese Liste im Objektinspektor editieren willst, dir aber ggf. mehrfach laden bei mehreren XEdit's sparen möchtest. Dann hier mal ein Beispiel wie es funktioniert:


Die Componente (also..der entscheidende Teil davon):

Delphi-Quellcode:
   TXEdit = class(TEdit)
   PRIVATE
      fsearchlist:TStrings;
   PUBLIC
      Constructor Create(AOwner:TComponent);
      Destructor Destroy;Override;
   PUBLISHED
       property Searchlist : TStrings read fsearchlist write fsearchlist;
   END;

   IMPLEMENTATION

   Constructor TXEdit.Create(AOwner:Tcomponent);
   begin
     inherited create(AOwner);
     fsearchlist := TStringlist.create;
   end;
   
   Destructor TXEdit.Destroy;
   begin
    fsearchlist.free;
    inherited;
   end;
Get und Set-Methoden sind nicht unbedingt notwendig, das die Liste beim erzeugen der Komponente gleich mit erzeugt wird und beim zerstören der Komponente freigegeben wird. Das ist wichtig, damit die Liste später auch in der DFM-Datei landet.

Nun zum Programm, das gerne eine Liste an mehrere XEdits verteilen will:

Delphi-Quellcode:
    Procedure TForm1.Button1Click(Sender:TObject);
    var
     iList : TStrings;
    begin
      iList := TStringlist.create;
      iList.loadfromfile('C:\Searchlist.txt');
      XEdit1.Searchlist.assign(iList);
      XEdit2.Searchlist.assign(iList);
      XEdit3.Searchlist.assign(ilist);
      ilist.free;
    end;
Feddich..alle 3 Edits enthalten nun ein kopie der daten aus ilist.

Hoffe das hilft.
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
guidobrose
(Gast)

n/a Beiträge
 
#8

Re: Allgemeine Frage zu Zuweisungen von Instanzen

  Alt 14. Jun 2007, 15:45
Danke für die Infos bisher

@Hawkeye: Nein, da verschwende ich keinen Gedanken daran, weil mir die Combobox nicht gefällt. Die Daten, mit denen mein Autovervollständigen arbeiten soll werden aus einem StringGrid kommen, das aus einer Datenbank gefüllt wird.

Ich habe jetzt mal was probiert, was sogar (weitgehend) funktioniert, aber noch Fragen bei mir aufwirft.

Delphi-Quellcode:
type

  TXTEdit = class(TEdit)
  private
    FAutocomplete: Boolean;
    FBAutocomplete: Boolean;
    FSearchList: TStrings;
    //FOnAutocomplete: TXTAutocompleteEvent;
  protected
    procedure DoAutocomplete;
    procedure CMChanged(var Message: TMessage); message CM_CHANGED;
  public
    constructor Create(AOwner: TComponent);Override;
    destructor Destroy; override;
    property Autocomplete: Boolean read FAutocomplete write FAutocomplete default False;
    //property OnAutocomplete: TXTAutocompleteEvent read FOnAutocomplete write FOnAutocomplete;
    property Searchlist: TStrings read FSearchlist write FSearchlist;
  end;

  TForm3 = class(TForm)
    ListBox1: TListBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
    Edit: TXTEdit;
  public
    { Public-Deklarationen }
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

constructor TXTEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FSearchlist:=TStrings.Create;
end;

destructor TXTEdit.Destroy;
begin
  FSearchlist.Free;
  inherited Destroy;
end;

procedure TXTEdit.DoAutocomplete;
var I, StartPos: Integer;
begin
  if assigned(FSearchlist) then
  begin
    for I:=0 to FSearchlist.Count-1 do
    begin
      if (Text='') or (LowerCase(FSearchlist.Strings[I])=LowerCase(Text)) then
      begin
// if assigned(FOnAutocomplete) then
// OnAutocomplete(I);
        Exit;
      end;
      if StrLComp(PChar(LowerCase(FSearchlist.Strings[I])), PChar(LowerCase(Text)),
        Length(Text)) = 0 then
      begin
        StartPos := Length(Text);
        Text := Text + Copy(FSearchlist.Strings[I], StartPos + 1, Length(FSearchlist.Strings[I]));
        SelStart := StartPos;
        SelLength := Length(Text) - StartPos;
// if assigned(FOnAutocomplete) then
// OnAutocomplete(I);
        Exit;
      end;
    end;
  end;
end;

procedure TXTEdit.CMChanged(var Message: TMessage);
begin
  if FAutocomplete then
    DoAutocomplete;
  inherited;
end;

procedure TForm3.FormCreate(Sender: TObject);
begin
  Edit:=TXTEdit.Create(self);
  Edit.Parent:=Form3;
  Edit.Searchlist:=Listbox1.Items;
end;

procedure TForm3.FormDestroy(Sender: TObject);
begin
  Edit.Searchlist:=nil; //Warum brauche ich das???
end;

end.
Wenn ich die Zeile in FormDestroy nicht einfüge, dann kommt es zu einer ungültigen Zeigeroperation. Warum?
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.639 Beiträge
 
#9

Re: Allgemeine Frage zu Zuweisungen von Instanzen

  Alt 14. Jun 2007, 15:54
Delphi-Quellcode:
procedure TForm3.FormCreate(Sender: TObject);
begin
  Edit:=TXTEdit.Create(self);
  Edit.Parent:=Form3;
  Edit.Searchlist:=Listbox1.Items; // <-- hier überschreibst Du die Instanz
end;
Das Formular will dann die ListBox aufräumen, die Items der Listbox, die die Listbox selber aufräumen will, wurde aber schon vom Edit aufgeräumt (ode rumgekehrt).

Bei den Items musst Du die per Assign von der Listbox auf das Edit kopieren.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
14. Jun 2007, 16:00
Dieses Thema wurde von "Phoenix" von "Object-Pascal / Delphi-Language" nach "VCL / WinForms / Controls" verschoben.
Eigentlich gehts hier ja auch eher um Controls
Antwort Antwort
Seite 1 von 2  1 2      


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 15:00 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz