Search code examples
delphipopuppositioncontextmenufiremonkey

A problem with TPopupMenu positioning in Firemonkey Delphi 10.4


My previous question on this problem was poorly formatted so I decided to delete the previous question and repropose it with a better (and smaller) example.

I'm experiencing a very strange behavior of the TPopupMenu component in Firemonkey (Delphi 10.4). To simulate the problem, I have created a FORM and I have placed:

  1. a TPopupMenu component on the form and I have assigned a couple of items
  2. a TLayout on it (the FORM in Firemonkey does not have a property PopupMenu)
  3. a TPanel, for the same reason, with the PopupMenu1 as property
  4. a Tbutton in the center of the Form Well, it happens that only a few times of the Right-Button press the pop up menu appears, and when it does, it is far away from the mouse cursor. Is there any assignment which must be done before to "popup" the popup? What am I doing wrong? I searched on the Embarcadero documentation without success. I have prepared a bit of code.

This is the code of the unit:

unit MainUnitTestPopup;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts, FMX.Menus;

type
  TForm2 = class(TForm)
    Layout1: TLayout;
    Button1: TButton;
    PopupMenu1: TPopupMenu;
    MenuItem1: TMenuItem;
    MenuItem2: TMenuItem;
    Panel1: TPanel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.fmx}

procedure TForm2.Button1Click(Sender: TObject);
begin
   Application.Terminate;
end;

end.

and this is the textcode of the FORM

object Form2: TForm2
  Left = 0
  Top = 0
  Caption = 'Form2'
  ClientHeight = 480
  ClientWidth = 640
  FormFactor.Width = 320
  FormFactor.Height = 480
  FormFactor.Devices = [Desktop]
  DesignerMasterStyle = 0
  object Layout1: TLayout
    PopupMenu = PopupMenu1
    Size.Width = 177.000000000000000000
    Size.Height = 480.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 0
    object Button1: TButton
      Position.X = 216.000000000000000000
      Position.Y = 168.000000000000000000
      Size.Width = 185.000000000000000000
      Size.Height = 65.000000000000000000
      Size.PlatformDefault = False
      TabOrder = 0
      Text = 'CLICK ME!'
      OnClick = Button1Click
    end
  end
  object Panel1: TPanel
    PopupMenu = PopupMenu1
    Position.X = 176.000000000000000000
    Position.Y = 232.000000000000000000
    Size.Width = 465.000000000000000000
    Size.Height = 257.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 2
  end
  object PopupMenu1: TPopupMenu
    Left = 520
    Top = 56
    object MenuItem1: TMenuItem
      Text = 'MenuItem1'
      object MenuItem2: TMenuItem
        Locked = True
        Text = 'MenuItem2'
      end
    end
  end
end

and this is the code of the project:

program TestPopupProject;

uses
  System.StartUpCopy,
  FMX.Forms,
  MainUnitTestPopup in 'MainUnitTestPopup.pas' {Form2};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end.

I hope this time I've been able to create a correctly formatted question. Thank you for your help (and pls excuse my lack of expertise in asking).


Solution

  • When I try it (also with Delphi 10.4), the popup menu opens at the cursor position as expected.

    However, it only appears when right-clicking on the panel, because, the TLayout ignores the mouse click. To change this, check the HitTest box in the object inspector. Then you can pop up the menu on the TLayout also.

    In addition, if you want the pop-up menu to work anywhere on the form, you should have the TLayout fill the form. This is best achieved by setting it's Align property to Client or Contents. Although even then it still won't work when right-clicking on another control, such as the button (unless you also set the control's PopupMenu property to the popup menu).