![]() |
Delphi-Version: 2006
Hint überschreiben
Hallo,
ich würde gerne bei einigen eigenen Komponenten die Eigenschaft Hint so überschreiben, dass ich zur Entwurfszeit einen Hint setze, der aber zur Laufzeit mit zusätzlichen Angaben ergänzt wird. Hint ist ja in TWincontrol so definiert:
Delphi-Quellcode:
Ich hätte nun gern sowas:
property Hint: string read FHint write FHint;
Delphi-Quellcode:
Das Überschreiben grundsätzlich geht ja, wenn ich im Quelltext den Hint abfrage, erhalte ich auch den erweiterten Text, allerdings wird zur Laufzeit nur der Grundtext als Hint angezeigt.
TMyComponent = class(TWinControl)
published property Hint: string read GetHint; end; TMyComponet.GetHint: string; begin result:=FHint+' Mein zusätzlicher Text'; end; Kann ich dies auf Komponentenebene lösen, oder bleibt hier nur der Umweg über eine ApplicationEvents-Komponente, in der ich den Hint entsprechend modifiziere? |
AW: Hint überschreiben
Du willst also im IDE-Editor den Hint ohne den Zusatz-Text haben, zur Laufzeit aber mit?
Dann ist ComponentState dein Freund :) Hier ein Beispiel mit einer TEdit-Ableitung:
Delphi-Quellcode:
Natürlich würd ich an deiner Stelle den Zusatz-Text auch noch dynamisch setzen, aber das ist ja ein Kinderspiel :)
unit my_hintedit;
interface uses Classes,StdCtrls ; type TmyHintEdit = class(TEdit) private FHint: string ; function GetHint(): string ; public constructor Create(AOwner: TComponent) ; override ; published property Hint read GetHint write FHint ; end; procedure Register; implementation // Constructor constructor TmyHintEdit.Create(AOwner: TComponent); begin inherited Create(AOwner); end; // Get hint (without additional Text in IDE, with additional text at runtime) function TmyHintEdit.GetHint(): string; begin // in IDE if (csDesigning in ComponentState) then Result := FHint // at runtime else Result := FHint + ' <Zusatz-Text>' ; end; // Register the new control in a toolbar procedure Register; begin RegisterComponents('My Controls', [TmyHintEdit]); end; end. |
AW: Hint überschreiben
Ausprobiert hab ichs, aber tun tuts nicht.
Wenn ich den Hint direkt auslese(z.b. Form.Caption:=MyEdit.Hint), wird er, wie in meinem Beispiel auch, richtig zugewiesen. Wenn ich mit der Maus über das Edit fahre, sehe ich jedoch nichts. Ich denke, da auch hier nichts mit overload deklariert wird, greift die VCL auf alle Components als TWinControl zu (cast) und dadurch wird der Hint der Basisklasse im Hintfenster angezeigt, der ja aber im Beispiel nicht gesetzt wird, da in der vererbten Klasse ein neuer Hint definiert wird. |
AW: Hint überschreiben
Eine dumme Frage: ShowHint hast Du aber auf true gesetzt, oder?
|
AW: Hint überschreiben
Ah, stimmt...er hat recht.
Das Mouseover funktioniert nicht mehr, sobald man Hint überschreibt. Wenn man im Constructor die Property mit inherited überschreibt, gehts auch nicht. Mal überlegen.... |
AW: Hint überschreiben
Funktioniert es so?
Delphi-Quellcode:
type
TmyHintEdit = class(TEdit) private function GetHint: string; procedure SetHint(const value: string); published property Hint: string read GetHint write SetHint; end; ... function TmyHintEdit.GetHint: string; begin Result := inherited Hint; end; procedure TmyHintEdit.SetHint(const value: string); begin if not (csDesigning in ComponentState) then inherited Hint := value + ' Test' else inherited Hint := value; end; |
AW: Hint überschreiben
Wie ich die VCL kenne wird sicherlich innerhalb der Klasse auf den Hint nur über die private FHint-Variable verwiesen.
|
AW: Hint überschreiben
Jup, sieht ganz so aus :wall::wall:
|
AW: Hint überschreiben
Beim MouseEnter Alten Hint merken, ergänzen
Beim MouseLeave Alten Hint zurückschreiben Oder, wenn du z.B. beim überfahren der Items einer Listbox die Caption des Items als Hint haben möchtest :
Delphi-Quellcode:
Lässt sich sicherlich auch auf andere Controls ausweiten ohne eine neue Klasse abzuleiten
procedure TForm1.ListBoxMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer); var item : integer; HS : string; LB : TListBox; begin LB := Sender as TListbox; item := LB.itemAtpos(Point(x, y), true); if item >= 0 then begin HS := LB.Items.Strings[Item]; if HS <> LB.Hint then begin LB.Hint := HS; Application.ActivateHint(Point(x, y)); end; end; end; |
AW: Hint überschreiben
Zitat:
Inzwischen hab ich meinen Code in den Komponenten noch etwas hin und her geschoben und mache es so: Alle Komponenten, für die ich das ganze brauche (Abgeleitet von Shape, Label, Bitmap, Edit...) haben sowieso ein gemeinsames Interface. Ich verwende ein TApplicationEvents-Objekt und in OnShowHint:
Delphi-Quellcode:
Aber ich wollte das ganze halt am liebsten in die Komponenten rein schieben, damit ich nicht in jedem Projekt im Hauptformular an den zitierten Code denken muss.
procedure TMainWindow.ApplicationEvents1ShowHint(var HintStr: string;
var CanShow: Boolean; var HintInfo: THintInfo); begin if Supports(HintInfo.HintControl, IMyInterface) then begin HintStr:=Hintstr+' '+(HintInfo.HintControl as IMyInterface).myZusatzHint; end; end; Da vermute ich jetzt einfach, dass es mit dem Hint überschreiben nicht geht, wenn nicht noch jemand eine geniale Idee hat. Gruß Rainer |
AW: Hint überschreiben
Wieso muß man eigentlich einen eigenen Hint-Property erstellen?
Die VCL kennt nur "ihr" Property und nutzt auch dieses für die Anzeige. Was sie nicht kennt, das kann die VCL nicht nutzen. |
AW: Hint überschreiben
Zitat:
|
AW: Hint überschreiben
Zitat:
Ausserdem haben die Komponenten noch Eigenschaften, die sie mit der Steuerung verknüpfen, welches Eingangsbit, oder Merkerbit z.b. mit der Komponente angesprochen wird. Diese Info möchte ich zusätzlich zur eigentlichen Komponentenbedeutung im Hint anzeigen, also z. B. "Kontrollschalter Türe (Eingang 8.0)", aber nicht grundsätzlich, sondern wählbar. Gruß Rainer |
AW: Hint überschreiben
Entweder du mußt ständig/regelmäßig alle Hint-Texte anpassen, also vorsorglich bevor sie angezeigt werden könnten, oder ...
entweder man definiert einen Marker, welcher dann ersetzt wird:
Delphi-Quellcode:
das geht auch mit Teilen
Label1.Hint := ':MyHint:'; // natürlich im OI deklariert
Label1.ShowHint := True; procedure TForm5.FormCreate(Sender: TObject); begin Application.OnShowHint := ShowHint; end; procedure TForm5.ShowHint(var HintStr: string; var CanShow: Boolean; var HintInfo: Controls.THintInfo); begin if HintStr = ':MyHint:' then HintStr := 'die aktuelle Zeit ist ' + TimeToStr(Now); if HintStr = ':MyOtherHint:' then HintStr := 'das aktuelle Datum ist ' + DateToStr(Now); end;
Delphi-Quellcode:
man kann aber auch über's Control gehn:
Label1.Hint := 'die aktuelle Zeit ist :MyHint:';
Label1.ShowHint := True; procedure TForm5.FormCreate(Sender: TObject); begin Application.OnShowHint := ShowHint; end; procedure TForm5.ShowHint(var HintStr: string; var CanShow: Boolean; var HintInfo: Controls.THintInfo); begin HintStr := StringReplace(HintStr, ':MyHint:', TimeToStr(Now), []); HintStr := StringReplace(HintStr, ':MyOtherHint:', DateToStr(Now), []); end;
Delphi-Quellcode:
ShowHint wird immer aufgerufen, kurz bevor irgendein Hint angezeigt wird.
procedure TForm5.FormCreate(Sender: TObject);
begin Application.OnShowHint := ShowHint; end; procedure TForm5.ShowHint(var HintStr: string; var CanShow: Boolean; var HintInfo: Controls.THintInfo); begin if HintInfo.HintControl = Label1 then HintStr := 'die aktuelle Zeit ist ' + TimeToStr(Now); end; Aber schöner wäre es natürlich, wenn in jeder Komponente auch ein OnHint existieren würde, damit man vor Ort reagieren und sich dort entsprechende Eventhandler schreiben könnte. Gut, man könnte auch ein anderes Event mißbrauchen, welches man sonst nirgends in der Anwendung verwendet hat. > OnEndDock bietet sich oftmals an
Delphi-Quellcode:
Label1.ShowHint := True;
Label1.OnEndDock := Label1EndDock; procedure TForm5.FormCreate(Sender: TObject); begin Application.OnShowHint := ShowHint; end; procedure TForm5.ShowHint(var HintStr: string; var CanShow: Boolean; var HintInfo: Controls.THintInfo); begin if Assigned(TForm(HintInfo.HintControl).OnEndDock) then begin TForm(HintInfo.HintControl).OnEndDock(HintInfo.HintControl, nil, 0, 0); HintStr := TForm(HintInfo.HintControl).Hint; end; // TForm wurde nur verwendet, da .Hint und end; // .OnEndDock in TControl als protected deklariert sind procedure TForm5.Label1EndDock(Sender, Target: TObject; X, Y: Integer); begin TLabel(Sender).Hint := 'die aktuelle Zeit ist ' + TimeToStr(Now); // oder Label1.Hint := 'die aktuelle Zeit ist ' + TimeToStr(Now); end; |
AW: Hint überschreiben
Zitat:
|
AW: Hint überschreiben
Klar könnte man im Prinzip alle Hints sofort anpassen, wo sich der Status ändert.
Also entweder bekommt man die Änderung mit und ändert da auch den Hint oder man pollt eben über 'nen Timer o.Ä. und fragt ständig alle Status (mit langem U oder halt Statusse :stupid:) abund setzt die Hints neu. Auch wenn die meisten der jedesmal gesetzten Hints wohl niemals angezeigt wird. (also könnte man das Ganze uch wieder als Pollen bezeichnen, was aus irgendwelchen unerfindlichen Gründen einige/viele nicht mögen :roll: ) Oder man reagiert eben auf das Anzeigen eines Hints, fragt kurz den aktuellen Status ab und setzt nur diesen einen Hint. |
AW: Hint überschreiben
Mal ein anderer Lösungsansatz:
Hints sind in der Regel zweigeteilt. Es gibt den Shorthint und den LongHint. Untergebracht sind beide im Hinttext, getrennt durch das Pipe-Symbol. WEnn man jetzt zur Laufzeit etwas einfach an den Hint dranhängt, dann hängt man eigentlich etwas an den Longhint-Anteil an. Ich habe nicht den blassesten Dunst eines Schimmers einer ahnung, wo und wann zum Henker der Longhint eigentlich angezeigt werden soll. Ich hab ihn jedenfals noch nie gesehen. Also muss der Hint zur Laufzeit von dem "|" befreit werden, dann sollte das IMHO auch klappen. Sherlock PS: Falls das alles Kokolores ist, bitte schnell wieder vergessen. PPS: Die OH sagt zum LongHint, der könne im OnHint mit GetLongHint extrahiert werden...für eine weitere Verwendung. S. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:04 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