Autor Beitrag
hui1991
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 433

Windows XP, WIndows Vista
Turbo Delphi Explorer| Delphi, PHP,Blitzbasic
BeitragVerfasst: Sa 16.06.07 19:10 
Hi,

ich möchte mich so langsam an Makro-Programmierung rantasten. Dazu möchte ich noch lernen, ob man an dem Code der unten kommt was vereinfachen kann.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const
  Name1: String = 'List1';


var
  Form1: TForm1;
  Names,Typ: Array[0..4] of String;
  Component: Array[0..4] of TControl;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  x: Integer;
begin
  Names[0]:='Button1';
  Names[1]:='Label1';
  Names[2]:='Edit1';
  Names[3]:='Button2';
  Names[4]:='ListBox1';
  Typ[0]:='TButton';
  Typ[1]:='TLabel';
  Typ[2]:='TEdit';
  Typ[3]:='TButton';
  Typ[4]:='TListBox';
  For x:=0 to 4 do begin
    if Typ[x]='TButton' then begin
      Component[x]:=TButton.Create(Form1);
      Component[x].Name:=Names[x];
      TButton(FindComponent(Names[x])).Tag:=x;
      TButton(FindComponent(Names[x])).Parent:=Form1;
      TButton(FindComponent(Names[x])).Left:=x*0;
      TButton(FindComponent(Names[x])).Top:=x*22;
    end;
    if Typ[x]='TLabel' then begin
      Component[x]:=TLabel.Create(Form1);
      Component[x].Name:=Names[x];
      TLabel(FindComponent(Names[x])).Tag:=x;
      TLabel(FindComponent(Names[x])).Parent:=Form1;
      TLabel(FindComponent(Names[x])).Left:=x*0;
      TLabel(FindComponent(Names[x])).Top:=x*22;
    end;
    if Typ[x]='TEdit' then begin
      Component[x]:=TEdit.Create(Form1);
      Component[x].Name:=Names[x];
      TEdit(FindComponent(Names[x])).Tag:=x;
      TEdit(FindComponent(Names[x])).Parent:=Form1;
      TEdit(FindComponent(Names[x])).Left:=x*0;
      TEdit(FindComponent(Names[x])).Top:=x*22;
    end;
    if Typ[x]='TListBox' then begin
      Component[x]:=TListBox.Create(Form1);
      Component[x].Name:=Names[x];
      TListBox(FindComponent(Names[x])).Tag:=x;
      TListBox(FindComponent(Names[x])).Parent:=Form1;
      TListBox(FindComponent(Names[x])).Left:=x*0;
      TListBox(FindComponent(Names[x])).Top:=x*22;
    end;
  end;
end;

end.


Irgendwie das TListBox und TButton usw. zu einem zusammenfassen, damit die Ifs alle überflüssig sind. Gibt es da eine Möglichkeit?

MfG
hui1991
Diskette
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21

Win XP
Delphi 5 Pers., Borland Developer 2006 Prof.
BeitragVerfasst: Sa 16.06.07 20:26 
Hi,
wenn du die String-Variablen als Integer-Variablen nimmst, funktioniert das ganz simple mit case...
Guck doch einfach mal in der Delphi-Hilfe nach 'case'...
Wenn du mein Vorgehen trotzdem nicht verstehst, melde dich nochmal bei mir.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const
  Name1: String = 'List1';


var
  Form1: TForm1;
  Names,Typ: Array[0..4] of Integer;
  Component: Array[0..4] of TControl;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  x: Integer;
begin
  Names[0]:=1; // Button1
  Names[1]:=2; // Label1
  Names[2]:=3; // Edit1
  Names[3]:=4; // Button2
  Names[4]:=5; // ListBox1
  Typ[0]:=1; // TButton
  Typ[1]:=2; // TLabel
  Typ[2]:=3; // TEdit
  Typ[3]:=4; // TButton
  Typ[4]:=5; // TListBox
  For x:=0 to 4 do begin
    case Typ[x] of
      1:  begin // if Typ[x] = 'TButton'
           Component[x]:=TButton.Create(Form1);
           Component[x].Name:=Names[x];
           TButton(FindComponent(Names[x])).Tag:=x;
           TButton(FindComponent(Names[x])).Parent:=Form1;
           TButton(FindComponent(Names[x])).Left:=x*0;
           TButton(FindComponent(Names[x])).Top:=x*22;
  end;
      2:  begin // if Typ[x] = 'TLabel'
           Component[x]:=TLabel.Create(Form1);
           Component[x].Name:=Names[x];
           TLabel(FindComponent(Names[x])).Tag:=x;
           TLabel(FindComponent(Names[x])).Parent:=Form1;
           TLabel(FindComponent(Names[x])).Left:=x*0;
           TLabel(FindComponent(Names[x])).Top:=x*22;
  end;
      3:  begin // if Typ[x] = 'TEdit'
           Component[x]:=TLabel.Create(Form1);
           Component[x].Name:=Names[x];
           TEdit(FindComponent(Names[x])).Tag:=x;
           TEdit(FindComponent(Names[x])).Parent:=Form1;
           TEdit(FindComponent(Names[x])).Left:=x*0;
           TEdit(FindComponent(Names[x])).Top:=x*22;
  end;
      4:  begin // if Typ[x] = 'TListBox'
           Component[x]:=TLabel.Create(Form1);
           Component[x].Name:=Names[x];
           TListBox(FindComponent(Names[x])).Tag:=x;
           TListBox(FindComponent(Names[x])).Parent:=Form1;
           TListBox(FindComponent(Names[x])).Left:=x*0;
           TListBox(FindComponent(Names[x])).Top:=x*22;
  end;
    end;
  end;
end;
end.


LG,
Diskette
hui1991 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 433

Windows XP, WIndows Vista
Turbo Delphi Explorer| Delphi, PHP,Blitzbasic
BeitragVerfasst: Sa 16.06.07 20:42 
Das meine ich nicht.
Ich wollte das If nicht ersetzen sondern die anzahl.
Bzw. die anzahl der zahlen der Case.
Der Code ist außerdem falsch.
Ich möchte eigentlich das nach dem Namen des Typ die Componente rausgesucht werden.
Sind ja alle vom TControl abgeleitet.
Aber beim TControl gibt es bestimmt keine Lines oder Items.
weil ich will am ende nicht, wenn überhaupt so viele verwender werden 50 Komponente in die Liste einfügen.
Deswegen habe ich hier gefragt ob man es zusammenfassen kann.
z.B. aus
ausblenden Delphi-Quelltext
1:
TButton(FindComponent(Names[x])).Tag:=x;					


zu dem hier werden kann (was ja leider nicht stimmt):

ausblenden Delphi-Quelltext
1:
GetComponent(Typ[x],FindComponent(Names[x])).Tag:=x					


Selbst wenn es geht sowas als function zu programmieren, wüsste ich net wie.
Hoffentlich geht es irgendwie.

MfG
hui1991
Diskette
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21

Win XP
Delphi 5 Pers., Borland Developer 2006 Prof.
BeitragVerfasst: Sa 16.06.07 21:04 
aso sry.
ne ich glaub das geht nicht...
Sei denn man kann Code in einer Variable speichern und diesen dann ausführen..
Wüsste aber leider nicht dass das geht
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 16.06.07 23:38 
Wenn Du die dann auch noch ein Array der Control-Klassen definierst, geht es sogar NOCH kürzer:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const
  Name1: String = 'List1';

type TControlClass = class of TControl;
const
  CtrlClasses : array[0..4] of TControlClass = (TButton, TLabel, TEdit, TButton, TListbox);

var
  Form1: TForm1;
  Names,Typ: Array[low(CtrlClasses)..High(CtrlClasses)] of String;
  Component: Array[low(CtrlClasses)..High(CtrlClasses)] of TControl;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  x: Integer;
begin
  For x:=low(CtrlClasses) to High(CtrlClasses) do begin
    Component[x]:=CtrlClasses[X].Create(Form1);
    Typ[x]:=CtrlClasses[X].ClassName;
    Names[x]:=Copy(Typ[X], 2, MaxInt) + '1';
    Component[x].Name:=Names[x];
    Component[x].Tag:=x;
    Component[x].Parent:=Form1;
    Component[x].Left:=x*0;
    Component[x].Top:=x*22;
  end;
end;

end.


Es lebe die RTTI :P

Was übrigens auch die Antwort auf deine Frage ist: Dazu musst Du über die Unit TypInfo die TypeInfo der Objekt-Instanzen auslesen und verarbeiten ... GetPropValue und SetPropValue sind da nur 2 Funktionen von vielen ...

//Edit: 10 überflüssige Zeilen entfernt ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
hui1991 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 433

Windows XP, WIndows Vista
Turbo Delphi Explorer| Delphi, PHP,Blitzbasic
BeitragVerfasst: So 17.06.07 13:14 
Hi,

die lösung ist recht kompliziert.
Hm.. Vorallem wenn der Name schon existiert wie bei deinem Beispiel.
Ich könnte auch per eine For schleife die ganzen Namen durchsuchen und das richtige ausgeben lassen.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure ButtonClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const
  Name1: String = 'List1';

type TControlClass = class of TControl;
const
  CtrlClasses : array[0..4] of TControlClass = (TButton, TLabel, TEdit, TButton, TListbox);

var
  Form1: TForm1;
  Names,Typ: Array[low(CtrlClasses)..High(CtrlClasses)] of String;
  Component: Array[low(CtrlClasses)..High(CtrlClasses)] of TControl;

implementation

{$R *.dfm}

function GetComponent(name: String; Namen: Array of TControl):TControl;
var
  n: Integer;
begin
  result:=nil;
  try
    For n:=0 to length(namen)-1 do begin
      if Namen[n]<>nil then
        if name=Namen[n].Name then
          result:=Namen[n];
    end;
  except

  end;
end;

procedure TForm1.ButtonClick(Sender: TObject);
begin
  if TButton(self).Tag=1 then
    GetComponent('Button2',Component).Left:=200;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  x,n: Integer;
begin
  For x:=low(CtrlClasses) to High(CtrlClasses) do begin
    Component[x]:=CtrlClasses[X].Create(Form1);
    Typ[x]:=CtrlClasses[X].ClassName;
    For n:=1 to length(CtrlClasses) do
      if GetComponent(Copy(Typ[X], 2, MaxInt)+inttostr(n),Component)=nil then
        break;
    Names[x]:=Copy(Typ[X], 2, MaxInt) + inttostr(n);
    Component[x].Name:=Names[x];
    Component[x].Tag:=x;
    Component[x].Parent:=Form1;
    Component[x].Left:=x*0;
    Component[x].Top:=x*22;
    GetComponent(Component[x].Name,Component).OnClick:=ButtonClick; //Geht nicht, wie soll man das lösen?
    //oder
    Component[x].OnClick:=ButtonClick; //Das geht auch nicht.
  end;
end;

end.

Ich habe es mit einer Suche erweitert wo das Problem mit dem gleichen Namen auch noch einfach gelöst werden kann.
Naja bei großen Mengen kann ja sowieso Probleme auftretten, z. B. dauert zu lange.

Nächstes Problem, ganz unten vom Code sind Kommentare, davor ist der Code der nicht geht, da delphi nur weiß das es ein TControl ist und einem ein TButton wird er bestimmt nicht wissen.
Ich habe da nicht so auf die schnelle eine Idee.

MfG
hui1991

//Ich wollte die Nachricht schon längst abschicken, aber heute wurde von 1&1 (wegen wechseln auf T-Com) das inet gekappt und ISDN hat vorhin den Geist aufgegeben, jetzt geht er ja wieder ^^
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 17.06.07 13:45 
Das Setzen der Eventhandler kannst Du über die RTTI-Funktionen in der Unit TypInfo realisieren.

Für dich interessant sein könnten folgende Routinen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
function GetMethodProp(Instance: TObject; const PropName: string): TMethod; overload;
procedure SetMethodProp(Instance: TObject; const PropName: string;
  const Value: TMethod); overload;

function GetMethodProp(Instance: TObject; PropInfo: PPropInfo): TMethod; overload;
procedure SetMethodProp(Instance: TObject; PropInfo: PPropInfo;
  const Value: TMethod); overload;

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
hui1991 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 433

Windows XP, WIndows Vista
Turbo Delphi Explorer| Delphi, PHP,Blitzbasic
BeitragVerfasst: So 17.06.07 14:46 
Keine Informationen über das gefunden.
Über RTTI habe ich was gefunden, aber nix über die zwei Funktionen.
Im Forum gabs auch kein Ergebniss :(
Woher soll ich den wissen wie ich das verwenden muss, wenn nirgends infos sind.
In Delphi-Hilfe ist nix, im Forum nix und über google nur auf russisch.
Bin bestimmt wieder zu blöd bessere begriffe als "delphi RTTI SetMethodProp" zu finden :cry:

MfG
hui1991
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 17.06.07 14:53 
Wie wär's intuitiv???

ausblenden Delphi-Quelltext
1:
SetMethodProp(Form1, 'OnClick', TMethod(DeinClickHandler));					


ggf. ein paar @'s an den richtigen Stellen ergänzen ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
hui1991 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 433

Windows XP, WIndows Vista
Turbo Delphi Explorer| Delphi, PHP,Blitzbasic
BeitragVerfasst: So 17.06.07 15:40 
Funktioniert nicht, auch mit dem Kleingedruckten nicht, ich weis einfach nicht wie ich das einsetzen soll.
Keine Ahnung. Deine Tipps bringen mir nicht weiter. Komme nur auf seiten wo ich die zeichen eh nicht verstehe.
Forum wurde das garnicht beredet und in Delphi-Hilfe steht nichts dazu drin.
Weiß sonst nicht was ich noch alleine ausprobieren soll.
:?: :?: :?:
Es ist wahrscheinlich einfacher als es für mich ist.
Ich kann, aber jetzt auch nur noch auf Tipps warten solange ich keine Ideen habe.

MfG
hui1991
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 17.06.07 15:57 
Kurz probiert:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
uses TypInfo;

procedure TForm1.Button1Click(Sender: TObject);
var
    M: TNotifyEvent;
begin
    M := Button2Click;
    SetMethodProp(Button2, 'OnClick', TMethod(M));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
    Caption := 'Klick!';
end;


War einzig ein kurzes Problem ... was man aus der Fehlermeldung des ersten Sources (Variable erforderlich) aber leicht hätte selber herleiten können ;-)

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
hui1991 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 433

Windows XP, WIndows Vista
Turbo Delphi Explorer| Delphi, PHP,Blitzbasic
BeitragVerfasst: So 17.06.07 18:23 
Danke,

funktioniert jetzt suppa =)
Werde mich melden hier im Forum, wenn was ist ^^

MfG
hui1991