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

  • 主题发起人 主题发起人 白衣书生
  • 开始时间 开始时间
to zjfeng: 多谢了。
倒是没有想到能够这样用!
用override(重置)还是overload(重载)?
我小试了以下,发现编译通不过啊!
.........
public
procedure showmodal;override;
..........
提示信息如下:
[Error] Unit2.pas(14): Declaration of 'showmodal' differs from previous declaration
 
“Canvasdo
es not allow drawing”:一般是因为你在线程中直接操作VCL,没有用Synchronize()造成的。
VCL不是线程安全的,记得要用Synchronize,即使只有一句ShowMessage(),也必须用。
 
我看了一下应该是override,这个绝对没有问题,在我的软件中一直使用着
 
多谢楼上2为继续指教! 谢谢!
我再去试试!
 
说错了一点,showmodal原来的声明 是
function showmodal:integer;
所以你应该
function showmodal:integer;override;
 
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
Inherited CreateParams(Params);
Params.WndParent:=GetDesktopWindow;
end;
 
不错,不错,学习!
 
to zjfeng:多谢老兄!
showmodal的override重置过程成功执行了。
但是没有达到预期目的,也就是说悬浮窗口在其他窗口执行了这个showmodal后仍旧不是活动的窗口,不能用。

我猜想大概不是用一句 My_Form.enabled:=True;
就能解决的,
也许showmodal并不是将其他窗体都enabled:=False了吧。

我想察看一下showmodal函数的源码,没有找到! [:(]
 
to zqw0117 、zw84611 两位大虾:
用线程的也实现了,
但是没有出现预期的效果。其他窗口ShowModal后,那个用线程的悬浮窗口仍不能活动。

线程代码如下:
unit MyThread;
interface
uses
Classes,SysUtils,Windows,Forms,Unit1{悬浮窗口单元};
type
My_Thread= class(TThread)
private
{ Private declarations }
Form1 : TForm1;//这个就是悬浮窗口
protected
procedure My_Pro;
procedure Execute;
override;
end;

implementation
procedure My_Thread.My_Pro;
begin
if not Assigned(Form1) then
begin
Form1:=TForm1.Create(Application);//--------------------》悬浮窗口生成
Form1.show;
//--------------------》悬浮窗口显示
end;
end;

procedure My_Thread.Execute;
begin
Synchronize(My_Pro);
//如zw84611老兄所说,用 Synchronize()后果然没有那个canvas的错误了
end;
end.
----------
调用线程的悬浮窗口如下:
uses MyThread;
procedure Tmainform.Button4Click(Sender: TObject);
var NewThread:My_Thread;
begin
NewThread:=My_Thread.Create(False);
end;

不知代码是否存在错误,请各位大虾指教!! 谢谢!!
 
首先,如果线程内部有独立的VCL控件的话,可以不用Synchronize()过程,否则会出现停止相应
的情况。因为Synchronize过程主要是和线程外的进程VCL控件交互,而线程内的VCL控件好像
不必使用它。
另外,FQueryForm := TfrmQueryName.Create(nil);这一句在我这里编译没有任何问题,
完全通过,不过有一个细节我忽略了,就是try...finally块中我调用的是ShowModal过程,而不是
Show,这主要是我的应用类似于瑞星杀毒的邮件发送监控,只用弹出顶部窗口发送完成操作就
行了,故用了ShowModal。鉴于楼主的问题是需要进入消息循环,所以还得想想更有效的方法,不过
线程应该是比较好的,具体还得请高手看看了,我恐怕还没有想到解决办法。
 
Form1:=TForm1.Create(Application);//这一句有问题,你把Form1 Create成了Application
的子对象了,这样Form1需要接受Application的消息循环,试试这样写:
Form1:=Tform1.Create(nil);
不过我也不知道是否有效。
 
定时把这个窗口放在最上层!
 
多谢 钟启文 老兄热心帮助! 受教了! 谢谢!
to caidao:关键是如何才能这样做?
 
zqw0117 说的倒是一个办法,不过可能需要在 From1 的 OnClose 中设
Action := caFree;
否则应用程序退出的时候恐怕不会帮你释放 Form1
 
真正的解决方案:
实际上重载showmodal是没有问题的,而且源码也不长,不过有问题的是各个showmodal的窗
体都要重载,烦,我用一个新的方法
原因:实际上showmodal为什么drag zone会不动,是因为他被disabled,这一点,你可以看
看showmodal的源码或用spy++看看就知道他的属性就知道了
解决方法:
对WM_ENABLE消息进行处理,当一个窗体的enabled改变时,windows会给他发这条消息
procedure EnableChanged(var Msg: TMessage);
message WM_ENABLE;
procedure TLittlebox.EnableChanged(var Msg: TMessage);
begin
//当窗口被禁止的时候
EnableWindow(handle, true);
inherited;
end;

测试无误,我的软件一直在用这段代码!
 
to 白衣书生:
不客气!但愿能帮你解决问题。我刚刚查看了一下FlashGet和另外一个用Delphi写
的悬浮窗程序,我发现如你所说,FlashGet在ShowModal窗口 后,悬浮窗能够 移动,
但是那个Delphi写的程序就不行了!
另外,beta前辈的话非常重要,否则无法释放Form1,上面我疏忽了,忘了说,谢谢
beta前辈的提醒。
 
多谢 beta、zjfeng 大虾 和 钟兄 指教!
我继续测试!
 
不用测试了,我的代码没有问题的,我的软件 一直用这段代码,不然你下个用用好了。
http://www.mycnknow.com/srm.zip 嘻嘻
 
倒。 怎么又遇到了?
我不久前刚回答过这么一个一模一样的问题。
 
to zjfeng:
老兄的代码果然很爽,搞定。
刚才已经测试通过了! 想发帖子可是重启后登录不了,着急,现在才能登录。
多谢多谢!! [:)]

to Another_eYes大虾:
您回答的哪个帖子啊? 可否告诉一下 lid ?想学习学习! 多谢!!
我搜索了,但是全文检索好像被换成了“龙腾盛世”--http://richsearch.com/ 奇怪之极! [:(]
 
后退
顶部