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/)
-   -   Methodenzeiger zur Designtime (https://www.delphipraxis.net/159515-methodenzeiger-zur-designtime.html)

Medium 31. Mär 2011 10:43

Methodenzeiger zur Designtime
 
Mahlzeit!

Meine Problemstellung: Ich habe auf einem Formular diverse Komponenten unterschiedlicher Klassen sitzen, und diese sollen eine Beschriftung in Form eines Labels erhalten. Diese Beschriftung ergibt sich im Regelfall aus dem Namen der zu beschriftenden Komponente, es können aber Variationen nach diversen Regeln vorkommen (z.B. eine zweite Komponente spendiert einen Teil der Beschriftung, oder es sind Zeichen zu entfernen, etc.). Die Anzahl, Art, Anordnung und Funktion der Komponenten ist dabei völlig beliebig, d.h. ich kann keine "Labeled"-Komponenten erstellen, bzw. würde das die gewünschte Arbeitsersparnis nicht aufwiegen.
Das ganze muss noch unter Delphi 7 gehen.

Eine eigene Label-Komponente habe ich bereits, die würde ich gern dahin gehend erweitern. Meine Idee so weit:
Delphi-Quellcode:
  TMyLabelBuilder = procedure(var Output: String; String1, String2, String3, String4: String) of object;
  TMyLabel = class(TGraphicControl)
  private
    FCaption: String;
    FSource1: TComponent;
    FSource2: TComponent;
    FSource3: TComponent;
    FSource4: TComponent;
    FOnBuild: TMyLabelBuilder;
  protected
    procedure Paint; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Caption: String    read FCaption write SetCaption;
    property Source1: TComponent read FSource1  write SetSource1;
    property Source2: TComponent read FSource2  write SetSource2;
    property Source3: TComponent read FSource3  write SetSource3;
    property Source4: TComponent read FSource4  write SetSource4;
    property OnBuildCaption: TMyLabelBuilder read FOnBuild write SetOnBuild;
  end;

implementation

procedure TMyLabel.Paint;
var
  s1, s2, s3, s4: String;
begin
  inherited;

  if Assigned(FOnBuild) then
  begin
    if Assigned(FSource1) then s1 := FSource1.Name else s1 := '';
    if Assigned(FSource2) then s2 := FSource2.Name else s2 := '';
    if Assigned(FSource3) then s3 := FSource3.Name else s3 := '';
    if Assigned(FSource4) then s4 := FSource4.Name else s4 := '';
    FOnBuild(FCaption, s1, s2, s3, s4);
  end;
  // Eigentliches Zeichnen
end;
Ich setze dann ein solches Label auf ein Formular, und schreibe dort einen Event-Handler für OnBuildCaption. Problem: Assigned(FOnBuild) scheint zur Designtime immer false zu sein, sprich die eigentliche Zuweisung der Methode findet nicht statt. Ließe sich das ähnlich, oder ggf sogar ganz anders lösen?
Ich könnte natürlich auf die Designtime verzichten, und dort mit einer Dummy-Caption arbeiten, aber es wäre erheblich komfortabler dort gleich die richtigen zu sehen. Besonders um die Platzierung besser handhaben zu können.

Bevor jemand fragt: Sinn des ganzen ist, dass solche Komponentengrüppchen bei uns oftmals einmalig erstellt werden, und dann vielfach und ggf. leicht abgewandelt kopiert werden, wobei sich die ganzen Namen der Komponenten ändern. Ich will mir/uns also im Grunde das zusätzliche manuelle Ändern der Beschriftungen ersparen. Das wäre ein erheblicher Zeitfaktor der sich so eliminieren ließe.

stahli 31. Mär 2011 11:32

AW: Methodenzeiger zur Designtime
 
Gibt es unterschiedliche Handler?
Notfalls könntest Du einen "Standardhandler" im Constructor zuweisen, der ggf. zur Designzeit überschrieben wird.

Medium 31. Mär 2011 11:44

AW: Methodenzeiger zur Designtime
 
Naja, das ist grad leider der Punkt. Es gibt praktisch kein Standardverhalten. Ich habe hier z.B. ein mal den Fall, dass einfach nur der Name von Source1 übernommen wird. Dann, dass der Name von Source1 abzüglich des ersten Zeichens, plus eines festen Zwischenteils, plus dem Namen von Source2 zusammen gebaut wird. Dann einen Fall, wo Präfix + Source1 steht, und einen mit den letzten 3 Zeichen von Source1 plus eines Suffix. Das kann total beliebig sein, daher ja überhaupt die Motivation einen Handler für dieses Zusammenbasteln zu erstellen. Das Dingen ist auch: Es müssen nachher Mitarbeiter damit klar kommen, die die Quelle der Labelkompo nicht haben/kennen/verändern dürfen, so dass diese Custom-Prozedur nicht in dessen Source stehen kann.


Edit:
Ich habe mal ein wenig rumgespielt, und die Prozedur SetMethodProp() in der Unit TypInfo aufgetan. Problem:
Delphi-Quellcode:
procedure TMyLabel.SetOnBuild(const Value: TMyLabelBuilder);
begin
  SetMethodProp(self, 'OnBuildCaption', TMethod(Value));
end;
An sich(!) scheint das garnicht mal so übel, das Dingen ist jedoch, dass TMethod(Value).Code immer 1 ist, wodurch ein Assigned() natürlich false ergibt. Der .Data Anteil hat einen realistischer aussehenden Wert, jedoch gibt es beim Aufrufen natürlich Schelte in Form einer Exception.
Alles auch irgendwo logisch, da dieses TMethod zur Designtime ja kaum mehr als ein Dummy-Wert sein kann, da die Adresse mangels Kompilierung ja noch nicht bekannt ist. Ich suche daher nach einem Weg, Delphi mitteilen zu können: "Bitte bitte kompilier diesen Fetzen, und lass mich ihn aufrufen."
Bei meinen Suchen bin ich hier und da über die ToolsAPI gestolpert, habe aber keinerlei Erfahrung in diesem Zusammenhang. Gibt es da ggf. einen Weg?


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:54 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