delphi – 如何在单击TButton时显示TPopupMenu?

我想在单击按钮时显示弹出菜单,但此过程在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;

当点击按钮显示错误时:

[DCC Error] Form1.pas(205): E2010 Incompatible types: ‘HWND’ and ‘TPoint’
[DCC Error] Form1.pas(398): E2197 Constant object cannot be passed as var parameter
[DCC Error] Form1.pas(398): E2197 Constant object cannot be passed as var parameter

当点击按钮时,是否有更好的方式来显示弹出菜单

解决方法

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

还有一些讨论

如果由于某种原因需要使用OnMosuseUp,则可以这样做

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;

你的代码不起作用,因为

> ClientToScreen是具有签名的Windows API的功能

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

但是,还有一个带签名的TControl.ClientToScreen

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

因此,如果你是一个方法,该类是TControl的后代,ClientToScreen将引用后者.如果没有,它将参考前一个.当然,这一个需要知道我们要从哪个窗口转换坐标!
>另外,如果你申报

var mb1: TMouseButton

作为参数,只接受TMouseButton类型的变量.但我看不出你为什么想要这个ShowPopupMenuEx函数的签名.事实上,我认为根本不需要这样的功能……

替代

上面的代码将弹出光标位置的菜单.如果你需要相对于按钮的一个角来固定点,你可以这样做

// 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,Y);
end;

相关文章

 从网上看到《Delphi API HOOK完全说明》这篇文章,基本上都...
  从网上看到《Delphi API HOOK完全说明》这篇文章,基本上...
ffmpeg 是一套强大的开源的多媒体库 一般都是用 c/c+&#x...
32位CPU所含有的寄存器有:4个数据寄存器(EAX、EBX、ECX和ED...
1 mov dst, src dst是目的操作数,src是源操作数,指令实现的...