to 沧海:
我基本上是这样做的,问题是浮动窗口显示出来,主窗口立即失去焦点。
我的想法是点击某一个按钮,然后下拉出浮动窗口(就跟combobox的下拉一样),这时焦点
在浮动窗口上,可对浮动窗口上的控件进行操作,并且主窗口看上去是没有失去焦点的(就
跟combobox的下拉一样),这是如果在主窗口上面点击鼠标,即触发浮动窗口的OnDeactivate
事件,可在此事件处理中隐藏浮动窗口。
各位不嫌弃的话,可看看小弟的代码:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, ComCtrls, StdCtrls;
type
TFormMain = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
FormMain: TFormMain;
implementation
uses unit2;
{$R *.dfm}
procedure TFormMain.Button1Click(Sender: TObject);
var
p: tpoint;
begin
p := CalcDropPos(Button1, PopupForm, mouse.CursorPos.X, mouse.CursorPos.y);
PopupForm.Left := p.X;
PopupForm.top := p.y;
PopupForm.Show;
//保持按钮下沉状态,等待关闭
while (PopupForm.Visible) do
Application.ProcessMessages;
end;
end.
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TPopupForm = class(TForm)
Panel1: TPanel;
procedure FormDeactivate(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
{ Private declarations }
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure WMActivateApp(var Message: TWMActivateApp); message WM_ACTIVATEAPP;
public
{ Public declarations }
end;
function CalcDropPos(Control, PopControl: TControl; X, Y: integer): TPoint;
var
PopupForm: TPopupForm;
implementation
uses unit1;
{$R *.dfm}
{ TForm2 }
function CalcDropPos(Control, PopControl: TControl; X, Y: integer): TPoint;
begin
Result := Point(0, Control.Height);
Result := Control.ClientToScreen(Result);
if Result.X < 0 then Result.X := 0;
if Result.Y < 0 then Result.Y := 0;
if Result.X + PopControl.Width > Screen.Width then Result.X := Screen.Width - PopControl.Width;
if Result.Y + PopControl.Height > Screen.Height then Result.Y := Screen.Height - PopControl.Height;
end;
procedure TPopupForm.CreateParams(var Params: TCreateParams);
begin
inherited;
with Params do
begin
WndParent := GetDesktopWindow;
Style := WS_CLIPSIBLINGS or WS_CHILD; //如果加上这行,则popupform无法得到焦点,如果删除这行,则主窗口没有了焦点,失败!
ExStyle := WS_EX_TOPMOST or WS_EX_TOOLWINDOW;
WindowClass.Style := CS_DBLCLKS or CS_SAVEBITS;
end;
end;
procedure TPopupForm.WMActivateApp(var Message: TWMActivateApp);
begin
if not Message.Active then Close;
end;
procedure TPopupForm.FormDeactivate(Sender: TObject);
begin
Hide; //失去焦点立即隐藏
end;
procedure TPopupForm.FormActivate(Sender: TObject);
begin
self.SetFocus;
end;
end.