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