我想在单击按钮时显示弹出菜单,但此过程在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错误] Form1.pas(205):E2010不兼容的类型:'HWND'和'TPoint'
[DCC错误] Form1.pas(398):E2197常量对象不能作为var参数传递 [DCC错误] Form1.pas(398):E2197常量对象不能作为var参数传递
单击按钮时,show popupmenu有没有更好的方法?
答案 0 :(得分:22)
只做
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, Button1.Height)) do
PopupMenu1.Popup(X, Y);
end;
答案 1 :(得分:5)
此错误是因为您的代码正在调用Windows.ClientToScreen
函数而不是
TControl.ClientToScreen
功能
尝试这样的事情
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;
或在ShowPopupMenuEx
课程中声明您的Tform1
程序,然后就可以了。
答案 2 :(得分:0)
(假设TToolButton Style
是tbsDropDown
...)
根据我的经验,我发现很多时候,我宁愿单击整个按钮时显示的下拉菜单,而不仅仅是 下拉箭头 (⯆)。
要实现此目标,请根据上面An Alternative
下@Andreas的代码,
只需添加Down := True
属性,如下所示:
procedure TForm1.ToolButton1Click(Sender: TObject);
begin
with ToolButton1, ClientToScreen(Point(0, Height)) do
begin
Down := True;
DropdownMenu.Popup(X, Y);
end;
end;
这也模拟了按钮背景的显示行为。