Delphi 单击t按钮时如何显示TPopupMenu?
我想在单击按钮时显示弹出菜单,但此过程在Delphi XE中有错误Delphi 单击t按钮时如何显示TPopupMenu?,delphi,button,cursor-position,popupmenu,Delphi,Button,Cursor Position,Popupmenu,我想在单击按钮时显示弹出菜单,但此过程在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 ; p
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 Error]Form1.pas(398):E2197常量对象不能作为var参数传递 单击按钮时,是否有更好的方式显示弹出菜单?只需执行即可
procedure TForm1.Button1Click(Sender: TObject);
var
pnt: TPoint;
begin
if GetCursorPos(pnt) then
PopupMenu1.Popup(pnt.X, pnt.Y);
end;
再讨论一下
如果出于某种原因需要使用onmoseup,您可以这样做
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;
// 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;
你的代码不起作用,因为
ClientToScreen
是带有签名的Windows API的函数
function ClientToScreen(hWnd: HWND; var lpPoint: TPoint): BOOL;
function TControl.ClientToScreen(const Point: TPoint): TPoint;
但是,还有一个带有签名的TControl.ClientToScreen
function ClientToScreen(hWnd: HWND; var lpPoint: TPoint): BOOL;
function TControl.ClientToScreen(const Point: TPoint): TPoint;
因此,如果您在一个类方法中,该类是TControl
的decentant,ClientToScreen
将引用后者。若否,则指前者。当然,这一个需要知道我们从哪个窗口转换坐标
另外,如果你申报
var mb1: TMouseButton
作为参数,则仅接受类型为TMouseButton
的变量。但是我看不出有任何理由希望您的ShowPopupMenuEx
函数具有此签名。事实上,我认为根本不需要这样一个函数
替代方案
我上面的代码将在光标位置弹出菜单。如果您需要固定相对于按钮一角的点,您可以这样做
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;
// 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;
此错误是因为您的代码调用的是Windows.ClientToScreen
函数,而不是
t控制.客户端到屏幕
功能
试试这样的
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;
或者在Tform1
类中声明您的过程ShowPopupMenuEx
,并将其工作。对于TToolButton也同样如此
(假设TToolButtonStyle
为tbsDropDown
。)
根据我的经验,我发现我更希望在单击整个按钮时显示下拉菜单,而不仅仅是下拉箭头(⯆).
为了实现这一点,根据@Andreas在上述替代方案下的代码,
只需添加Down:=True
属性,如下所示:
过程TForm1.ToolButton1Click(发送方:TObject);
开始
使用工具按钮1,客户端到屏幕(点(0,高度))执行以下操作
开始
向下:=真;
下拉菜单。弹出窗口(X,Y);
结束;
结束;
这也模拟了按钮的背景显示行为。当有t按钮时,使用Self.ClientToScreen
是相当愚蠢的。而且,我用八分钟击败了你…@Andreas试试我发布的代码,你就会明白为什么我调用Self.ClientToScreen
而不是t按钮.ClientToScreen
@RRUZ:对不起,我看不到。但我确实认为在我提交帖子八分钟后在帖子中发布所有信息的子集是不礼貌的。对不起,我感觉不到任何不同…@Andreas:你的代码使用当前光标位置,而RRUZ的代码使用按钮的左下角。因此有一个不同的e、 IMHO RRUZ的版本看起来更好。-)为什么要在shoppopumenuex()过程中使用var参数?哎呀,这是我的错误,对不起。