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;
source share