熟悉windows api的大虾请进,关于浮动窗口 (100分)

  • 主题发起人 主题发起人 Adnil
  • 开始时间 开始时间
A

Adnil

Unregistered / Unconfirmed
GUEST, unregistred user!
如何用form实现跟toolbar97中的toolwindow97浮动时候的类似效果?
即,浮动窗口显示的时候,浮动窗口和主form都是active的,
是否能够dock,是否有标题栏则无所谓。

才疏学浅,未能研究透tabctoolwindow和ttoolwindow97的源代码,特别是窗口样式部分。
 
>>"浮动窗口和主form都是active的,"
浮动窗口的标题只不过是深蓝色的而已,能说明是active的吗?
 
不可能都active吧?
你弄一个bsNone然后总在最前的窗体SetWindowPos()就是了.
呵呵,蒙人的.
 
请仔细观察一下再发言,跟delphi中的工具窗口有区别的。
 
1.让form1透明。
form1.WindowState:=wsMaximized;
form1.TransparentColor :=true;
form1.Color :=clred;
form1.TransparentColorValue :=clred;
2.form1上放两个panel,并在他们的mousedown,mouseover,mouseup编写相应代码使得panel1,panel2,
可以在运行时移动。
3。运行程序,则看到屏幕上的两个panel都是active的。
 
呵呵 不用 API 也可以呀!
procedure TFormDrop.Createparams(var Params:TCreateParams);

begin

Inherited CreateParams(Params);

With Params do

begin

EXStyle:=ExStyle or WS_EX_TOPMOST OR WS_EX_ACCEPTFILES or WS_DLGFRAME

wndParnet:=GetDesktopWindow; //关键一行,用SetParent都不行!!

end;

end;
 
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.

 
用消息转换不就可以解决了吗?

处理浮动窗口的时候,向 MainForm Dispatch Messages!
 
to ddev:
能再给点提示吗? 这点我也想到过,但不知道具体怎么做。
 
1、MSO 中的窗口激活是假象,事实上,如果你拉出格式工具栏,然后击取缩放比,
主窗口立即失去焦点!但微软在这方面做得到家了,以至于我们看不出,但最起码
它不可能打破“只能有一个窗口接受焦点”的真言!
2、激活 FloatBox 时,焦点将视你的处理而不同:SetWindowPos() 就可以做到这一
点:显示窗口而不激活;
3、FloatBox 必须 CaptureMouse(),并在鼠标事件中处理,这不用我说了吧。在主
窗口中也必须处理 Mouse 事件,以便在适当的时候能够显示 FloatBox(用 SetWindowPos()).

如果采用消息轮询太繁杂而且效率低,你可以建立一个 ActionList, 利用 Action 的
轮询来完成。
 
看了半天理论的东西,还是甚不明白,有那位兄弟有示例代码?
 
我看你想做得是不是象 ComboBox 一样得东东呀?

你看看你想要得是不是我说的这个

外观和功能基本上和 ComboBox 一样
但是下拉出来的是一个 Panel
当然 Panel 上可以有 你想要的东东了
当 控件 失去 焦点 下拉的界面 隐藏。

如果是这个东东 我好像在那里 见过,等我找找先。
 
基本上类似COMBOBOX,但是外观可能是一个BUTTON,事实上我想让下拉出来的控件和
未下拉的控件相对独立,例如一个是我们新创建的TPopupControl,一个是现有的TButton
那么可以在Button.OnClick事件中写
with TPopupControl.Create do
begin
....
Popup(Button1);
end;
 
看看 TInplaceEdit 的实现,很清楚。
 
是 DBGrid 的 TDBGridInplaceEdit。
 
如果我没理解错你的意思,用下面两行应该可以实现:
SetWindowPos(Form2->Handle, HWND_TOPMOST, Pos.x, Pos.y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_SHOWWINDOW);
SetCapture(Form2->Handle);
 
xg:
不行,SetWindowPos显出出来的只能是一个空的窗体,上面的控件全部都不能出来。
写个小程序测试一下就知道了,两个form,一个button。
 
请看
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1346084
功能强大的停靠控件,可以满足你的停靠要求
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
586
import
I
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部