Delphi 10,柏林,弹出菜单和隐藏秀

时间:2017-02-22 19:44:44

标签: delphi popupmenu delphi-10.1-berlin

在表单上,​​我有TrayIcon和PopupMenu组件。

  • 将PopupMenu分配给Form和TrayIcon。
  • 在TrayIcon的OnClick事件中,我会显示表单。
  • PopupMenu有2个项目来显示/隐藏表单。

当我运行项目时,表单显示正常。右键单击Form,弹出PopupMenu。

在TrayIcon上,左键单击显示表格确定。

在TrayIcon上,右键单击显示PopupMenu。选择“显示”项,表单显示确定。

但是,在此之后,PopupMenu不再启用了。右键单击不起作用!

3 个答案:

答案 0 :(得分:3)

从托盘图标显示PopupMenu有点棘手。 Windows实际上存在一个众所周知的问题,它会导致问题,甚至在MSDN中也有记录:

TrackPopupMenu function

  

要显示通知图标的上下文菜单,当前窗口必须是应用程序调用TrackPopupMenu或TrackPopupMenuEx 之前的前台窗口。否则,当用户单击菜单外部或创建菜单的窗口(如果可见)时,菜单不会消失。如果当前窗口是子窗口,则必须将(顶级)父窗口设置为前景窗口。

     

但是,当前窗口是前景窗口时,第二次显示此菜单时,它会出现,然后立即消失。要更正此问题,您必须强制将任务切换到名为TrackPopupMenu的应用程序。这是通过向窗口或线程发布良性消息来完成的,如以下代码示例所示:

SetForegroundWindow(hDlg);

// Display the menu
TrackPopupMenu(   hSubMenu,
                  TPM_RIGHTBUTTON,
                  pt.x,
                  pt.y,
                  0,
                  hDlg,
                  NULL);

PostMessage(hDlg, WM_NULL, 0, 0);

要在Delphi中考虑到这一点,您可以将PopupMenu.AutoPopup属性设置为false,然后在需要时调用PopupMenu.Popup()方法,例如:

procedure TForm1.FormContextPopup(Sender: TObject);
begin
  ShowPopup;
end;

procedure TForm1.TrayIcon1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbRight then ShowPopup;
end;

procedure TForm1.ShowPopup;
begin
  BringToFront;
  with Mouse.CursorPos do
    PopupMenu1.Popup(X, Y);
  PostMessage(Handle, WM_NULL, 0, 0);
end;

答案 1 :(得分:2)

我观察了PopUpMenu" AutoPopup"展会活动中的财产是假的;设置它恢复预期的行为:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    PopupMenu1: TPopupMenu;
    Show1: TMenuItem;
    Hide1: TMenuItem;
    TrayIcon1: TTrayIcon;
    procedure Show1Click(Sender: TObject);
    procedure Hide1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Hide1Click(Sender: TObject);

begin
   Hide;
   TrayIcon1.Visible := true;
end;

procedure TForm1.Show1Click(Sender: TObject);

begin
   ///////////////////
   //
   // Comment out this line and app will have OP's observed behavior
   Popupmenu.AutoPopup := true;
   ///////////////////

   Show;
end;

end.

答案 2 :(得分:1)

我在尝试你做的时遇到了同样的问题,当你隐藏表单时,form.popupmenu的值似乎变为nil,我的解决方案是添加另一个具有相同事件处理程序的popupmenu,将第一个分配给形式和第二个托盘图标,它将工作。

修改

Sertac Akyuz 感谢您注意Popupmenu.AutoPopup在隐藏表单时变为false而不是form.popupmenu变为nil