Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Procedure auf Knopfdruck [gelöst]


blackbirdXXX - So 15.02.04 21:55
Titel: Procedure auf Knopfdruck [gelöst]
Ich erstelle 100 Buttons. Das klappt.
Nun will ich diesen Buttons eine Funktion zuweisen.

Delphi-Quelltext
1:
2:
for i := 1 to 100 do
 dr_buttons[i].OnClick := action(i);

= Fehler. Ich kann nur

Delphi-Quelltext
1:
2:
for i := 1 to 100 do
 dr_buttons[i].OnClick := action;

schreiben. Aber ich will übergeben welcher button die Procedure aufgerufen hat. Hab schon versucht das mit Sender rauszukriegen will aber irgendwie nicht funzen.

So hätte meine Prozedure aussehen sollen

Delphi-Quelltext
1:
2:
3:
4:
procedure Tdesigner.OpenUrl(id: Integer; Sender: TObject);
begin
 ShellExecute(0'open', pchar(act_url[id]), '''', sw_normal);
end;


Keldorn - So 15.02.04 22:07

Hallo

versteh nicht ganz, was du genau willst, aber vielleicht hiflt dir die Tag-Eigenschaft weiter. dort kannste deine Nummer hinterlegen und beim onclick kannst du mit TComponent(Sender).Tag diese wieder auslesen.

Mfg Frank


blackbirdXXX - Mo 16.02.04 08:24

Ich habe drei Komponentenarten.
array of TButton, array of TSpeedButton, array of TImage.

Jetzt muss ich allen in einem Rutsch eine Prozedur verpassen die so aussieht


Delphi-Quelltext
1:
2:
3:
4:
procedure Tdesigner.OpenUrl(id: Integer; Sender: TObject);
begin
 ShellExecute(0'open', pchar(act_url[id]), '''', sw_normal);
end;


Aber so will der Debugger das nicht.


teebee - Mo 16.02.04 09:18

Das kann so auch nicht gehen. Das OnClick-Ereignis ist vom Typ TNotifyEvent, der ist so definiert:type TNotifyEvent = procedure (Sender: TObject) of object;
D.h. Deine Ereignis-Prozedur muss vom selben Typ sein, ist sie im Moment aber noch nicht, da sie noch einen zweiten Parameter erwartet.
Du kannst es so machen, wie keldorn schon angesprochen hat. Setze beim Erzeugen Deiner Buttons/SpeedButtons/Images das 'Tag'-Property auf die gewünschte ID und beziehe Dich dann in der Ereignis-Prozedur darauf:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
for i := 1 to 100 do begin
 dr_buttons[i].OnClick := OpenUrl;
 dr_buttons[i].Tag := i;
 ...
end;

procedure Tdesigner.OpenUrl(Sender: TObject); 
begin 
 If (Sender is TButton) Or (Sender is TSpeedButton) Or (Sender is TImage)
  Then ShellExecute(0'open', pchar(act_url[TComponent((Sender).Tag]), '''', sw_normal);
end;


Insgesamt finde ich das Design einer Anwendung allerdings nicht so gelungen, wenn man soviele Buttons braucht, da gibt es eigentlich schönere Möglichkeiten für eine Auswahl (Listboxen, ComboBoxen, etc...).

Gruß, teebee

Moderiert von user profile iconPeter Lustig: Zeilenumbruch eingefügt


blackbirdXXX - Mo 16.02.04 15:41

Ich will auch nicht 100 Buttons oder so auf eine Seite tun. Der Benutzer soll später Buttons hinzufügen. d.H. Userbuttons.


blackbirdXXX - Mo 16.02.04 18:13

Sollte eigentlich funktionieren nur zweigt er mir eine lustige Fehlermeldung
Fehlermeldung hat folgendes geschrieben:

---------------------------
projekt1.exe
---------------------------
Zugriffsverletzung bei Adresse 00470A8C in Modul 'projekt1.exe'. Schreiben von Adresse 0000000C.
---------------------------
OK
---------------------------

Das will irgendwie nicht. Ich habe herausgefunden dass er das nur anzeigt wenn ich die Tags festlege.


Motzi - Mo 16.02.04 18:44

Wie schaut denn dein momentan verwendeter Code aus..?


blackbirdXXX - Mo 16.02.04 18:54

Momentan so:

Beispiel: Label

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:
 //Label
 if lowercase(tmpclass) = 'label' then
  begin
   xcr_Label[dg].Tag := dg;
   xcr_label[dg] := TLabel.Create(self);
   xcr_label[dg].Caption := tmpvalue;
   xcr_label[dg].Name := 'xcr_' + tmpname;
   if lowercase(tmpcolor) <> 'transparent' then
    xcr_label[dg].Color := StringToColor(tmpcolor)
   else
    xcr_label[dg].Transparent := true;

   //Aktion zuweisen
   if lowercase(Copy(tmpaction, 111)) = 'setvisible(' then
    begin
    act_url[dg] := Copy(tmpaction, 12, length(tmpaction)-11);
     xcr_label[dg].OnClick := SetVisible;
    end;
   if lowercase(Copy(tmpaction, 19)) = 'setvalue(' then
    begin
    act_url[dg] := Copy(tmpaction, 10, length(tmpaction)-9);
     xcr_label[dg].OnClick := SetValue;
    end;
   if lowercase(Copy(tmpaction, 14)) = 'msg(' then
    begin
    act_url[dg] := Copy(tmpaction, 5, length(tmpaction)-4);
     xcr_label[dg].OnClick := MsgBox;
    end;
   if lowercase(tmpaction) = 'close' then xcr_label[dg].OnClick := CloseProgram;
   if lowercase(Copy(tmpaction, 14)) = 'url(' then
    begin
    act_url[dg] := Copy(tmpaction, 5, length(tmpaction)-4);
     xcr_label[dg].OnClick := OpenUrl;
    end;
   if lowercase(Copy(tmpaction, 14)) = 'open(' then
    begin
    act_url[dg] := Copy(tmpaction, 6, length(tmpaction)-5);
     xcr_label[dg].OnClick := OpenUrl;
    end;
   xcr_label[dg].Parent := self;
   xcr_label[dg].Left := tmpposx;
   xcr_label[dg].Top := tmpposy;
   xcr_label[dg].Width := tmpwidth;
   xcr_label[dg].Height := tmpheight;
   xcr_label[dg].AutoSize := tmpautosize;
   xcr_label[dg].WordWrap := tmpwordwrap;
   xcr_label[dg].Font.Name := tmpfontface;
   xcr_label[dg].Font.Size := tmpfontsize;
   xcr_label[dg].Font.Color := StringToColor(tmpfontcolor);

   //Sichtbarkeit
   if tmpvisible = 'full' then xcr_label[dg].Visible := true
   else xcr_label[dg].Visible := false;
  end;


Die wichtigsten Proceduren.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure Tdesigner.MsgBox(Sender: TObject);
var a: Integer;
begin
 if (Sender is TButton) or (Sender is TSpeedButton) or (Sender is TImage)
  then Application.MessageBox(pchar(GetShortHint(act_url[TComponent(Sender).Tag])), pchar(GetLongHint(act_url[TComponent(Sender).Tag])), 0);
end;

procedure Tdesigner.CloseProgram(Sender: TObject);
begin
 Close;
end;

procedure Tdesigner.OpenUrl(Sender: TObject);
begin
 if (Sender is TButton) or (Sender is TSpeedButton) or (Sender is TImage)
  then ShellExecute(0'open', pchar(act_url[TComponent(Sender).Tag]), '''', sw_normal);
end;


blackbirdXXX - Mo 16.02.04 19:21

Hab nun eine Idee. Ich denke es liegt an dem

Delphi-Quelltext
1:
xcr_Label[dg].Tag := dg;                    

Wenn das nicht drinnen ist dann läuft alles wie es soll.
Kann es sein das diese Tags schon besetzt sind?


Keldorn - Mo 16.02.04 21:00

Hallo

Zitat:

if lowercase(tmpclass) = 'label' then
begin
xcr_Label[dg].Tag := dg;
xcr_label[dg] := TLabel.Create(self);

ich würd erst das label erzeugen und dann die Eigenschaften ändern.
ein Tag ist nur eine zahl, und dient für zusätzliche Informationen. Was du dort hinterlegst bleibt dir überlassen

Mfg Frank


blackbirdXXX - Di 17.02.04 18:18

Funzt. *aufdiestirnhau* Hätt ich auch drauf kommen müssen.