Just do
procedure TForm1.Button1Click(Sender: TObject);
var
pnt: TPoint;
begin
if GetCursorPos(pnt) then
PopupMenu1.Popup(pnt.X, pnt.Y);
end;
Some more discussion
If you for some reason 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 doesn't work because
ClientToScreen
is a function of the Windows API with signature
function ClientToScreen(hWnd: HWND; var lpPoint: TPoint): BOOL;
But, there is also a TControl.ClientToScreen
with signature
function TControl.ClientToScreen(const Point: TPoint): TPoint;
Hence, if you are in a class method, the class being a decendant of TControl
, ClientToScreen
will refer to the latter one. If not, it will refer to the former one. And this one, of course, needs to know which window we are to transform coordinates from!
Also, if you declare
var mb1: TMouseButton
as a parameter, then only a variable of type TMouseButton
will be accepted. But I cannot see any reason why you would like this signature of your ShowPopupMenuEx
function. In fact, I see no need for such a function at all...
An Alternative
My code above will popup the menu at the cursor pos. If you need to fix the 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;