delphi模态窗体突然不模态了

我今天在做项目的时候,也遇到这个问题了,问题就出在我调用的代码里,同事写的代码中有    Application.MainForm.Enabled:= true;这样一句,这样就使得我原理模态的窗体不能够模态了。具体的原理,请参照下面的解释,这是摘自另外的博客,感谢原作者。





问题描述

  昨天同事修改一个bug,请我审查代码时我发现这个bug很有意思,值得深入研究一下。

  问题是这样的,弹出一个模态窗口后,在窗口内切换树节点,发现主窗口也可以接受鼠标和键盘消息了——模态窗口不模态了

  跟踪发现,在窗口内切换树节点会间接调用到进度条窗口(我们自己写的一个窗口),ShowProgress时会调用Application.MainForm.Enabled := False,HideProgress是会调用Application.MainForm.Enabled := True,问题就出现在这个地方。

ShowModal实现

复制代码
TCustomForm.ShowModal begin //... 
  WindowList := DisableTaskWindows(0); 
  Show;
  SendMessage(Handle, CM_ACTIVATE, 0, 0); repeat Application.HandleMessage; if Application.Terminated then ModalResult := mrCancel else if ModalResult <> 0 then CloseModal; until ModalResult <> 0; //... end; DisableTaskWindows begin //... EnumThreadWindows(GetCurrentThreadID, @DoDisableWindow, 0); //... end DoDisableWindow begin //... EnableWindow(Window, False);  
  //... end
复制代码

  ShowModal的实际上只让模态接收键盘和鼠标信息,而禁止其他的窗口接收键盘和鼠标消息,这是通过调用EnableWindow这个Windows API实现的。

SetEnabled实现

复制代码
TControl.SetEnabled begin //...
  Perform(CM_ENABLEDCHANGED, 0, 0) //... end TWinControl.CMEnabledChanged begin //... EnableWindow(FHandle, Enabled) //... end
复制代码

  当调用Application.MainForm.Enabled := True时就会使得MainForm的可以接收消息了,之前的模态窗口就不再模态了。

  修改bug的方法:判断Application.ModalLevel > 0是否为真,为真的时候就不在做上述调用。

Windows API

1、EnableWindow:该函数允许/禁止指定的窗口或控件接受鼠标和键盘的输入,当输入被禁止时,窗口不响应鼠标和按键的输入,输入允许时,窗口接受所有的输入。

2、IsWindowEnabled:用于判断指定的窗口是否允许接受键盘或鼠标输入。

3、EnumThreadWindows枚举所有与一个线程相关联的非子窗口,办法是先将句柄传送给每一个窗口,随后传送给应用程序定义的回调函数。EnumThreadWindows函数继续直到所有窗口枚举完为止或回调函数返回FALSE为止。

VCL:DisableTaskWindows:{ EnumThreadWindows(GetCurrentThreadID, @DoDisableWindow, 0); } //DoDisableWindow为回调函数

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25990299/viewspace-1839978/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/25990299/viewspace-1839978/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值