![]() |
Delphi-Version: 10.2 Tokyo
Dynamischer Verweis auf Komponente
Moin zusammen,
dies ist ggf. eine blöde Frage aber ich komme da einfach nicht weiter: Wie kann ich Dynamisch auf eine Komponente zugreifen? Beispiel: Ich habe Buttons, deren Namen auf einer Logik basieren (einfachstes Beispiel hierfür wäre: "Name1", "Name2",...) bzw. auch deren Funktion. Nun möchte ich nicht für jeden Button einzeln eine Funktion schreiben, sondern würde dies gerne ableiten. Beispiel2: Button1: ShellExecute(Handle, 'open', PChar(Tool1E.text), PChar(Tool1P.Text), nil, SW_SHOW); Button2: ShellExecute(Handle, 'open', PChar(Tool2E.text), PChar(Tool2P.Text), nil, SW_SHOW); besser wäre die "1" (bzw. die "2") aus dem Button-Namen zu ziehen (kein Problem) und dadurch den dyn. Verweis (PChar(Tool1E.text)) zu generieren (keine Ahnung wie). Kann mir hierbei jemand weiter helfen, ich finde nur dynamische Erzeugung von Buttons etc. aber kein dynamischer Verweis. |
AW: Dynamischer Verweis auf Komponente
Dein Programm oder ein fremdes Programm?
Wenn Fall eins: "findcomponent delphi" sollte in der Suchmaschine deiner Wahl weiterhelfen. |
AW: Dynamischer Verweis auf Komponente
Und ein Frame würde da nicht gehen?
Dort hättest du einen Button und zwei TextBoxen und der code im ButtonClick sähe dann so aus
Delphi-Quellcode:
In der Form erzeugst du nun einfach x-mal den Frame und bist fertig.
ShellExecute(Handle, 'open', PChar(Tool1E.text), PChar(Tool1P.Text), nil, SW_SHOW);
|
AW: Dynamischer Verweis auf Komponente
Vielleicht suchst du ja die Methode
![]()
Delphi-Quellcode:
procedure TForm325.Button1Click(Sender: TObject);
var btn: TButton; edtE: TEdit; edtP: TEdit; idx: Integer; begin btn := Sender as TButton; idx := ExtractButtonNumber(btn.Name); edtE := FindComponent(Format('Tool%dE', [idx])) as TEdit; edtP := FindComponent(Format('Tool%dP', [idx])) as TEdit; ShellExecute(Handle, 'open', PChar(edtE.text), PChar(edtP.Text), nil, SW_SHOW); end; |
AW: Dynamischer Verweis auf Komponente
@TiGü: Es sind Komponenten innerhalb meines Programms, jedoch in einer TPageControl. Wenn ich nun also deinem Tipp nachgehe bekomme ich folgendes als "Lösungsansatz":
TEdit(FindComponent('Tool' + copy(Name, 5, 1) + 'E')).Text Leider ist, wenn ich mir das mal als Showmessage zur Kontrolle ausgeben lasse, immer leer. Der Name wird jedoch korrekt zusammengesetzt.
Delphi-Quellcode:
@Schokohase: Ich verstehe aktuell nicht wie du es meinst, da dein Beispiel wie eine 1:1 Kopie meines geposteten Textes aussieht. Es sind insgesamt 15 Buttons, die wiederum auf jeweils 2*15 Edit-Felder zugreifen für das Shellexecute.
procedure TTools.Tool1BClick(Sender: TObject);
begin with sender as TButton do begin showmessage(TEdit(FindComponent('Tool' + copy(Name, 5, 1) + 'E')).Text); //nur zum Testen das Showmessage, hier kommt später die Shellexecute rein end; // ShellExecute(Handle, 'open', PChar(Tool1E.text), PChar(Tool1P.Text), nil, SW_SHOW); end; @Uwe Raabe: Die Funktion habe ich auf TiGü's Hinweis hin gefunden, scheint aber irgendwie nicht 100%ig zu funktionieren (s.o.). Und die Funktion "ExtractButtonNumber" ist mir und Delphi nicht bekannt. |
AW: Dynamischer Verweis auf Komponente
Zitat:
Zitat:
Wenn FindComponent nicht funktioniert, wäre das jetzt der richtige Zeitpunkt für ein kleines Testprojekt, bei dem das nicht funktioniert. |
AW: Dynamischer Verweis auf Komponente
Nun ja, einfach so:
Delphi-Quellcode:
und in der Form dann
unit uStartFrame;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TFrame1 = class(TFrame) Edit1: TEdit; Edit2: TEdit; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; implementation uses Winapi.ShellAPI; {$R *.dfm} procedure TFrame1.Button1Click(Sender: TObject); begin ShellExecute( Handle, 'open', PChar(Edit1.Text), PChar(Edit2.Text), nil, SW_SHOW ); end; end.
Delphi-Quellcode:
unit uMainForm;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, uStartFrame; type TForm1 = class( TForm ) Frame11: TFrame1; Frame12: TFrame1; Frame13: TFrame1; Frame14: TFrame1; Frame15: TFrame1; private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} end. |
AW: Dynamischer Verweis auf Komponente
@Uwe Raabe:
Achso XD Das mit der Button Nummer bekomme ich so hin:
Delphi-Quellcode:
Die Showmessage werden dann natürlich durch shellexecute abgelöst, wenn hier der richtige Wert raus kommt.
procedure TTools.Tool1BClick(Sender: TObject);
begin with sender as TButton do begin try StrToInt(copy(Name, 6, 1)); showmessage('Tool' + copy(Name, 5, 2) + 'E'); //zur Prüfung des korrekt generierten Namens - passt showmessage(TEdit(FindComponent('Tool' + copy(Name, 5, 2) + 'E')).Text); //zur Prüfung des korrekten übergebenen Inhalts - leer!? except showmessage('Tool' + copy(Name, 5, 1) + 'E'); //zur Prüfung des korrekt generierten Namens - passt showmessage(TEdit(FindComponent('Tool' + copy(Name, 5, 1) + 'E')).Text); //zur Prüfung des korrekten übergebenen Inhalts - leer!? end; end; // ShellExecute(Handle, 'open', PChar(Tool1E.text), PChar(Tool1P.Text), nil, SW_SHOW); end; Das mit dem "nicht funktionierendem Beispiel" muss ich schauen, da mein Programm mittlerweile 4170 Zeilen hat, wo auch Daten drin sind, die nicht für die Öffentlichkeit bestimmt sind müsste ich dafür ein Beispiel bauen. Ich habe dies aber auch mal mit einem Edit-Feld getestet, welches nicht in einer TPageControl eingebettet ist und auch dort funktioniert es leider nicht. Er scheint die Komponente nicht zu finden. @Schokohase: Die Editfelder befinden sich nicht im gleichen Menüpunkt meiner TPageControl wie die Buttons und zudem würde ich auch dort wieder mehrere Funktionen schreiben anstatt einer (dynamischen) Funktion. |
AW: Dynamischer Verweis auf Komponente
Wenn TTools kein Formular ist, sondern irgendein Client-Control davon, wäre vielleicht FindControl statt FindComponent der bessere Ansatz. FindComponent sucht nach Komponenten, deren Owner die aufrufende Klasse ist, FindControl nach Controls, deren Parent sie ist. Bei zur Designtime hinzugefügten Komponenten ist der Owner normalerweise das Formular, vermutlich geht es deshalb nicht.
|
AW: Dynamischer Verweis auf Komponente
Also würdest du so etwas brauchen
Delphi-Quellcode:
Und für den Button
unit uStartFrame;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TFrame1 = class(TFrame) Edit1: TEdit; Edit2: TEdit; private { Private-Deklarationen } public procedure Execute(); end; implementation uses Winapi.ShellAPI; {$R *.dfm} procedure TFrame1.Execute; begin ShellExecute( Handle, 'open', PChar(Edit1.Text), PChar(Edit2.Text), nil, SW_SHOW ); end; end.
Delphi-Quellcode:
procedure TFormX.Button1_Click(Sender:TObject);
begin Frame1.Execute; end; |
AW: Dynamischer Verweis auf Komponente
@Schokohase: Nicht wirklich. Sorry aber ich glaube du hast das nicht so ganz verstanden.
Aufbau: Edits: Pagecontrol1 (Menu) -> PageX (Einstellungen) -> Pagecontrol2 (EinstellungenPC) -> PageY (ToolsE) -> EditE1-15 (Programmpfade) & EditP1-15 (Parameter) Tool1E.text...Tool15E.text Tool1P.text...Tool15P.text Buttons: Pagecontrol1 (Menu) -> PageZ (Programme) - >GroupBox (Toolbar) -> Button1-15 (Aufruf) Tool1B...Tool15B Und an dem Aufbau wird sich nichts ändern. @DeddyH: Doch TTools ist die Form (Formname: Tools). Probiert habe ich es auch schon mit: showmessage(TEdit(FindComponent('Application.TTool s.Tool' + copy(Name, 5, 1) + 'E')).Text); showmessage(TEdit(FindComponent('Application.Tools .Tool' + copy(Name, 5, 1) + 'E')).Text); showmessage(TEdit(FindComponent('TTools.Tool' + copy(Name, 5, 1) + 'E')).Text); showmessage(TEdit(FindComponent('Tools.Tool' + copy(Name, 5, 1) + 'E')).Text); leider kein Erfolg, er scheint das EditFeld absolut nicht zu finden. Da muss irgendwo ein Denkfehler sein. |
AW: Dynamischer Verweis auf Komponente
Nun sagen wir mal so, du hast es gar nicht erklärt. Und Nichts kann man eben nicht nicht verstehen.
Aber aus deinen Erklärungen sehe ich das es auf der PageY (ToolsE) 15 Paare von Edit-Feldern gibt (eines für den Programmpfad, das andere für die Parameter). Diese beiden könnte man in einem Frame zusammenfassen und dem Frame eine Execute-Methode verpassen (so wie von mir gezeigt). Aber ist schon recht ... bei dem Aufbau würde ich da auch ganz anders drangehen (kein Zugriff vom Button auf die ToolXE/ToolXP-Cotrols) |
AW: Dynamischer Verweis auf Komponente
Zitat:
|
AW: Dynamischer Verweis auf Komponente
Liste der Anhänge anzeigen (Anzahl: 1)
Das sollte kein Problem darstellen^^ s.u.
|
AW: Dynamischer Verweis auf Komponente
Hab aber in einem anderen Beitrag (über Google über Umwege) eine Lösung gefunden:
TEdit(Tools.FindComponent('Tool' + copy(Name, 5, 1) + 'E')).Text -.- |
AW: Dynamischer Verweis auf Komponente
Zitat:
Es gibt keine Exception, aber einen falschen Zugriff auf Tool1E! |
AW: Dynamischer Verweis auf Komponente
Zitat:
|
AW: Dynamischer Verweis auf Komponente
@Schokohase: Doch:
Delphi-Quellcode:
try
StrToInt(copy(Name, 6, 1)); //1-Stellig (0-9) except //2-Stellig (10-99) end; |
AW: Dynamischer Verweis auf Komponente
Wieso sollte der Code eine Exception werfen, wenn im 6. Zeichen eine Ziffer steht?
|
AW: Dynamischer Verweis auf Komponente
Zitat:
Es ist keine globale Funktion, sondern die Methode von TComponent-Nachfahren. In deinem Fall also
Delphi-Quellcode:
, welches somit aus deiner TForm kommt (über die Klasse, in welcher die aufrufende Methode liegt)
Self.FindComponent
Und das Ding sucht nur nach Sub-Komponenten in der angegebenen Komponente, also nach allem, von dem deine Form der Owner ist. Komponenten-Pfade werden dabei nie aufgelöst ... nur das was "direkt" ein Child ist. Das Selbe gilt für FindControl, was entsprechend die Parent-Beziehungen behandelt. In der globalen Variabe Screen findet man alle Forms, welche man durchgehen und da drauf suchen könnte. |
AW: Dynamischer Verweis auf Komponente
Zitat:
|
AW: Dynamischer Verweis auf Komponente
Zitat:
|
AW: Dynamischer Verweis auf Komponente
Ja genau. Aber es ist doch einfach zu verstehen. Die Namen bauen sich (logischerweise) so auf:
ButtonXABC ... ButtonXXABC Nun schaue ich (nach obigem Beispiel) ob an 8. Stelle eine Zahl ist. Wenn ja, dann ist an der 7. Stelle auch eine Zahl und somit sind wir im Bereich 10-99. Andernfalls sind wir im Bereich 0-9. Oder Andres gesagt: Versucht er bei "ButtonXABC" sonst das "A" in eine Zahl zu wandeln, was nicht geht -> exception -> anderes Handling.
Delphi-Quellcode:
Alternativ hätte man auch generell 2-Stellig arbeiten können:
try
StrToInt(copy(Name, 8, 1)); //1-Stellig (0-9) except //2-Stellig (10-99) end; Button0XABC ... ButtonXXABC Dann bräuchte man nur prüfen ob an 7. Stelle eine "0" vorhanden ist und dementsprechend ableiten, also:
Delphi-Quellcode:
if Name[7] = '0' then
//1-Stellig (0-9) else //2-Stellig (10-99) |
AW: Dynamischer Verweis auf Komponente
Also ehrlich gesagt finde ich das alles sehr aufwändig. ich würde - wenn es wirklich nur um Nummern geht - einfach das .Tag verwenden:
beim erstellen des Buttons das Tag mit der entsprechenden Nummer versehen, alle Buttons auf das gleiche onClick und dann 'tool'+inttostr((sender as Tbutton).tag)+'......' |
AW: Dynamischer Verweis auf Komponente
@noisy_master: Es gibt viele Wege nach Rom ;)
Aber ich denke (nur persönliche Meinung), das in der Summe es wesentlich länger dauert, bei jedem Button manuell den "Tag" anzupassen als einmal dies (über den sowieso schon manuell gesetzten Namen) per Exception abzufangen. Auch die Fehlerquelle ist höher, denn: Buttons mit gleichem "Tag" sind möglich ("Tag"-Änderung beim manuellen Erstellen des Buttons vergessen), mit gleichen Namen jedoch nicht (-> Fehlermeldung)! Anders wäre dies evtl. bei generierten Buttons im Programm, da hier das Setzen des "Tag" mal "nebenbei" mit gemacht werden kann und dies mit einer dafür angelegten Variable durchgezählt werden kann. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:23 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