也許我失去了一些東西,但至少一個彈出菜單,這是很容易:
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