Delphi-PRAXiS
Seite 1 von 2  1 2      

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/)
-   -   Memo TextHint (https://www.delphipraxis.net/192379-memo-texthint.html)

a.def 13. Apr 2017 12:31

Memo TextHint
 
Ich habe folgende Unit gefunden, um einem Memo ein Multi-Line-TextHint zu verpassen
Delphi-Quellcode:
unit classMemo;

interface

uses StdCtrls, Graphics, Messages, Classes, SysUtils, Controls;

type
 TMemo = class(StdCtrls.TMemo)
 private
  FTextHint: TStrings;
  FTextHintFont: TFont;
 protected
  FCanvas: TCanvas;
  procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
 public
  constructor Create(AOwner: TComponent); override;
  destructor Destroy; override;
 published
  property TextHint: TStrings read FTextHint write FTextHint;
  property TextHintFont: TFont read FTextHintFont write FTextHintFont;
 end;

implementation

constructor TMemo.Create(AOwner: TComponent);
begin
 inherited;
 FTextHint := TStringList.Create;
 FCanvas := TControlCanvas.Create;
 FTextHintFont := TFont.Create;
 FTextHintFont.Color := clGrayText;
 TControlCanvas(FCanvas).Control := Self;
end;

destructor TMemo.Destroy;
begin
 FreeAndNil(FTextHintFont);
 FreeAndNil(FCanvas);
 FTextHint.Clear;
 FreeAndNil(FTextHint);

 inherited;
end;

procedure TMemo.WMPaint(var Message: TWMPaint);
var
 i: integer;
 TextHeight: integer;
begin
 inherited;

 if (Text = '') and (not Focused) then
  begin
   FCanvas.Font := FTextHintFont;
   TextHeight := FCanvas.TextHeight('yY'); // Dummy Text to determine Height

   for i := 0 to FTextHint.Count - 1 do
    FCanvas.TextOut(1, 1 + (i * TextHeight), FTextHint[i]);
  end;
end;

end.
Doch leider kennt der Compiler Memo1.TextHint.Add() nicht, wie das Beispiel eigentlich vorgibt.
Bekommt man irgendwie anders ein TextHint in ein Memo?

Quelle: http://stackoverflow.com/questions/1...nt-for-a-tmemo

Der schöne Günther 13. Apr 2017 12:40

AW: Memo TextHint
 
Was du versuchst ist eine "Interposer"-Klasse. Es reicht nicht diese Unit einfach hinzuzufügen. Denn bislang hast du einmal die Klasse "TMemo" aus "Vcl.StdCtrls", und einmal "deine" neue "TMemo" aus "classMemo". Das TMemo auf deinem VCL-Formular ist weiterhin vom Typ TMemo aus Vcl.StdCtrls.

Du musst in der .pas-Datei deines Formulars vor der Definition von TForm1 (zum Beispiel) noch die Zeile
Delphi-Quellcode:
TMemo = classMemo.TMemo
hinzufügen. Sieht dann so aus:

Delphi-Quellcode:
unit Form1;

interface

uses (...), classMemo;

type
   TMemo = classMemo.TMemo;
   
   TForm1 = class(TForm)
      (...)
   end;
   
implementation

(...)

end.

Vielleicht reicht es einfach nur aus die Unit "classMemo" als letztes in der uses im Interface-Teil zu haben, aber so sieht man wenigstens auf einen Blick dass man bewusst eine Interposer (oder "Cracker")-Klasse ins Spiel lässt.

DeddyH 13. Apr 2017 12:41

AW: Memo TextHint
 
TextHint ist doch vom Typ TStrings, welcher auch eine Add-Methode hat. Bist Du sicher, dass auch Deine Ableitung verwendet wird und nicht das Original-TMemo?

[edit] Und hier lauert auch ein mögliches Memoryleak:
Zitat:

Delphi-Quellcode:
  property TextHint: TStrings read FTextHint write FTextHint;
  property TextHintFont: TFont read FTextHintFont write FTextHintFont;

Mach besser ReadOnly-Properties daraus oder schreib einen kleinen Setter, der mit Assign nur die Werte kopiert. [/edit]

himitsu 13. Apr 2017 12:42

AW: Memo TextHint
 
Entweder du machst das als "richtige" Komponente, welche bei Delphi registriert und "statt" des TMemo auf die Form gelegt wird,

oder deine Unit "classMemo" muß in der Uses-Liste nach/hinter der Unis StdCtrls stehen.

EWeiss 13. Apr 2017 12:45

AW: Memo TextHint
 
Zitat:

Zitat von himitsu (Beitrag 1367510)
Entweder du machst das als "richtige" Komponente, welche bei Delphi registriert und "statt" des TMemo auf die Form gelegt wird,

oder deine Unit "classMemo" muß in der Uses-Liste nach/hinter der Unis StdCtrls stehen.

Richtig.. ;)
Hatte das letztens bei mir auch mit einer eigenen TFont class.
Diese musste ich hinter Graphics einfügen damit es funktioniert.

gruss

a.def 13. Apr 2017 12:47

AW: Memo TextHint
 
Zitat:

Du musst in der .pas-Datei deines Formulars vor der Definition von TForm1 (zum Beispiel) noch die Zeile TMemo = classMemo.TMemo hinzufügen. Sieht dann so aus:
Das funktioniert jetzt. Danke.

Zitat:

oder deine Unit "classMemo" muß in der Uses-Liste nach/hinter der Unis StdCtrls stehen.
Wichtige Info. Hat mir eben Ärger erspart.

Zitat:

[edit] Und hier lauert auch ein mögliches Memoryleak:
Erklärst du mir bitte, warum dort ggf. ein MemoryLeak ist? Ja, das MemoryLeak gibt es wirklich (eben getestet). Aber wieso?

Zacherl 13. Apr 2017 12:48

AW: Memo TextHint
 
Zitat:

Erklärst du mir bitte, warum dort ggf. ein MemoryLeak ist? Ja, das MemoryLeak gibt es wirklich (eben getestet). Aber wieso?
Weil die
Delphi-Quellcode:
TFont
und
Delphi-Quellcode:
TStringList
Instanzen innerhalb deiner gehackten Memo Komponente erzeugt und freigegeben werden. Wenn du jetzt von außerhalb über die Setter neue Instanzen zuweist, wird die interne Instanz nie wieder freigegeben (und unter Umstanden sogar die externe Instanz mehrmals).

DeddyH 13. Apr 2017 12:49

AW: Memo TextHint
 
Die TStrings- und die TFont-Instanz werden ja intern erzeugt und in den jeweiligen Feldern hinterlegt. Wird nun ein anderer Wert zugewiesen, so werden die Felder mit den zugewiesenen Instanzen belegt, die ursprünglichen sind nicht mehr erreichbar und können somit auch nicht mehr freigegeben werden.

a.def 13. Apr 2017 12:53

AW: Memo TextHint
 
Das klingt selbst mir jetzt einleuchtend. Danke habe es verstanden.

Die Felder sind nun ReadOnly un ich mache es so für mehrere Memos
Delphi-Quellcode:
 Memo1.TextHint.Add('1');
 Memo1.TextHint.Add('2');
 Memo1.TextHint.Add('3');

 Memo2.TextHint.AddStrings(Memo1.TextHint);
Klappt wunderbar.

A propos. type TMemo = classMemo.TMemo; kann ich auch aus der Unit rauslassen wo die Memos stehen. Funktioniert trotzdem.

Zacherl 13. Apr 2017 12:54

AW: Memo TextHint
 
Falls du schnell mal z.b. eine andere Font zuweisen willst, dann mach dir einfach zwei richtige Setter Methoden:
Delphi-Quellcode:
type
  TMemo = class(..)
  private
    FTextHintFont: TFont;
  private
    procedure SetTextHintFont(const Value: TFont); inline;
  ..
  published
    property TextHintFont: TFont read FTextHintFont write SetTextHintFont;
  ..
  end;

..

procedure TMemo.SetTextHintFont(const Value: TFont);
begin
  FTextHintFont.Assign(Value);
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:28 Uhr.
Seite 1 von 2  1 2      

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