How to show TPopupMenu when clicking on TButton?

I want to show popupmenu at the click of a button, but this procedure has an error in Delphi XE.

procedure ShowPopupMenuEx(var mb1:TMouseButton;var X:integer;var Y:integer;var pPopUP:TPopupMenu); var popupPoint : TPoint; begin if (mb1 = mbLeft) then begin popupPoint.X := x ; popupPoint.Y := y ; popupPoint := ClientToScreen(popupPoint); //Error Here pPopUP.Popup(popupPoint.X, popupPoint.Y) ; end; end; procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer); begin ShowPopupMenuEx(button,Button1.Left,Button1.Top,PopupMenu1); //Error Here end; 

when the click button shows this error:

[DCC Error] Form1.pas (205): E2010 Incompatible types: "HWND" and "TPoint"
[DCC error] Form1.pas (398): E2197 A constant object cannot be passed as a var parameter

[DCC error] Form1.pas (398): E2197 Constant cannot be passed as var parameter

Is there a better way to show popupmenu at the click of a button?

+4
source share
2 answers

Just do

 procedure TForm1.Button1Click(Sender: TObject); var pnt: TPoint; begin if GetCursorPos(pnt) then PopupMenu1.Popup(pnt.X, pnt.Y); end; 

Some more discussions

If for some reason you need to use OnMosuseUp , you can do

 procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var pnt: TPoint; begin if (Button = mbLeft) and GetCursorPos(pnt) then PopupMenu1.Popup(pnt.X, pnt.Y); end; 

Your code does not work because

  • ClientToScreen is a Windows API function with a signature

     function ClientToScreen(hWnd: HWND; var lpPoint: TPoint): BOOL; 

    But there is also a TControl.ClientToScreen with a signature

     function TControl.ClientToScreen(const Point: TPoint): TPoint; 

    Therefore, if you are in a class method, the class being the TControl ClientToScreen , ClientToScreen , will refer to the latter. If not, this will apply to the first. And this one, of course, must know in which window we must convert the coordinates from!

  • Also, if you announce

     var mb1: TMouseButton 

    as a parameter, then only a variable of type TMouseButton will be accepted. But I see no reason why you need this signature of your ShowPopupMenuEx function. In fact, I do not see the need for such a function at all ...

Alternative

My code above will appear in the pos cursor menu. If you need to correct a point relative to one corner of the button, instead you can do

 // Popup at the top-left pixel of the button procedure TForm1.Button1Click(Sender: TObject); begin with Button1.ClientToScreen(point(0, 0)) do PopupMenu1.Popup(X, Y); end; // Popup at the bottom-right pixel of the button procedure TForm1.Button1Click(Sender: TObject); begin with Button1.ClientToScreen(point(Button1.Width, Button1.Height)) do PopupMenu1.Popup(X, Y); end; // Popup at the bottom-left pixel of the button procedure TForm1.Button1Click(Sender: TObject); begin with Button1.ClientToScreen(point(0, Button1.Height)) do PopupMenu1.Popup(X, Y); end; 
+17
source

this error occurs because your code calls the Windows.ClientToScreen function instead of the TControl.ClientToScreen function

try something like this

 procedure TForm6.Button2Click(Sender: TObject); var pt : TPoint; begin pt.x := TButton(Sender).Left + 1; pt.y := TButton(Sender).Top + TButton(Sender).Height + 1; pt := Self.ClientToScreen( pt ); PopupMenu1.popup( pt.x, pt.y ); end; 

or declare your ShowPopupMenuEx procedure inside your Tform1 class and you will work.

+4
source

All Articles