Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Eigene Komponente: Problem mit Property Lines: TStrings... (https://www.delphipraxis.net/58121-eigene-komponente-problem-mit-property-lines-tstrings.html)

Ares 1. Dez 2005 16:53


Eigene Komponente: Problem mit Property Lines: TStrings...
 
Hallo!

In meinem anderen Beitrag suche ich nach einem Label, das mehr als 255 Zeichen aufnehmen kann (http://www.delphipraxis.net/internal...=465683#465683). Da keine wirkliche Lösung in Sicht ist, wollte ich es einfach mal mit einer eigenen Komponente versuchen. Ich wollte von einem TLabel ableiten, eine Eigenschaft Lines vom Typ TStrings hinzufügen. Die Unit sieht bis jetzt so aus:

Delphi-Quellcode:
unit MyLabelUnit;

interface

uses Windows, Messages, SysUtils, Classes, Controls, ExtCtrls, Graphics;

type
   TMyLabel = class(TLabel)
   private
     FLines : TStrings;
   protected
     procedure setLines(newLines: TStrings);
   public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
   published
     property Lines : TStrings read FLines write setLines;
   end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Eigene', [TMyLabel]);
end;

constructor TMyLabel.Create(AOwner: TComponent);
begin
  FLines := TStringList.Create;
  inherited Create(AOwner);
end;

destructor TMyLabel.Destroy;
begin
  FLines.Free;
  inherited;
end;

procedure TMyLabel.setLines(newLines: TStrings);
begin
  FLines := newLines;
  self.caption := FLines.GetText;
end;
Wenn ich die Komponente auf einem Form platziere kann ich im Objektinspektor den Eigenschaftseditor für Lines aufrufen und einen Text eingeben. Der Text (beliebig lang) wird auch in das Label "gemalt".

Wenn ich den Eigenschaftseditor von Lines nochmal aufrufen oder das Projekt compilieren will, bekomme ich allerdings folgede Fehlermeldung und Delphi stürzt total ab (muss beendet werden):

Zitat:

---------------------------
Fehler
---------------------------
Zugriffsverletzung bei Adresse 40005982 in Modul 'rtl60.bpl'. Lesen von Adresse 00000026.
---------------------------
OK
---------------------------
Was mache ich hier falsch???


Besten Dank
Ares

teebee 1. Dez 2005 17:07

Re: Eigene Komponente: Problem mit Property Lines: TStrings.
 
Im Konstruktor würde ich inherited zuerst aufrufen.
Die Set-Methode sollte ungefähr so aussehen:
Delphi-Quellcode:
procedure TMyLabel.setLines(newLines: TStrings);
begin
  if Assigned(newLines) then
    FLines.Assign(newLines)
  else
    FLines.Clear;
  //... alles weitere
end;
Gruß, teebee

Ares 1. Dez 2005 17:11

Re: Eigene Komponente: Problem mit Property Lines: TStrings.
 
Zitat:

Zitat von teebee
Im Konstruktor würde ich inherited zuerst aufrufen.
Die Set-Methode sollte ungefähr so aussehen:
Delphi-Quellcode:
procedure TMyLabel.setLines(newLines: TStrings);
begin
  if Assigned(newLines) then
    FLines.Assign(newLines)
  else
    FLines.Clear;
  //... alles weitere
end;
Gruß, teebee


Danke, ich habe beides geändert. Leider hat es keine Besserung gebracht...

teebee 1. Dez 2005 17:46

Re: Eigene Komponente: Problem mit Property Lines: TStrings.
 
Bei mir funktioniert es so. Hast Du die Komponente auch neu installiert?

Ares 1. Dez 2005 18:32

Re: Eigene Komponente: Problem mit Property Lines: TStrings.
 
Zitat:

Zitat von teebee
Bei mir funktioniert es so. Hast Du die Komponente auch neu installiert?


Klar :-) Ich habe auch schon ein eigenes Package erstellt und das installiert. Das selbe Ergebnis... Wenn ich ein neues Projekt erstelle, die Komponente auf dem Form platziere, einen Texte eingebe und dann compiliere erhalte ich die Meldung:

[Fehler] RLINK32: Error opening file "D:\Projekte\test\Unit1.dfm"

Noch ne Idee, was ich falsch machen könnte?

Besten Dank
Ares

Nightshade 1. Dez 2005 18:36

Re: Eigene Komponente: Problem mit Property Lines: TStrings.
 
Nur mal so zur Erklärung :

Delphi-Quellcode:
  FLines := newLines;
Hier wird "FLines" (welches ein Pointer ist) ein neuer Wert zugewiesen, und zeigt nun nicht mehr auf die ursprüngliche Liste, sondern auf "NewLines". Die ursprüngliche Liste ist nur noch Datenmüll im Speicher.


Mit
Delphi-Quellcode:
 FLines.Assign(newLines)
werden die Daten aus "NewLines" in "FLines" kopiert, der Pointer zeigt weiterhin auf die richtige Liste.

( Zumindest wenn ich alles richtig verstanden habe :) )


PS : Schmeiss die Komponente vom Form und neu drauf, das sollte helfen, wenn nicht lösch mal die .DCU von der Komponente, damit er die neu kompiliert.

Muetze1 1. Dez 2005 22:09

Re: Eigene Komponente: Problem mit Property Lines: TStrings.
 
Zitat:

Zitat von teebee
Im Konstruktor würde ich inherited zuerst aufrufen.
Die Set-Methode sollte ungefähr so aussehen:
Delphi-Quellcode:
procedure TMyLabel.setLines(newLines: TStrings);
begin
  if Assigned(newLines) then
    FLines.Assign(newLines)
  else
    FLines.Clear;
  //... alles weitere
end;
Gruß, teebee

Wozu die Unterscheidung? Assign(Nil) löscht auch die Liste, also einfach nur
Delphi-Quellcode:
FLines.Assign(NewLines);
So, und noch zu einem anderen Ding was ich so sehe: Verschiebe das Anlegen der FLines nach dem inherited Create Aufruf.

teebee 2. Dez 2005 08:19

Re: Eigene Komponente: Problem mit Property Lines: TStrings.
 
Zitat:

Zitat von Muetze1
Wozu die Unterscheidung? Assign(Nil) löscht auch die Liste, also einfach nur
Delphi-Quellcode:
FLines.Assign(NewLines);

Assign(Nil) auf einer TStringList-Instanz führt zu einer EConvertError-Exception, da TStrings.Assign an TPersistent.Assign weitergeleitet wird, wenn kein TStrings ankommt. Auszug aus classes.pas von D3 (sieht ähnlich aus in D6):
Delphi-Quellcode:
procedure TStrings.Assign(Source: TPersistent);
begin
  if Source is TStrings then
  begin
    BeginUpdate;
    try
      Clear;
      AddStrings(TStrings(Source));
    finally
      EndUpdate;
    end;
    Exit;
  end;
  inherited Assign(Source);
end;
Man könnte höchstens darüber diskutieren, ob man durch das Abfangen von Nil den 'unsachgemäßen' Gebrauch der Komponente verschleiert, aber das ist Geschmackssache.

Gruß, teebee

Robert Marquardt 2. Dez 2005 08:46

Re: Eigene Komponente: Problem mit Property Lines: TStrings.
 
Wieso soll ein TLabel nicht mehr als 255 Zeichen aufnehmen koennen?
Ich habe gerade nochmal nachgeprueft das mehr Zeichen gehen. Auch Zeilenumbruch ist kein Problem.
Nur der Standard IDE-Editor fuer Strings kann keine Zeilenumbrueche. das kann man aber aendern.

Ares 2. Dez 2005 09:23

Re: Eigene Komponente: Problem mit Property Lines: TStrings.
 
Zitat:

Zitat von Robert Marquardt
Wieso soll ein TLabel nicht mehr als 255 Zeichen aufnehmen koennen?
Ich habe gerade nochmal nachgeprueft das mehr Zeichen gehen. Auch Zeilenumbruch ist kein Problem.
Nur der Standard IDE-Editor fuer Strings kann keine Zeilenumbrueche. das kann man aber aendern.

Welche Delphiversion benutzt du denn? Wenn ich im Objektinspektor Text in das Captionfeld eingebe ist nach 255 Zeichen Schluss... Wenn ich z.B. den Finger auf A lasse wird das Label munter befüllt, nach 255 Zeichen ertönt diese "Windows-Boing" und es ist keine weitere Eingabe möglich.

Wie kann ich denn den IDE-Editor für die Strings ändern bzw. austauschen?

tigerman33 2. Dez 2005 09:28

Re: Eigene Komponente: Problem mit Property Lines: TStrings.
 
Vielleicht liegt das am OI, hast du schon mal probiert, der Caption zur Laufzeit einen String mit mehr als 255 Zeichen zuzuweisen?

Robert Marquardt 2. Dez 2005 09:30

Re: Eigene Komponente: Problem mit Property Lines: TStrings.
 
Delphi 6. Du darfst natuerlich nicht "Huge strings" in den Projektoptionen ausschalten.

Ares 2. Dez 2005 09:47

Re: Eigene Komponente: Problem mit Property Lines: TStrings.
 
Zitat:

Zitat von tigerman33
Vielleicht liegt das am OI, hast du schon mal probiert, der Caption zur Laufzeit einen String mit mehr als 255 Zeichen zuzuweisen?

Klar (siehe einige Beiträge weiter oben...). Es ist gar kein Problem der Caption-Eigenschaft über den Quelltext längere Texte zuzuweisen. Aber wie gesagt wäre es mehr als unpraktisch und unübersichtlich für jedes Label eine Zuweisung schreiben zu müssen.


Zitat:

Zitat von Robert Marquardt
Delphi 6. Du darfst natuerlich nicht "Huge strings" in den Projektoptionen ausschalten.

Dann verstehe ich jetzt gar nichts mehr. Warum kannst du im OI beliebig viele Zeichen für die Caption eingeben und ich nicht? An den Projektoptionen habe ich nichts verändert. Option "Huge strings" ist aktiviert. Hast du für die Stringeingabe vielleicht einen anderen Editor aktiviert :?

Robert Marquardt 2. Dez 2005 11:06

Re: Eigene Komponente: Problem mit Property Lines: TStrings.
 
Nein, ich benutze die Defaulteditoren, sprich ich gebe im Objektinspektor ein.
Wenn du die JVCL hast, dann starte doch nochmal den Installer und aktiviere "register global design editors" und installiere durch.
Danach haben Strings den TStringList Editor registriert und erlauben auch mehrzeilige Texte.

Ares 2. Dez 2005 12:10

Re: Eigene Komponente: Problem mit Property Lines: TStrings.
 
Zitat:

Zitat von Robert Marquardt
Nein, ich benutze die Defaulteditoren, sprich ich gebe im Objektinspektor ein.
Wenn du die JVCL hast, dann starte doch nochmal den Installer und aktiviere "register global design editors" und installiere durch.
Danach haben Strings den TStringList Editor registriert und erlauben auch mehrzeilige Texte.

Ok, danke! Das hat prima Funktioniert. Warum der Standardeditor bei dir mehr als 255 Zeichen zulässt ist aber immer noch ein Rätsel.

Parallel habe ich auch noch an meiner eigenen Komponente weiter gearbeitet. Die funktioniert jetzt auch ganz gut. Die Eigenschaften "Caption" und "AutoSize" sind nun überflüssig, werden aber noch im OI angezeigt. Hat jemand einen Tipp, wie ich die dort rausbekomme?

Besten Dank
Ares

Robert Marquardt 2. Dez 2005 12:47

Re: Eigene Komponente: Problem mit Property Lines: TStrings.
 
Das kommt davon wenn du von TLabel ableitest.
Ueblicherweise sind Komponenten als Paare von Klassen implementiert, z. B. TLabel und TCustomLabel.
TLabel macht nur alle Properties published. Die gesamte Implementierung liegt in TCustomLabel.
Das ist noetig, da man zwar bei der Ableitung von protected nach public oder published gehen kann, aber
bei weiterer Ableitung nicht mehr zurueck.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz