如何检测鼠标点击一个按钮,下拉菜单
问题描述:
我的问题与答案如下在 How to create a button with drop-down menu?如何检测鼠标点击一个按钮,下拉菜单
我试图复制在左上角发现了“Office按钮”的行为的Mircosoft Office 2007用户界面;特别是在用户点击按钮的地方,弹出菜单出现并且按钮在“下”状态中被重新绘制。按钮图像保持在向下状态,直到用户单击菜单上的鼠标或表单上的其他位置或者甚至在应用程序外部。
我需要检测到这个鼠标点击,所以我可以重新绘制正常图像中的按钮,如果我使用我自己的对话框作为弹出菜单,隐藏菜单。
我正在使用D6。
感谢您的任何建议,
关心,
PhilW。
澄清:
我现在认识到,答案是琐碎当使用TPopUpMenu,已经以曾经在弹出菜单中显示的错误认识,它留给主事件的命运循环。我过去曾愉快地编码。 Wiser,有点尴尬(但朋友之间没关系)我的问题应该是更具体的,并且说:
“当我使用对话框表单来行为像TPopUpMenu时,如何检测到此鼠标单击?
对不起,我感到困惑。
答
也许我失去了一些东西,但至少一个弹出菜单,这是很容易:
procedure TForm1.FormCreate(Sender: TObject);
begin
SpeedButton1.AllowAllUp := TRUE;
SpeedButton1.GroupIndex := 1;
end;
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
CurPos: TPoint;
begin
CurPos := Mouse.CursorPos;
PopupMenu1.Popup(CurPos.x, CurPos.y);
SpeedButton1.Down := FALSE;
end;
这工作,如使用辅助消息循环中所示的弹出式菜单,它的点击外面做解雇它就像点击一个菜单项一样。
如果你想显示一个窗体而不是弹出菜单,你只需要提供一个封装函数,只有当窗体已经关闭时才会返回,类似于上面代码中的Popup()
。例如,您可以显示非模态表单,并使用SetCaptureControl()
方法处理所有鼠标事件,即使鼠标光标位于表单区域之外。
编辑:
一些代码来让你开始 - 它表明了原则,但肯定是不完整的或最优的。取而代之的是弹出式菜单的形式显示:
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
PtLeftTop: TPoint;
begin
PtLeftTop := ClientToScreen(Point(SpeedButton1.Left + SpeedButton1.Width,
SpeedButton1.Top + SpeedButton1.Height));
TForm2.ShowFormAsPopup(PtLeftTop);
SpeedButton1.Down := FALSE;
end;
形式具有下面的代码:
type
TForm2 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormDeactivate(Sender: TObject);
public
class procedure ShowFormAsPopup(ATopLeft: TPoint);
end;
// boilerplate snipped
class procedure TForm2.ShowFormAsPopup(ATopLeft: TPoint);
var
Form2: TForm2;
OldDeactivate: TNotifyEvent;
begin
Form2 := TForm2.Create(nil);
try
OldDeactivate := Application.OnDeactivate;
try
Application.OnDeactivate := Form2.FormDeactivate;
Form2.Left := ATopLeft.x;
Form2.Top := ATopLeft.y;
Form2.Show;
SetCaptureControl(Form2);
while Form2.Visible do
Application.ProcessMessages;
finally
Application.OnDeactivate := OldDeactivate;
end;
finally
Form2.Release;
end;
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
KeyPreview := TRUE;
end;
procedure TForm2.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_ESCAPE then
Visible := FALSE;
end;
procedure TForm2.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
ScreenPos: TPoint;
begin
ScreenPos := ClientToScreen(Point(X, Y));
if (ScreenPos.X < Left) or (ScreenPos.Y < Top)
or (ScreenPos.X > Left + Width) or (ScreenPos.Y > Top + Height)
then begin
Visible := FALSE;
end;
end;
procedure TForm2.FormDeactivate(Sender: TObject);
begin
Visible := FALSE;
end;
金恰恰相反,那是我。花了很长时间才能理解你的答案,直到我意识到Popup语句在(!)之后立即返回控制权。我澄清了我的问题。 – PhilW 2009-07-27 07:06:48