[gelöst] Variable Button-Klick Prozedur

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Theozh
Beiträge: 99
Registriert: So 1. Jul 2012, 10:56

[gelöst] Variable Button-Klick Prozedur

Beitrag von Theozh »

Hallo,
einem Button möchte ich über eine Variable eine Prozedur zuordnen.
Wenn ich das "fix verdrahte", sieht das etwa so aus:

Code: Alles auswählen

 
Button1.OnClick:= @Test;
 
procedure Test();
begin
  ShowMessage('Test');
end;
 
Da ich den Knopf selbst erst zur Laufzeit des Programms erzeuge, möchte/muss ich auch die auszuführende Prozedur erst zur Laufzeit des Programms festlegen.

Lazarus verlangt dafür:
"<procedure variable type of procedure(TObject) of object;Register>"

Da verstehe ich bislang nur Bahnhof.
Wie kann ich so eine Variable definieren/deklarieren/initialisieren/zuweisen/ändern?
Zuletzt geändert von Theozh am So 2. Feb 2014, 01:05, insgesamt 1-mal geändert.

Benutzeravatar
theo
Beiträge: 10900
Registriert: Mo 11. Sep 2006, 19:01

Re: Variable Button-Klick Prozedur

Beitrag von theo »

Theozh hat geschrieben: Wenn ich das "fix verdrahte", sieht das etwa so aus:
Was heisst "etwa so"? Das geht nicht.
Der Eventhandler muss genau so aussehen, wie wenn du ihn von der IDE machen lässt, also z.B.

Code: Alles auswählen

 
procedure TForm1.Test(Sender: TObject);
begin
  ShowMessage('Test');
end;   
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  Button1.OnClick:=@Test;
end;
 

Theozh
Beiträge: 99
Registriert: So 1. Jul 2012, 10:56

Re: Variable Button-Klick Prozedur

Beitrag von Theozh »

OK, korrekt...
TForm1 habe ich der Einfachheit halber weggelassen...
Starten wir mit Deiner Version.

Code: Alles auswählen

 
procedure TForm1.FormCreate(Sender: TObject);
begin
  CreateButton(Form1);  // eine Procedure z.B. aus Unit2 s.u.
  Button1.OnClick:=@Test; // ob hier Test1 oder Test2 ausgeführt wird, will ich auch aus Unit2 definieren
end;
 
procedure TForm1.Test1(Sender: TObject);
begin
  ShowMessage('Test1');
end;   
 
procedure TForm1.Test2(Sender: TObject);
begin
  ShowMessage('Test2');
end;   

Code: Alles auswählen

 
unit Unit2;
...
 
procedure CreateButton(MyForm: TForm);
begin
  NewButton:= TButton.Create(MyForm);
  with NewButton do
  begin
    Name:= 'Knopf1';
    Parent:= MyForm;
    OnClick:= ???  // Wie kann ich hier Test1 oder Test2 definieren?
  end;
end;
Solche Knöpfe definiere ich so, das funktioniert. Jetzt fehlt mir nur, dass ich diesen Knöpfen eine Prozedur bei "OnClick" zuweisen kann.
Und jetzt hoffe ich, dass es "geht nicht" nicht gibt.

Benutzeravatar
theo
Beiträge: 10900
Registriert: Mo 11. Sep 2006, 19:01

Re: Variable Button-Klick Prozedur

Beitrag von theo »

Verstehe nicht, warum du das so machst. Das sieht für mich nach extrem verkorkstem Design aus. Das bringt so mMn nichts.
Da würde ich mir nochmal die Struktur überlegen.

Theozh
Beiträge: 99
Registriert: So 1. Jul 2012, 10:56

Re: Variable Button-Klick Prozedur

Beitrag von Theozh »

hmm, wie könnte ich es dann machen?
Etwas vereinfacht: stell Dir z.B. Taschenrechnertasten oder eine Tastatur vor. Diese möchte ich auf verschiedenen Forms per Programm und nicht von Hand erzeugen. Letzteres wäre bei Änderungen von Position, Anordnung, Schriftgröße, usw. sehr aufwändig.
Was gibt es Deiner Meinung nach für andere Möglichkeiten?

martin_frb
Beiträge: 587
Registriert: Mi 25. Mär 2009, 21:12
OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
CPU-Target: mostly 32 bit

Re: Variable Button-Klick Prozedur

Beitrag von martin_frb »

Also wenn Du

Code: Alles auswählen

 
procedure TForm1.Test1(Sender: TObject);
 
in einer eigenen Variable zwischenspeichern willst

Code: Alles auswählen

 
type 
  TButtonClickEvent = procedure(Sender: TObject) of object;
var
  SomeClick: TButtonClickEvent; 
 
Und die procedure muss nicht unbedingt teil von TForm sein. Aber es muss eine Methode sein. Das heisst es muss zu einem Object (irgendeinem Object) gehoeren.

Code: Alles auswählen

 
type 
  TMyOwnClass = class
     procedure Test1(Sender: TObject);
  end;
 
Natuerlich brauchst du eine Instanz der Klasse

Benutzeravatar
theo
Beiträge: 10900
Registriert: Mo 11. Sep 2006, 19:01

Re: Variable Button-Klick Prozedur

Beitrag von theo »

Theozh hat geschrieben:hmm, wie könnte ich es dann machen?
Etwas vereinfacht: stell Dir z.B. Taschenrechnertasten oder eine Tastatur vor. Diese möchte ich auf verschiedenen Forms per Programm und nicht von Hand erzeugen. Letzteres wäre bei Änderungen von Position, Anordnung, Schriftgröße, usw. sehr aufwändig.
Was gibt es Deiner Meinung nach für andere Möglichkeiten?
Dann mach eine Klasse

TTaschenRechnerTastatur=class(TCustomControl)

Da drin arbeitest du alles ab.
Die Tastauren pappst du dann nur noch auf deine Forms.

EDIT: Habe dir mal ein simples Beispiel gemacht, wie man sowas einigermassen sauber lösen kann. TTaschenRechnerTastatur kann man auch in einer anderen Unit definieren.

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
 
type
 
 { TTaschenRechnerTastatur }
 
 TTaschenRechnerTastatur=class(TCustomControl)
  private
     procedure BtnClick(Sender: TObject);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;
 
  { TForm1 }
 
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
    Tast:TTaschenRechnerTastatur;
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  Tast:=TTaschenRechnerTastatur.Create(self);
  Tast.Parent:=Self;
  Tast.Align:=alClient;
end;
 
{ TTaschenRechnerTastatur }
 
procedure TTaschenRechnerTastatur.BtnClick(Sender: TObject);
begin
  ShowMessage((Sender as TButton).Caption);
end;
 
constructor TTaschenRechnerTastatur.Create(AOwner: TComponent);
var i:integer;
  Btn:TButton;
begin
  inherited;
  for i:=0 to 9 do
  begin
     Btn:=TButton.Create(self);
     Btn.Parent:=self;
     Btn.Width:=Btn.Height;
     Btn.Left:=i*Btn.Width;
     Btn.Caption:=Inttostr(i);
     Btn.OnClick:=@BtnClick;
  end;
end;
 
destructor TTaschenRechnerTastatur.Destroy;
begin
  inherited Destroy;
end;
 
end.
 
 

Theozh
Beiträge: 99
Registriert: So 1. Jul 2012, 10:56

Re: Variable Button-Klick Prozedur

Beitrag von Theozh »

Danke, Theo, für das ausführliche Beispiel. Sieht einfach aus, aber bei mir bleibt die Form allerdings leer. Keine Knöpfe 0-9...
Fehlt da noch ein Detail? Ist da irgendetwas noch undefiniert? z.B. btn.name oder btn.top, btn.height ... ?

Benutzeravatar
theo
Beiträge: 10900
Registriert: Mo 11. Sep 2006, 19:01

Re: Variable Button-Klick Prozedur

Beitrag von theo »

Müsste klappen. Du bist aber schon so schlau, dass du das Event OnCreate der Form eingehängt hast?

Theozh
Beiträge: 99
Registriert: So 1. Jul 2012, 10:56

Re: Variable Button-Klick Prozedur

Beitrag von Theozh »

nicht ganz... :oops:
ok, tut...

Theozh
Beiträge: 99
Registriert: So 1. Jul 2012, 10:56

Re: Variable Button-Klick Prozedur

Beitrag von Theozh »

Wenn ich jetzt noch rausfinde wie ich mit Deinem Konstrukt Folgendes erledige, dann kann ich meinen früheren "Murks" ersetzen.

a) wie ich das ganze Zahlenpanel wieder verschwinden lassen kann, z.B. wenn Button 5 gedrückt wird sollen die Tasten verschwinden
Mit Destroy aber wie?

Code: Alles auswählen

if (Sender as TButton).Caption = '5' then ???.Destroy;
b) wie z.B. bei Drücken von Knopf 7, auch Knopf 1 gedrückt wird (dazu sollten es eigentlich alles Toggleboxes sein)

Code: Alles auswählen

if (Sender as TButton).Caption = '7' then ???.Checked:= true;

Benutzeravatar
theo
Beiträge: 10900
Registriert: Mo 11. Sep 2006, 19:01

Re: Variable Button-Klick Prozedur

Beitrag von theo »

Ja, dann musst du die Buttons halt referenzieren können.
Dazu kannst du Variablen einführen, eine TObjectList nehmen oder mit FindComponent arbeiten.

Aber mal ehrlich, möchtest du dir nicht ein Delphi oder Lazarus Buch besorgen und mal ein bisschen darin lesen, damit du etwas selbständiger wirst?
Weil so schrittchenweise im Forum nachfragen, das ist doch nix.

Theozh
Beiträge: 99
Registriert: So 1. Jul 2012, 10:56

Re: Variable Button-Klick Prozedur

Beitrag von Theozh »

Du wirst es nicht glauben, aber ich habe ein Lazarus- und ein FreePascal-Buch im Regal. Doch weder im einen noch im anderen findet man z.B. TObjectList oder FindComponent im Inhaltsverzeichnis. Um Anworten auf konkrete Fragen zu finden und das Ganze zu erlernen, halte ich die Bücher für wenig geeignet. Vielleicht kannst Du mir ja brauchbare Online-Tutorials nennen...?

Benutzeravatar
theo
Beiträge: 10900
Registriert: Mo 11. Sep 2006, 19:01

Re: Variable Button-Klick Prozedur

Beitrag von theo »

Wie gesagt, ein altes Delphi Buch (zu D6 oder so) besorgen.
Sowas, z.B. http://www.amazon.de/Borland-Delphi-6-G ... 3446217347

Sonst findet auch Google immer einiges:

http://www.delphi-treff.de/tutorials/vc ... rundlagen/
http://docwiki.embarcadero.com/CodeExam ... 8Delphi%29

etc.

Theozh
Beiträge: 99
Registriert: So 1. Jul 2012, 10:56

Re: Variable Button-Klick Prozedur

Beitrag von Theozh »

@martin_frb
Danke! Das war für mich nicht leicht zu verstehen, aber so funktioniert es!

@theo
...so eben lieber etwas, was sofort funktioniert und den Zweck erfüllt, als eine Eleganz, die ewig braucht und neue Probleme aufwirft...

Antworten