Ich möchte Popup-Menüs in Pascal dynamisch erstellen können.Dynamische Zuweisung anonymer Funktionen in Pascal
Ich würde auch gerne in der Lage sein, OnClick-Handler zu jedem Menüpunkt dynamisch zuzuweisen.
Dies ist die Art von Dingen, die ich in C# tun kann, das ist mein Versuch in Pascal.
Der Menüpunkt onClick-Event-Handler muss zu einem Objekt gehören (of Object
), also erstelle ich ein Container-Objekt dafür.
Hier ist mein Code:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Menus;
type
TForm1 = class(TForm)
PopupMenu1: TPopupMenu;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TFoo = class
public
Bar : String;
Val : Integer;
end;
TNotifyEventWrapper = class
private
FProc: TProc<TObject>;
I : Integer;
public
constructor Create(Proc: TProc<TObject>);
published
procedure Event(Sender: TObject);
end;
var
Form1: TForm1;
NE : TNotifyEventWrapper;
implementation
{$R *.dfm}
constructor TNotifyEventWrapper.Create(Proc: TProc<TObject>);
begin
inherited Create;
FProc := Proc;
end;
procedure TNotifyEventWrapper.Event(Sender: TObject);
begin
ShowMessage(IntToStr(I));
FProc(Sender);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
F : TFoo;
I: Integer;
mi : TMenuItem;
begin
if Assigned(NE) then FreeAndNil(NE);
for I := 1 to 10 do
begin
F := TFoo.Create;
F.Bar := 'Hello World!';
F.Val := I;
NE := TNotifyEventWrapper.Create
(
procedure (Sender :TObject)
begin
ShowMessage(F.Bar + ' ' + inttostr(F.Val) + Format(' Addr = %p', [Pointer(F)]) + Format('Sender = %p, MI.OnClick = %p', [Pointer(Sender), Pointer(@TMenuItem(Sender).OnClick)]));
end
);
NE.I := I;
mi := TMenuItem.Create(PopupMenu1);
mi.OnClick := NE.Event;
mi.Caption := inttostr(F.Val);
PopupMenu1.Items.Add(mi);
end;
end;
end.
Menüpunktnummer 6
Das Programm zeigt die erwartete Nachricht
jedoch die nächste Nachricht Auf klicken war nein t zeigt das erwartete Ergebnis.
Statt 6 zeigt es Artikel 10
Egal, welches Element in der Liste mich auf, sie alle scheinen den Event-Handler für das letzte Element in der Liste (10) zu schießen.
Es wurde mir vorgeschlagen, dass die Mitgliedsprozedur NE
des Objekts Event
die gleiche Speicheradresse für alle Instanzen dieses Objekts ist.
Egal welchen Menüpunkt ich anklicke, die Speicheradresse MI.OnClick
ist gleich.
Ich frage mich, ob ich einen Fehler/Einschränkung von Delphi – sav
Nein haben Sie nicht gefunden haben. Sie haben die Nuance der variablen Erfassung noch nicht vollständig verstanden. Es erfasst Variablen und nicht Werte. –
Beachten Sie, dass Ihr Code undicht ist. Ich nehme an, Sie wissen das und haben einen Plan, um das später anzugehen. –