AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Komponentenentwicklung - Event weiterleiten - Denkfehler?
Thema durchsuchen
Ansicht
Themen-Optionen

Komponentenentwicklung - Event weiterleiten - Denkfehler?

Offene Frage von "Aviator"
Ein Thema von Aviator · begonnen am 27. Sep 2016 · letzter Beitrag vom 27. Sep 2016
Antwort Antwort
Seite 1 von 2  1 2      
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#1

Komponentenentwicklung - Event weiterleiten - Denkfehler?

  Alt 27. Sep 2016, 14:50
Hallo Delphianer,

ich bin gerade dabei mir für einen ganz speziellen Fall eine Komponente zu basteln. Dabei bin ich auf ein Problem gestoßen für das ich aktuell keine Lösung kenne und auch nur bedingt etwas im Internet (auch bei der DP) gefunden hatte. Die vorhandenen Threads zu dem Thema haben mir leider nicht so wirklich weitergeholfen.

Nun hoffe ich, dass ihr das könnt.


Folgendes Szenario:

Ich habe folgende Klasse (allgemeingehaltene Namen zur besseren Übersicht):

Delphi-Quellcode:
TFoo = class(TCustomControl)
private
  FSomeVar: TSomeType;
protected
  procedure WM_Paint(var Msg: TMessage) message WM_PAINT;
public
  property OnGetSubComponents;
end;

Delphi-Quellcode:
TFooBar = class(TCustomControl)
private
  FSomeVar: TFoo;
protected
  procedure WM_Paint(var Msg: TMessage) message WM_PAINT;
end;

Delphi-Quellcode:
TBar = class(TCustomControl)
private
  FSomeVar: TFooBar;
protected
  procedure WM_Paint(var Msg: TMessage) message WM_PAINT;
public
  property OnGetSomeData;
end;
Jetzt habe ich das Problem, dass ich auf den Klick auf die TFoo Komponente reagieren können muss. Die einzige Möglichkeit die ich jetzt kennen würde wäre, das Event durchzuschleifen. Also in jeder Klasse ein ObGetSubComponents Event erstellen und dann den Weg TFoo (Auslöser) --> TFooBar --> TBar durchlaufen.

Irgendwie kommt mir das aber falsch vor.

Die andere Möglichkeit wäre, dass ich (hier geht es um eine Mausklickfunktion) die Mausposition bspw. auswerte und dann errechne wo ich bin. Aber die Subkomponente selbst bietet das ja schon durch die WM_LBUTTONDOWN Message an, sodass ich da eben gar nix mehr machen müsste.

Habe ich jetzt einen grundlegenden Denkfehler wie meine Klassen aufgebaut sind, oder gibt es genau hierfür schon bestimmte Lösungsansätze? Wie macht ihr das wenn ihr unterschiedliche Komponenten ineinander verschachteln müsst?

Bin über jeden Lösungsvorschlag dankbar. Falls noch Informationen fehlen sollten, dann kann ich die gerne zur Verfügung stellen.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Komponentenentwicklung - Event weiterleiten - Denkfehler?

  Alt 27. Sep 2016, 14:59
Kannst Du die Fragestellung nochmal anders formulieren?

Du hast 3 verschachtelte Controls und möchtest wie reagieren, wenn das innerste geklickt wird?

Warum reagierst Du nicht auf OnClick oder OnMouseDown?
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Komponentenentwicklung - Event weiterleiten - Denkfehler?

  Alt 27. Sep 2016, 15:02
Warum reagierst Du nicht auf OnClick oder OnMouseDown?
Du hast das Problem denke ich schon richtig verstanden. Ich habe eben diverse Events die beim Klick auf die innerste Komponente ausgelöst werden sollen. Meine GUI Klasse kann aber nur die Events der äußersten Komponente abonnieren. Nicht aber die der innersten. Und jetzt wäre die Frage, wie ich auf bspw. die OnClick oder auch meine speziellen Events der innersten Komponente reagieren kann.
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

AW: Komponentenentwicklung - Event weiterleiten - Denkfehler?

  Alt 27. Sep 2016, 15:09
Ja gut, dann musst du wirklich in der innersten Komponente im Event ein Event feuern und das nach oben leiten bis zu TBar und dann zum User.
Finde ich aber besser als irgendwo irgendwelche Koordinaten abzufragen oder sowas..
Delphi-Quellcode:
TFoo = class(TCustomControl)
private
  FSomeVar: TSomeType;
protected
  procedure WM_Paint(var Msg: TMessage) message WM_PAINT;
public
  property OnGetSubComponents;
  property OnButtonClick: TNotifyEvent read FOnButtonClick write FOnButtonClick;
end;

procedure TFoo.Button1Click(Sender: TObject);
begin
  if Assigned(FOnButtonClick) then
    FOnButtonClick(Sender);
end;

// TFooBar

TFooBar = class(TCustomControl)
private
  FSomeVar: TFoo;
protected
  procedure WM_Paint(var Msg: TMessage) message WM_PAINT;
  property OnButtonClick: TNotifyEvent read FOnButtonClick write FOnButtonClick;
end;

constructor TFooBar.Create()
begin
  FSomeVar.OnButtonClick := InternalButtonClick;
end;

procedure TFooBar.InternalButtonClick()
begin
  if Assigned(FOnButtonClick) then
    FOnButtonClick(Sender);
end;

// TBar

TBar = class(TCustomControl)
private
  FSomeVar: TFooBar;
protected
  procedure WM_Paint(var Msg: TMessage) message WM_PAINT;
public
  property OnGetSomeData;
end;

constructor TBar.Create()
begin
  FSomeVar.OnButtonClick := InternalButtonClick;
end;

procedure TBar.InternalButtonClick()
begin
  if Assigned(FOnButtonClick) then
    FOnButtonClick(Sender);
end;
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Komponentenentwicklung - Event weiterleiten - Denkfehler?

  Alt 27. Sep 2016, 15:12
Ja gut, dann musst du wirklich in der innersten Komponente im Event ein Event feuern und das nach oben leiten bis zu TBar und dann zum User.
Wow. Ich hätte wirklich gedacht, dass das einfacher gehen müsste und ich etwas falsch mache. Dann muss ich mir jetzt was überlegen ...
Finde ich aber besser als irgendwo irgendwelche Koordinaten abzufragen oder sowas..
Ja. Einfacher ist es bestimmt.
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#6

AW: Komponentenentwicklung - Event weiterleiten - Denkfehler?

  Alt 27. Sep 2016, 15:17
Mir fällt zumindest nichts einfacheres ein
Will nicht ausschließen, dass es dafür eine einfachere/elegantere Lösung gibt.
Falls ja, wäre ich auch daran interessiert zu wissen wie
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Komponentenentwicklung - Event weiterleiten - Denkfehler?

  Alt 27. Sep 2016, 15:19
[Trotz rotem Kasten aus Zeitgründen mal rausgehauen...]

Da musst man noch unterscheiden.


1) Soll es eine fixe Behandlung geben?

Dann kannst Du eine Methode
procedure MyInnerControlClick(Sender: TObject);
dem
InnerControl.OnClick
einfach zuweisen.

Dein InnerControl muss dann den Context kennen, in dem es existiert und Zugriff auf die benötigten Daten haben.


2) Soll eine freie Behandlung definierbar sein?

Dann musst Du Dir anschauen, wie OnClick implementiert ist und das mit OnInnerClick nachbauen.
Dann kannst Du in Deinem Projektcode die Behandlung individuell regeln.
Das ist natürlich komplexer.
(Das ich so etwas gemacht habe ist Jahre her. Ich könnte bei Bedarf mal suchen, ob ich dazu noch etwas finde.)
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: Komponentenentwicklung - Event weiterleiten - Denkfehler?

  Alt 27. Sep 2016, 15:58
Danke für die Antworten. Ich konkretisiere das Ganze aber mal noch ein bisschen.

Ausgehend von der Idee der TVirtualBreadCrumb Komponente von Codehunter habe ich meine eigene BreadCrumbBar schreiben wollen. Hintergrund ist der, dass ich nicht nur auf den VST reagieren, sondern bei Bedarf auch eine eigene Struktur aufbauen können will. Eine Frage habe ich diesbezüglich auch bereits in seinem Thread geschrieben.

Konkret geht es jetzt darum, dass ich eine folgende Klassenstruktur habe:

Delphi-Quellcode:
TBreadCrumbButtonBase = class(TCustomControl)
[...] // BasisButton von dem alle anderen Buttons abgeleitet werden
end;
Delphi-Quellcode:
TBreadCrumbRootButton = class(TBreadCrumbButtonBase)
[...] // Button der angezeigt wird, wenn nicht alle Breadcrumbs in die Bar passen
end;
Delphi-Quellcode:
TBreadCrumbButton = class(TBreadCrumbButtonBase)
[...] // Das ist der DropDown Button der hinter dem BreadCrumb hängt
end;
Delphi-Quellcode:
TBreadCrumb = class(TCustomControl)
private
  FButton: TBreadCrumbButton; // Hier der verschachtelte BreadCrumbButon auf dessen Klick ich reagieren will um ein Menü anzuzeigen
end;
An dieser Stelle kommt jetzt noch meine Basis BreadCrumbBar von der alle anderen Bars die speziell reagieren sollen abgeleitet werden können.
Delphi-Quellcode:
TCustomBreadCrumbBar = class (TCustomControl)
private
  FRootButton: TBreadCrumbRootButton;
  FBreadCrumbs: TBreadCrumbs;
[...]
end;
Hier die konkrete Implementierung der BreadCrumbBar die es zulässt, dass ich eigene Buttons hinzufügen kann wie ich das möchte.
Delphi-Quellcode:
TBreadCrumbBar = class(TCustomBreadCrumbBar)
[...]
end;
Später soll es dann noch eine andere Ableitung geben, die die Buttons dann selbst erstellt (abhängig von einem VirtualTreeView). Diese Ableitung wird dann noch erweitert, dass ich zusätzlich zu den VirtualTreeView Buttons auch eigene vorne dran stellen kann.

Da wie beim Windows Explorer beim Klick auf den TBreadCrumbButton ein Menü erscheinen soll welches diverse Auswahlmöglichkeiten bietet, muss ich ja das ClickEvent des TBreadCrumbButtons durchschleifen damit dies auf meiner GUI Form ankommt.

Und hier setzt meine Frage an. Wie kann ich das Vorhaben vereinfachen?

Diese vielen Klassen habe ich eben gemacht, damit ich nur noch eine TBreadCrumb Instanz erzeugen muss und dadurch dann entsprechend auch der DropDownButton erzeugt wird und sich auch alles selbst zeichnet. Deshalb auch TCustomControl. Wenn ich alles in der TCustomBreadCrumbBar zeichnen würde, dann müsste ich die Mausposition auswerten und errechnen, an welcher Stelle ich geklickt habe um entsprechend reagieren zu können. Durch die vielen Komponenten habe ich eben schon diverse Features die ich nicht mehr selbst implementieren muss.

Ich hoffe ich habe es jetzt ausführlicher und damit etwas verständlicher beschrieben.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Komponentenentwicklung - Event weiterleiten - Denkfehler?

  Alt 27. Sep 2016, 18:11
So ganz kann ich nicht folgen, aber mal ein Versuch (etwas PseudoCode):


Delphi-Quellcode:
TBreadCrumb = class(TCustomControl)
private
   FButton: TBreadCrumbButton; // Hier der verschachtelte BreadCrumbButon auf dessen Klick ich reagieren will um ein Menü anzuzeigen
   procedure BreadCrumbButtonClick(Sender...);
end;

constructor TBreadCrumb.Create(...)
begin
  inherited;
  FButton := TBreadCrumbButton.Create(Self);
  fButton.Parent := Self;
  fButton.OnClick := BreadCrumbButtonClick;
end;

procedure TBreadCrumb.BreadCrumbButtonClick(...)
var
  P: TPoint;
begin
  P := TPoint.Create(IrgendEinX, IrgendEinY);
  P := ClientToSreen(P);
  PopupMenueÖffnenMitBestimmtenEintraegenAnPos(P);
end;

Ich weiß nicht, ob Dich das weiter bringt.
Zumindest kann der Button selbst auf den Klick reagieren.
Was er dann machen soll, wird sicher schon schwieriger.
Dazu muss er halt wissen, für welche Aufgabe er in welchem aktuellen Kontext steht.


Frag doch sonst mal CodeHunter, ob er Dir weiter helfen kann, er hat ja da offenbar schon etwas vorgelegt...
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#10

AW: Komponentenentwicklung - Event weiterleiten - Denkfehler?

  Alt 27. Sep 2016, 19:57
Wenn du die gekapselte Komponente als SubKomponente anlegst, bekommst du die Eigenschaften und Events im Objektinspektor angezeigt. Hier als Beispiel ein Panel mit einem Button drauf.

Delphi-Quellcode:
unit PanelExt;

interface

uses
  System.SysUtils, System.Classes, Vcl.Controls, Vcl.ExtCtrls, Vcl.StdCtrls;

type
  TPanelExt = class(TPanel)
  private
    FButton: TButton;
  protected
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Button: TButton read FButton;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TPanelExt]);
end;

constructor TPanelExt.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FButton := TButton.Create(Self);
  FButton.SetSubComponent(true);
  FButton.Parent := Self;
  FButton.Name := 'TestButton';
end;

destructor TPanelExt.Destroy;
begin
  FButton.Free;
  inherited Destroy;
end;

end.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
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 05:11 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