Button zerstören?
Hallo Alle Zusammen
Ich habe hier eine ganz einfaches Programm. Es erstellt 500 Buttons. Nun will ich, das wenn ich einen bestimmten Button drücke, dieser verschwindet (sich zerstört). Aber bei mir kommt immer die Fehlermeldung "Abstrakter Fehler". Was muss ich ändern, damit es funktioniert? Oder geht es überhaupt?
Delphi-Quellcode:
const MAX_BUTTONS = 500; procedure TForm1.Button1Click(Sender: TObject); var i: integer; begin SetLength(pbTemp,MAX_BUTTONS); for i:=0 to MAX_BUTTONS - 1 do begin pbTemp[i] := TButton.Create(nil); pbTemp[i].Name := 'ButtonNr' + IntToStr(i); pbTemp[i].Parent := Form1; pbTemp[i].Top := 16 * i; pbTemp[i].Left := 300; pbtemp[i].OnClick := butclick; pbtemp[i].Tag := i; end; end; procedure TForm1.ButClick(Sender: TObject); var a: integer; begin a := (sender as Tbutton).tag; label1.caption := inttostr(a); pbtemp[a].Free; end; |
Re: Button zerstören?
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
das liegt daran, dass Du den Button, der das OnClick Event gefeuert hat im selben zerstörst. D.h. der Button ruft den OnClick-Handler auf. Nach dem der Code im OnClick-Handler abgearbeitet wurde kehrt dieser zum Button zurück. Nur zum welchem Button soll er denn zurück ??? Der Button wurde ja freigegeben. Deshalb empfehle ich im OnClick-Handler den Button nicht freizugeben, sondern mit PostMessage eine Botschaft an das Formular zu senden. Über wParam des Messagerecords kannst Du den Arrayindex übergeben. Siehe Anlage |
Re: Button zerstören?
Vielen Dank. Isst genau dass was ich gebraucht habe. :angle:
|
Re: Button zerstören?
hallo,
hab da mal ne frage zum "button-prog". wie müsste ich das ganze lösen, wenn ich einfach in einer schleife einige objekte löschen möchte?
Delphi-Quellcode:
da müsste ich doch jetzt quasi nur "TComponent(Sender)" durch meine komponente (über FindComponent) ersetzen.
PostMessage(Handle,PM_FREEBUTTON,TComponent(Sender).Tag,0);
nur was muss ich nun hier machen:
Delphi-Quellcode:
ich habe ja kein array mit den objektnamen und möchte auch keins erstellen. was bedeutet denn das "message.wparam" überhaupt. Muss ich bei FreeAndNil nicht einfach nur den Objektnamen wie "Edit1" einsetzen?
FreeAndNil(FButtonArray[Message.wParam]);
danke schonmal gruß tkliewe hier mal kurz der ganze quelltext:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var iCnt : Integer; begin SetLength(FButtonArray,MAX_BUTTONS); For iCnt:=0 to MAX_BUTTONS-1 do begin FButtonArray[iCnt]:=TButton.Create(Self); FButtonArray[iCnt].Parent:=Self; FButtonArray[iCnt].Caption:='Button '+IntToStr(iCnt+1); FButtonArray[iCnt].SetBounds(100,12+iCnt*(FButtonArray[iCnt].Height+4),FButtonArray[iCnt].Width,FButtonArray[iCnt].Height); FButtonArray[iCnt].Tag:=iCnt; FButtonArray[iCnt].OnClick:=ButtonClick; end; Button1.Enabled:=False; end; procedure TForm1.ButtonClick(Sender: TObject); begin {PostMessage wird hier verwendet, weil PostMessage ans Ende der Botschafts- warteschlange gestellt wird und deshalb erst abgearbeitet wird wenn alle anderen Botschaft, wie z.B. die Click Botschaft an den Button abgearbeitet wurde} PostMessage(Handle,PM_FREEBUTTON,TComponent(Sender).Tag,0); end; procedure TForm1.PMFREEBUTTON(var Message: TMessage); begin FreeAndNil(FButtonArray[Message.wParam]); end; |
Re: Button zerstören?
Zitat:
Delphi-Quellcode:
Codeprocedure TForm1.ButtonXClick(Sender : TObject);
var iCnt : Integer; begin For iCnt:=Low(FButtonArray) to High(FButtonArray) do FreeAndNil(FButtonArray[iCnt]); end; Zitat:
Delphi-Quellcode:
Objektnamen sind wie andere Namen auch nur Schall und Rauch. Wichtig ist, dass Du eine gültige Referenz auf das Objekt hast. Über den Namen des Objektes sorgt der Compiler dafür das dem so ist. Ob die Referenz in einer Instanzenvariablen oder in Array oder sonst wo gespeichert ist ist dabei egal.
procedure TForm1.ButtonXClick(Sender : TObject);
var iCnt : Integer; begin For iCnt:=0 to 9 do // wir haben 10 Buttons FindComponent('Button'+IntToStr(iCnt)).Free; end; |
Re: Button zerstören?
Ich hab hierzu auch noch eine Frage:
Ich habe einem Button des FButtonArrays die Funktion gegeben, dass Programm zu beenden. Erstellen eines neuen Buttons
Delphi-Quellcode:
SetLength(Form1.FButtonArray, 10);
Form1.FButtonArray[iCnt]:= TButton.Create(Form1); Form1.FButtonArray[iCnt].Parent := Form1; Form1.FButtonArray[iCnt].Caption := 'Programm Beenden'; //Form1.FButtonArray[iCnt].Tag := iCnt; Form1.FButtonArray[iCnt].Left := x+25; Form1.FButtonArray[iCnt].Top := y; Form1.FButtonArray[iCnt].Width := w; Form1.FButtonArray[iCnt].Height := h; @Form1.FButtonArray[iCnt].OnClick := @MeinEigenesOnClick; Nachdem auf ein Button geklickt wurde
Delphi-Quellcode:
Seitdem ich dies so mache (Beenden des Programms) kommt nach Schließen des Programms der Windows-Fehler-Sound
procedure MeinEigenesOnClick (Self: TObject; Sender: TObject);
var prg_gesucht : string; begin prg_gesucht := TButton(Sender).Caption; if prg_gesucht = 'Programm beenden' then begin MessageDlg ('Beenden ...',mtInformation,[mbOk],0); // Fehlt hier was ??? Form1.Close; end; [...] und in der Delphi-Umgebung die Debugger-Exception "Ungültige Zeigeroperation". Kann mir jemand helfen ??? MFG devnull |
Re: Button zerstören?
hmm, ich hab das hier mit Buttonserstellen auch mal ausprobiert (<- newb ;))
klappt auch alles soweit, nur wenn ich versuche den neuen buttons ein ereignis zuzuweisen mit
Delphi-Quellcode:
kommt der Fehler "Incompatible Types: TNotifyevent and Procedure".
Buttonarray[i].OnClick := TForm1.EigenerClick;
ich hab das aber doch genauso gemacht wie ihr hier :gruebel: |
Re: Button zerstören?
Ersetz die Zeile mal mit der unten stehenden:
Delphi-Quellcode:
-->
Buttonarray[i].OnClick := TForm1.EigenerClick;
Delphi-Quellcode:
@Form1.FButtonArray[iCnt].OnClick := @MeinEigenesOnClick;
MFG devnull |
Re: Button zerstören?
hallo,
@ Jens Schumann du hast mir ja geschrieben, dass ich einfach mit findcomponent das objekt suchen soll und dann mit free "löschen". dann habe ich aber wieder das geleiche problem wie der ursprüngliche poster ("Abstrakter fehler"). ich dachte halt, dass mir das "PostMessage" diesen fehler behebt. mfg tkliewe |
Re: Button zerstören?
Zitat:
Das darfst Du natürlich nicht. Habe ich oben auch extra geschrieben. Wenn Du das unbedingt möchtest, dann kannst Du PostMessage nutzen. In den lParam packst Du die Objektreferenz, die Du mit Findcomponent gefunden hast. In dem Messagehandler kannst Du dann aus lParam die Objektreferenz ziehen und den Button freigeben. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:44 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