| Autor |
Beitrag |
rolX
      
Beiträge: 25
D5
|
Verfasst: Fr 13.05.05 12:31
Hallo zusammen,
ich möchte gerne während der Laufzeit Buttons generieren und beim Klick auf diese Buttons erkennen können, welcher der Buttons geklickt wurde. Das Buttons Generieren habe ich schonmal hinbekommen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| var tbButtons : array of TButton; begin
SetLength(tbButtons, icnButtons);
for icnI := 0 to (icnButtons -1) do begin tbButtons[icnI] := TButton.Create(frmForm1); tbButtons[icnI].Parent := frmForm1; tbButtons[icnI].Visible := true; tbButtons[icnI].Caption := biaButtons[icnI].szCaption; tbButtons[icnI].Default := biaButtons[icnI].boDefault; tbButtons[icnI].Cancel := biaButtons[icnI].boCancel; tbButtons[icnI].Enabled := biaButtons[icnI].boEnabled; tbButtons[icnI].Name := 'Button' + IntToStr(icnI +1); end; |
Wie kann ich nun dem OnClick Event eines jeden Buttons eine Funktion zuweisen und dabei noch erkennen, welcher der Buttons geklickt wurde.
Ich hab' im Netz bereits gesucht und das gefunden:
www.delphi-fundgrube.../faq14.htm#topic1402
aber ich blick das nicht so ganz... also ein klizekleines beispiel würde mir bestimmt weiterhelfen.
Vielen Dank im Voraus schonmal,
Gruß, rolX
Moderiert von raziel: Code- durch Delphi-Tags ersetzt.
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 13.05.05 12:43
Na ja, mit (Sender as TButton) kannst du auf den Button zugreifen und´da kannst du beispielsweise das mit deinem Buttonarray vergleichen oder aber bei der Erzeugung deinen Buttons einen Wert für Tag zuweisen.
Tag kannst du ja frei verwenden und ist ein Integer-Wert.
Wenn du also bei der Erzeugung
Delphi-Quelltext 1: 2:
| tbButtons[icnI].Tag := icnI; tbButtons[icnI].OnClick := ButtonClicked; |
benutzt, kannst du in OnClick mit
Delphi-Quelltext 1:
| (Sender as TButton).Tag |
herausfinden welcher Button im Array das ist.
Du kannst so auch die Buttons gruppieren, indem du mehreren dieselbe Tag-Eigenschaft zuweist...
Ach so: Mit (Sender as TButton).Name hast du auch Zugriff auf den Namen, den du dem Button gegeben hast, dann brauchst du auch die Tag-Eigenschaft gar nicht, aber mit der kann man, wie ich eben schrieb ja auch noch mehr machen...
|
|
feivel3333
      
Beiträge: 190
W7
Delphi XE prof
|
Verfasst: Fr 13.05.05 12:47
Titel: Zum laufzeitgenerierten Button eine Funktion zuweisen
Hi,
so was habe ich auch schon mal programmiert.
Du kannst dem zur Laufzeit generierten Button folgendermaßen eine Funktion zuweisen:
Benutze die gleiche Form von Funktionen, die auch beim "normalen" Button erzeugt wird. Faulheiterweise würde ich mir einen Button aufs Formular legen und doppelklicken. Dann die Funktion ergänzen und den Button wieder löschen (aber bitte nicht die Funktion!).
Nun, am Ende deines Quelltextes, schreibst du
Quelltext 1:
| tbButtons[icnI].OnClick := PseudoButtonClick; |
Mehr nicht.
Das war´s.
Gruß, AS
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 13.05.05 12:57
@feivel3333: Ich glaube, das war nicht das Problem. Ich hab das so verstanden, dass er das weiß, aber nicht weiß, wie er dann noch herausfindet, welcher Button das Ereignis ausgelöst hat...
|
|
rolX 
      
Beiträge: 25
D5
|
Verfasst: Fr 13.05.05 13:42
Hallo,
vielen Dan für Eure Antwort, aber ich bekomms nicht hin,
wenn ich eine Procedure "schreiben lasse":
Delphi-Quelltext 1: 2: 3: 4:
| procedure TfrmXMsgBox.btnXMBClick(Sender: TObject); begin showmessage('Test'); end; |
oder auch selbst eine schreibe:
Delphi-Quelltext 1: 2: 3: 4:
| procedure ButtonClicked(); begin end; |
Dann bekomme ich nur die Meldung:
[Error] srcFrm1.pas(122): Incompatible types: method pointer and regular procedure
oder
[Error] srcXMsgBox.pas(122): Incompatible types: 'TNotifyEvent' and 'Procedure'
an der Stelle:
Delphi-Quelltext 1:
| tbButtons[icnI].OnClick := ButtonClicked; |
@jaenicke: Kannst Du mir zeigen, wie ich das ins Programm bringe - wo steht die Zeile
Delphi-Quelltext 1:
| (Sender as TButton).Tag |
Wie siht die Funktion aus, in der ich den Tag auslesen kann? Sorry, bin Anfänger.
Gruß, rolX.
Moderiert von raziel: Code- durch Delphi-Tags ersetzt.
|
|
Fabian W.
      
Beiträge: 1766
Win 7
D7 PE
|
Verfasst: Fr 13.05.05 13:48
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 13.05.05 13:58
Also bei deiner selbst geschriebenen Methode hast du den Parameter vergessen.
Ich versuch mal, so aus dem Kopf ein Beispiel zu schreiben:
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:
| type TForm1 = class(TForm) private public procedure FormCreate(Sender: TObject); procedure ButtonClicked(Sender: TObject); end;
implementation
procedure TForm1.FormCreate(Sender: TObject); begin tbButtons[icnI].onClick := ButtonClicked; end;
procedure TForm1.ButtonClicked(Sender: TObject); begin ShowMessage((Sender as TButton).Name + ' geklickt'); end;
end. |
Statt in FormCreate musst du halt in deiner Methode die Zeile hinschreiben, das ist nur ein Beispiel.
|
|
rolX 
      
Beiträge: 25
D5
|
Verfasst: Fr 13.05.05 14:25
Wenn ich's genau so mache bekomme ich folgenden Fehler:
Quelltext 1:
| tbButtons[icnI].OnClick := TfrmForm1.ButtonClicked; |
erzeugt: [Error] srcXMsgBox.pas(122): Incompatible types: 'TNotifyEvent' and 'Procedure'
oder bei
Quelltext 1:
| tbButtons[icnI].OnClick := ButtonClicked; |
[Error] srcXMsgBox.pas(122): Undeclared identifier: 'ButtonClicked'
Was stimmt nicht? Wie kann ich ihm sagen, dass das ein TNotifyEvent sein soll?
Gruß, rolX.
|
|
Fabian W.
      
Beiträge: 1766
Win 7
D7 PE
|
Verfasst: Fr 13.05.05 14:27
Die Variablen und Oarameter der Buttonclicked Procedure müssen mit denen einer Buttonclick Proc übereinstimmen:
(Sender: TObiject, Shift....)
|
|
Tobias1
      
Beiträge: 454
Win 98, XP Prof
D3 Prof, D2005 Prof
|
Verfasst: Fr 13.05.05 14:29
Ist bei dir vielleicht procedure buttonclick und nicht proccedure tform1.buttonclick??
_________________ Auch das schlechteste Buch hat seine gute Seite: die letzte. (John Osborne)
|
|
rolX 
      
Beiträge: 25
D5
|
Verfasst: Fr 13.05.05 14:39
|
|
Tobias1
      
Beiträge: 454
Win 98, XP Prof
D3 Prof, D2005 Prof
|
Verfasst: Fr 13.05.05 14:41
Kopier vielleicht mal die ganze Unit rein
_________________ Auch das schlechteste Buch hat seine gute Seite: die letzte. (John Osborne)
|
|
Fabian W.
      
Beiträge: 1766
Win 7
D7 PE
|
Verfasst: Fr 13.05.05 14:41
|
|
Tobias1
      
Beiträge: 454
Win 98, XP Prof
D3 Prof, D2005 Prof
|
Verfasst: Fr 13.05.05 14:43
Fabian W. hat folgendes geschrieben: | | Sicher, sind das alle?? |
Parameter?
Man braucht doch sonst nix mehr, oder?
_________________ Auch das schlechteste Buch hat seine gute Seite: die letzte. (John Osborne)
|
|
Fabian W.
      
Beiträge: 1766
Win 7
D7 PE
|
Verfasst: Fr 13.05.05 14:45
Ja es sind alle! Er soll halt mal die Unit schicken!
|
|
rolX 
      
Beiträge: 25
D5
|
Verfasst: Fr 13.05.05 15:13
Ok, hier die ganze Unit:
Das soll eine erweiterte Messagebox geben, ber der die Buttons beliebig betextet werden können.
Rückgabe soll sein: 1 für den 1. Button, 2 für den 2. usw. 0 wenn X geklickt wurde. Optional soll sie auch als Inputbox verwendet werden können. Die Rückgabe habe ich noch nicht gebastelt.
Beispielaufruf:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| iReturn := xMsgBox('Hier ein Text zum Testen' + #10 + #13 + 'mit Umbruch.' + #10 + #13 + 'Und noch einer asöidu f asodf aos ösdopfsopiuw efwefu wi', 'Der Titel', 1, '+ Ok |-Abbrechen|*Disabled', 0, true, szText) ; |
Also los gehts:
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: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221:
| unit srcXMsgBox;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
const giXMBInformation = 1; giXMBQuestion = 2; giXMBExclamation = 3; giXMBCritical = 4; giXMBApplication = 5;
type tpeButtonInfos = record icnNo : Integer; szCaption : String; boEnabled : boolean; boDefault : Boolean; boCancel : Boolean; end;
type TfrmXMsgBox = class(TForm) imgXMBApplication: TImage; inpXMB001: TEdit; lblXMB001: TLabel; imgXMBCritical: TImage; imgXMBExclamation: TImage; imgXMBInformation: TImage; imgXMBQuestion: TImage; tmrXMB001: TTimer; procedure tmrXMB001Timer(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Button1Click(Sender: TObject); private public procedure ButtonClicked(Sender: TObject); end;
function xMsgBox(const szMessage : String; const szTitle: String; const iStyle: Integer; const szButtons : String; const iTimeOut: Integer; const boInputEnable: Boolean; var szDefaultInput: String) : Integer;
function szGetChar(const szInput : String; iPos: Integer) : String;
var frmXMsgBox: TfrmXMsgBox;
implementation
{$R *.DFM}
function xMsgBox(const szMessage : String; const szTitle: String; const iStyle: Integer; const szButtons : String; const iTimeOut: Integer; const boInputEnable: Boolean; var szDefaultInput: String) : Integer;
var iReturn : Integer; biaButtons : array of tpeButtonInfos; icnI : Integer; icnButtons : Integer; tbButtons : array of TButton; iButtonWidth : Integer; iButtonSpace : Integer; iButtonTop : Integer; iVertAbst : Integer; begin iButtonSpace := 10; iVertAbst := 15;
iReturn := 0; icnButtons := 0; icnI := 1; while icnI <= Length(szButtons) do begin if (szButtons[icnI] = '|') or (icnI = 1) then begin icnButtons := icnButtons + 1; SetLength(biaButtons,icnButtons); biaButtons[icnButtons-1].icnNo := icnButtons; biaButtons[icnButtons-1].boEnabled := True; biaButtons[icnButtons-1].boDefault := False; biaButtons[icnButtons-1].boCancel := False; if (icnI > 1) then icnI := icnI + 1; if (szButtons[icnI] in ['+','-','*']) then begin if (szButtons[icnI] = '*') then biaButtons[icnButtons-1].boEnabled := False; if (szButtons[icnI] = '+') then biaButtons[icnButtons-1].boDefault := True; if (szButtons[icnI] = '-') then biaButtons[icnButtons-1].boCancel := True; icnI := icnI + 1; end; end; biaButtons[icnButtons-1].szCaption := biaButtons[icnButtons-1].szCaption + szButtons[icnI]; icnI := icnI + 1; end; SetLength(tbButtons, icnButtons); frmxMsgBox.lblXMB001.Caption := ''; for icnI := 0 to (icnButtons -1) do begin tbButtons[icnI] := TButton.Create(frmXMsgBox); tbButtons[icnI].Parent := frmXMsgBox; tbButtons[icnI].Visible := true; tbButtons[icnI].Caption := biaButtons[icnI].szCaption; tbButtons[icnI].Default := biaButtons[icnI].boDefault; tbButtons[icnI].Cancel := biaButtons[icnI].boCancel; tbButtons[icnI].Enabled := biaButtons[icnI].boEnabled; tbButtons[icnI].Name := 'Button' + IntToStr(icnI +1); tbButtons[icnI].Tag := icnI; tbButtons[icnI].OnClick := TfrmXMsgBox.ButtonClicked; if (Length(tbButtons[icnI].Caption) > Length(frmxMsgBox.lblXMB001.Caption)) then frmxMsgBox.lblXMB001.Caption := tbButtons[icnI].Caption; end;
iButtonWidth := frmxMsgBox.lblXMB001.Width + 8;
frmxMsgBox.Caption := szTitle; frmxMsgBox.lblXMB001.Caption := szMessage; frmxMsgBox.Width := icnButtons * iButtonWidth + 40; if ((frmxMsgBox.lblXMB001.Left + frmxMsgBox.lblXMB001.Width + 10) > frmxMsgBox.Width) then frmxMsgBox.Width := frmxMsgBox.lblXMB001.Left + frmxMsgBox.lblXMB001.Width + 40;
frmxMsgBox.Height := frmxMsgBox.lblXMB001.Height + tbButtons[0].Height + 70; if (boInputEnable) then frmxMsgBox.Height := frmxMsgBox.Height + frmxMsgBox.inpXMB001.Height + iVertAbst;
iButtonTop := frmxMsgBox.lblXMB001.Top + frmxMsgBox.lblXMB001.Height + iVertAbst; frmxMsgBox.inpXMB001.Visible := boInputEnable; if (boInputEnable) then begin frmxMsgBox.inpXMB001.Left := frmxMsgBox.imgXMBInformation.left; frmxMsgBox.inpXMB001.Top := frmxMsgBox.lblXMB001.Top + frmxMsgBox.lblXMB001.Height + 20; if (frmxMsgBox.inpXMB001.Top < (frmxMsgBox.imgXMBInformation.Top + frmxMsgBox.imgXMBInformation.Height + iVertAbst)) then frmxMsgBox.inpXMB001.Top := frmxMsgBox.imgXMBInformation.Top + frmxMsgBox.imgXMBInformation.Height + iVertAbst; frmxMsgBox.inpXMB001.Width := frmxMsgBox.Width - (2 * frmxMsgBox.inpXMB001.Left) - 10; frmxMsgBox.inpXMB001.Text := szDefaultInput; iButtonTop := frmxMsgBox.inpXMB001.Top + frmxMsgBox.inpXMB001.height + iVertAbst; end;
if (iButtontop < (frmxMsgBox.imgXMBInformation.Top + frmxMsgBox.imgXMBInformation.Height + iVertAbst)) then iButtontop := frmxMsgBox.imgXMBInformation.Top + frmxMsgBox.imgXMBInformation.Height + iVertAbst;
tbButtons[0].Left := (frmXMsgBox.Width - (icnButtons * iButtonWidth + icnButtons * iButtonSpace) ) div 2 ; for icnI := 0 to (icnButtons -1) do begin tbButtons[icnI].Width := iButtonWidth; tbButtons[icnI].Top := iButtonTop; if (icnI > 0) then tbButtons[icnI].Left := tbButtons[icnI-1].Left + tbButtons[icnI-1].Width + iButtonSpace;
end;
frmxMsgBox.Height := tbButtons[0].Top + tbButtons[0].Height + 2* iVertAbst;
frmxMsgBox.imgXMBInformation.Visible := False; frmxMsgBox.imgXMBQuestion.Visible := False; frmxMsgBox.imgXMBExclamation.Visible := False; frmxMsgBox.imgXMBCritical.Visible := False; frmxMsgBox.imgXMBApplication.Visible := False; case iStyle of giXMBInformation : frmxMsgBox.imgXMBInformation.Visible := True; giXMBQuestion : frmxMsgBox.imgXMBQuestion.Visible := True; giXMBExclamation : frmxMsgBox.imgXMBExclamation.Visible := True; giXMBCritical : frmxMsgBox.imgXMBCritical.Visible := True; giXMBApplication : frmxMsgBox.imgXMBApplication.Visible := True else frmxMsgBox.imgXMBInformation.Visible := True; end;
if (iTimeOut > 0) then frmxMsgBox.tmrXMB001.Interval := iTimeOut * 1000;
frmxMsgBox.ShowModal;
Result := iReturn; end;
function szGetChar(const szInput : String; iPos: Integer) : string; var szReturn : string; begin szReturn := ''; if (iPos > 0) and (iPos <= length(szInput)) then szReturn := copy(szInput,iPos,1); result := szReturn;
end;
procedure TfrmXMsgBox.tmrXMB001Timer(Sender: TObject); begin frmXMsgBox.Close end;
procedure TfrmXMsgBox.FormClose(Sender: TObject; var Action: TCloseAction); var icnI : Integer; begin
icnI := frmXMsgBox.ControlCount -1; while (icnI >= 0) do begin if (frmXMsgBox.Controls[icnI] is TButton) then frmXMsgBox.Controls[icnI].Destroy ; icnI := icnI -1; end;
end;
procedure TfrmXMsgBox.ButtonClicked(Sender: TObject); begin ShowMessage((Sender as TButton).Name + ' geklickt'); end; |
Moderiert von Christian S.: Code- durch Delphi-Tags ersetzt.
|
|
Fabian W.
      
Beiträge: 1766
Win 7
D7 PE
|
Verfasst: Fr 13.05.05 15:37
Kann es sein, dass es an einem Button liegt? Was für Button erstellst du, ich hab den Code nur überflogen.
|
|
rolX 
      
Beiträge: 25
D5
|
Verfasst: Fr 13.05.05 15:47
eine TButton:
die Stelle (Zeile 114):
Quelltext 1:
| tbButtons[icnI] := TButton.Create(frmXMsgBox); |
dabei ist tbButtons: var tbButtons : array of TButton;
Gruß, rolX
|
|
Fabian W.
      
Beiträge: 1766
Win 7
D7 PE
|
Verfasst: Fr 13.05.05 15:51
Und das hgnze spielt sich in einer Unit ab, oder gibst auch erstellte Buttons mit parent(Form2) oder so?
|
|
rolX 
      
Beiträge: 25
D5
|
Verfasst: Fr 13.05.05 15:57
Alles komplett in einer Unit. Die Buttons werden komplett während der Laufzeit generiert. Das funktioniert auch bestens. Nur habe ich jetzt schöne Buttons, kann aber nicht abfragen, welcher geklickt wurde und sollte nach dem Klick die Form auch wieder schließen.
Gruß, rolX
|
|