Delphi 在运行时创建弹出菜单

Delphi 在运行时创建弹出菜单,delphi,popup,contextmenu,Delphi,Popup,Contextmenu,我试图简单地创建一个弹出菜单(或上下文菜单),向其中添加一些项目,并在鼠标位置显示它。我发现的所有示例都是使用designer实现的。我是通过一个DLL插件来实现的,所以没有表单/设计器。用户将单击主应用程序中的按钮,该按钮调用下面的execute过程。我只希望出现类似于右键单击菜单的内容 我的代码显然不起作用,但我希望有一个在运行时而不是设计时创建弹出菜单的示例 procedure TPlugIn.Execute(AParameters : WideString); var pnt: TP

我试图简单地创建一个弹出菜单(或上下文菜单),向其中添加一些项目,并在鼠标位置显示它。我发现的所有示例都是使用designer实现的。我是通过一个DLL插件来实现的,所以没有表单/设计器。用户将单击主应用程序中的按钮,该按钮调用下面的
execute
过程。我只希望出现类似于右键单击菜单的内容


我的代码显然不起作用,但我希望有一个在运行时而不是设计时创建弹出菜单的示例

procedure TPlugIn.Execute(AParameters : WideString);
var
  pnt: TPoint;
  PopupMenu1: TPopupMenu;
  PopupMenuItem : TMenuItem;
begin
  GetCursorPos(pnt);
  PopupMenuItem.Caption := 'MenuItem1';
  PopupMenu1.Items.Add(PopupMenuItem);
  PopupMenuItem.Caption := 'MenuItem2';
  PopupMenu1.Items.Add(PopupMenuItem);
  PopupMenu1.Popup(pnt.X, pnt.Y);

end;

您必须在Delphi中实际创建类的实例,然后才能使用它们。下面的代码创建一个弹出菜单,向其中添加一些项目(包括用于单击的事件处理程序),并将其分配给表单。请注意,您必须像我一样,自己声明(并编写)handlePoupItemClick事件

在界面部分(将
菜单
添加到
使用
子句):


现在,我将让您来决定如何完成其余部分(在特定位置创建并显示它)。

我创建并显示了上下文菜单,所有这些都是在相同的过程中完成的。我不需要释放任何东西,对吗?我不能回答,因为我不知道你到底做了什么。在我发布的代码中,菜单属于表单(
tpopumenu.Create(Self)
在表单方法中意味着表单是所有者,并负责释放它),单个项属于菜单('TMenuItem.Create(FPopup)`)。您的菜单必须存在足够长的时间,以便事件处理程序在单击某个项目时仍然有效。我可能会让插件在其构造函数中创建弹出菜单
Execute
将获得光标位置并在该位置显示菜单,插件的析构函数可以释放弹出菜单。我不知道这是否适用于你,因为除了你在问题中发布的内容之外,我没有任何其他信息。是的,很抱歉没有详细信息,部分内容是想弄清楚要描述什么以及如何描述。但是添加
析构函数
和添加
FPopup.Free工作。在此之前,我的应用程序一直在崩溃。谢谢。我无法理解人们在发表类似Warren P的评论时如此咄咄逼人。这种傲慢是从哪里来的?他们忘记了他们曾经是新手,犯过同样的基本错误。如果你没有必要的平静来处理这些基本问题,我认为最好不要发表评论。以Ken White(肯·怀特)为例,他的回答直截了当、简单、客观,实际上帮助用户解决了问题。@Warren有很多静态类型的语言,声明一个变量就足以初始化它。C++是明显的例子。@ IKE在插件DLL中期待GUI代码的问题。- 1,“我的代码显然不起作用”。总是用错误信息一字不差地描述故障“我的代码显然不工作”。为什么,为什么?看来你知道答案了!那么为什么要问?@Rigel这就是包存在的原因。为插件使用DLL而不是包意味着DLL有一个单独的VCL实例到主机可执行文件。典型症状是类型标识不能按预期工作。例如,在上面的代码中,由于存在不同的VCL实例,DLL中的类型与主机中完全相同的命名类型不同。但还有很多问题。如果包不是一个可行的选择,那么您需要做更多的工作来启用插件。
type
  TForm1 = class(TForm)
    // Double-click the OnCreate in the Object Inspector Events tab. 
    // It will add this item.
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    // Add the next two lines yourself, then use Ctrl+C to
    // generate the empty HandlePopupItem handler
    FPopup: TPopupMenu;      
    procedure HandlePopupItem(Sender: TObject);
  public
    { Public declarations }
  end;

implementation

// The Object Inspector will generate the basic code for this; add the
// parts it doesn't add for you.
procedure TForm1.FormCreate(Sender: TObject);
var
  Item: TMenuItem;
  i: Integer;
begin
  FPopup := TPopupMenu.Create(Self);
  FPopup.AutoHotkeys := maManual;
  for i := 0 to 5 do
  begin
    Item := TMenuItem.Create(FPopup);
    Item.Caption := 'Item ' + IntToStr(i);
    Item.OnClick := HandlePopupItem;
    FPopup.Items.Add(Item);
  end;
  Self.PopupMenu := FPopup;
end;

// The Ctrl+C I described will generate the basic code for this;
// add the line between begin and end that it doesn't.
procedure TForm1.HandlePopupItem(Sender: TObject);
begin
  ShowMessage(TMenuItem(Sender).Caption);
end;