关于“悬浮窗口”---有其他Form.ShowModal后就不灵了。(150分)

  • 主题发起人 主题发起人 白衣书生
  • 开始时间 开始时间

白衣书生

Unregistered / Unconfirmed
GUEST, unregistred user!
悬浮窗口已经搞定了--可以在最前,也可拖动。
当有其他窗口ShowModal的时候,悬浮窗口就失灵了,虽然在最前,但不能拖动了。
由于需要,必须使用Showmodal,那位大虾有解决办法,
使“悬浮窗口”真正象蚂蚁或小车的悬浮窗口那样,在其他窗口ShowModal的时候也可以拖动使用?
察看了http://www.delphibbs.com/delphibbs/dispq.asp?lid=279911 后也没有解决办法。
 
试验一下 下面的家伙。
private
procedure CreateParams(var Params: TCreateParams);
override;
public
end;

// 始终在最上层即使最小化所有窗体
procedure TFrmMain.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.ExStyle := Params.ExStyle or WS_EX_TOPMOST or WS_EX_TOOLWINDOW;
Params.WndParent := 0;
end;
 
to 人在昆明:
谢谢及时回复。
这样不行的。这样只是做了一个悬浮窗口,当有其他的窗体showmodal时,悬浮窗口就不灵了。
关键showmodal的时候是模态窗体,其他窗体就不能响应了,只能处理showmodal的窗体事件。
这是Windows决定的。
 
即然是 ShowModal 其它窗体就失灵了。这好像没有办法的吧
楼上这位在回答什么呢? 疑惑???
 
to shuszj:
谢谢。
正如您老兄所说的“是 ShowModal 其它窗体就失灵了”。

但是老兄不妨看看蚂蚁或Flashget的悬浮窗体,当有其他窗体ShowModal的时候,它还可以用。

难道它们的“ShowModal”状态是假的?是模拟的?
望有经验的大虾回复。 谢谢。
 
可能问题在于被ShowModal的窗体是相对于调用它的窗体而ShowModal的,若
该窗体是相对于系统而ShowModal的也许就可以了,建议考虑SetWindowPos这个
API。
 
但我觉那个是调用另外一个DLL的窗体来实现,而不是在同一个工程编译出来的程序
 
我认为:当有其他的窗体showmodal时,是无法操纵悬浮窗口的。
 
to Zhenyu Xia:多谢!
用了SetWindowPos(handle,HWND_TopMost,0,0,0,0,SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
也是不行的。
to shuszj:多谢!
有可能如您所说的那样,悬浮窗口和主窗口不在同一个工程中。
象DLL窗体,我去试试,但这样处理起来肯定会麻烦很多。
to tata1:您看看蚂蚁的,可以“实现”啊。
 
建议将您的悬浮窗口做到线程里面,可以避免这样的情况。
我曾经将类似的窗口做到线程里面,注意要在线程的Execute中创建窗体,可以完全不用
理会主窗口的操作限制。
 
to zqw0117:
多谢老兄指点!
听到线程感觉到高深。您有没有代码或Demo可供学习? 多谢了!
 
请等等,我得翻翻硬盘了。
 
好的。
感谢老兄热心帮助。 [:)]
 
unit MyThread;
interface
uses
SysUtils,Classes, QueryName{这个是悬浮窗口的定义单元}, Windows;
type
TMyThread = class(TThread)
private
{ Private declarations }
FQueryForm : TfrmQueryName;//这个就是悬浮窗口
protected
procedure Execute;
override;
public
end;

implementation
procedure TMyThread.Execute;
begin
{ Place thread code here }
FQueryForm := TfrmQueryName.Create(nil);
try
//做你想做的事情,可以等待拖拽操作或者任何你需要的操作,当接到Terminate为true后就跳出结束
finally
FQueryForm.Free;
end;
end;

 
是多线程问题
 
注意,悬浮窗口必须使用
procedure TFrmMain.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.ExStyle := Params.ExStyle or WS_EX_TOPMOST or WS_EX_TOOLWINDOW;
Params.WndParent := 0;
end;
 
OK! 多谢指点!
我去试试!
-----------------
葵花宝典中是这样写的:
begin
Inherited CreateParams(Params);
With Paramsdo
begin
EXStyle:=ExStyle or WS_EX_TOPMOST OR WS_EX_ACCEPTFILES or WS_DLGFRAME;
WndParent:=GetDesktopWindow;
//关键一行,用SetParent都不行!!
end;
end;
 
WndParent:=GetDesktopWindow;
这一句和
Params.WndParent := 0;
效果一样
 
实际上是这样的,当一个form showmodal时,就将其他这个进程内的form的enabled设为false
,所以,你可以重载showmodal,然后,将悬浮窗的enabled设为true就可以了
代码类似
procedure aform.showmodal;//override;
begin
inherited;
dragzone.enabled:=True;
end;
就可以了
 
to zqw0117:
老兄,我新建了一个线程对象,按照你所说的写。
跟踪调试,运行到这句时有问题--
FQueryForm := TfrmQueryName.Create(nil);
提示说“Canvasdo
es not allow drawing”,不允许重绘,何故?
 
后退
顶部