弹出模态窗体的应用程序隐藏和恢复显示的问题解决_xjjrocker的博客-程序员ITS203

技术标签: application  function  integer  api  Delphi  


    主程序是MDI风格的,在弹出很多子窗体并同时有个模态窗体的情况下,实现定时锁屏功能,锁屏后,要使得整个应用程序都最小化,当输入所凭密码后再恢复显示成最初的状态。

这个过程会有几个问题点需要解决:
1、主窗体包括子窗体可以用frmMain.Hide来隐藏
2、是否有弹出来模态窗体需要进行检测,如果有则需要抓出模态窗体的句柄Handle,通过对模态窗体的发消息,隐藏模态窗体
3、恢复主窗体用frmMain.Show来显示
4、如果模态窗体句柄存在,则恢复显示模态窗体,同样用对指定句柄发消息来实现
5、对应用程序进行restore,此步骤很关键,没有此步骤,则会导致锁屏多次后,主窗体的【最小化】按钮不起作用,这时窗体可以操作、可以最大化、可以关闭,却再也不能最小化了!这就是引用消息机制的副作用,即使你的wndproc里面含有inherited也没用,就是不最小化,原因是这样的:

在进程中,主窗体的WM_SYSCOMMAND 消息是被传递给Application 类处理的,当CmdType 为SC_MINIMIZE的时候,Application 会调用Minimize 方法:

procedure TApplication.Minimize;
begin
  if not IsIconic(FHandle) then
  begin
    NormalizeTopMosts;
    SetActiveWindow(FHandle);
    if (MainForm <> nil) and (ShowMainForm or MainForm.Visible)
      and IsWindowEnabled(MainForm.Handle) then
    begin
      SetWindowPos(FHandle, MainForm.Handle, MainForm.Left, MainForm.Top,
        MainForm.Width, 0, SWP_SHOWWINDOW);
      DefWindowProc(FHandle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
    end else
      ShowWinNoAnimate(FHandle, SW_MINIMIZE);
    if Assigned(FOnMinimize) then FOnMinimize(Self);
  end;
end;

注意这个IsIconic(FHandle),它就是问题原因的冰山一角。IsIconic 是用来检测窗体是否处于最小化状态的API。我发现,第二实例将前一实例的主窗体置前之后,这个窗体最小化调用这个方法时,每次IsIconic(FHandle) 都是True。也就是说,Application 一直认为自己是最小化的(所以不能怪wndproc里面的inherited,因为inherited起作用了)。

于是问题就比较清楚了:我们在将主窗体强行置到最前的时候,Application 并没有恢复原状态。于是在Minimize 方法中主窗体就得不到最小化的命令了。

难怪在VC 开发的程序中不会有这样的问题!因为不存在Application 的这个因素。

于是我们只要将主窗体强行置前之前,首先将Application 恢复:

if IsIconic(Application.Handle) then
begin
    DefWindowProc(Application.Handle, WM_SYSCOMMAND, SC_RESTORE, 0);
end;

或者自己调用Application.Restore;来恢复。这样就好了。

具体程序关键代码片段如下:
--------------------------------------------
procedure TfrmMain.acLockExecute(Sender: TObject);   //锁屏动作
var
  tHandle:HWND;
  function ApplicationHasModalForm:HWND; //找到模态窗体
  var
  i:integer;
  begin
    result:=0;
    for i:=0 to Screen.FormCount-1 do
    begin
      if Screen.Forms[i] is TForm then
      begin
        if fsModal in Screen.Forms[i].FormState then
        begin
          result:=Screen.Forms[i].Handle;
          break;
        end;
      end;
    end;
  end;
begin
  if LockForm <> nil then
    Exit;
  cnMain.Pause := True;
  frmMain.Hide;     //隐藏主程序
  tHandle:=ApplicationHasModalForm;//获得模态窗体句柄
  if tHandle>0 then
     ShowWindow(tHandle,SW_HIDE);    //隐藏模态窗体
  LockForm := TLockForm.Create(Application);
  LockForm.ShowModal;
  LockForm.Free;
  LockForm := nil;
  dwLastInputTick := GetTickCount;
  cnMain.Pause := False;
  frmMain.Show;    //显示主程序
  if tHandle>0 then
    ShowWindow(tHandle,SW_SHOW);   //显示模态窗体
  Application.Restore;  //恢复窗体状态,否则"最小化"可能失败
  if acNavigate.Checked then
  begin
    ShowDockForm(frmNavigate);
  end;
end;

 上面代码的加粗部分即是关键代码部分。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xjjrocker/article/details/2147334

智能推荐

python3.7怎么安装django_django-为Python 3.7 virtualenv安装mod_wsgi_weixin_39528843的博客-程序员ITS203

尝试为Python 3.7安装mod_wsgi以完成Django的设置.但是它失败并显示以下错误消息Collecting mod-wsgiUsing cached https://files.pythonhosted.org/packages/9e/37/dd336068ece37c43957aa337f25c59a9a6afa98086e5507908a2d21ab807/mod_wsgi-4....

XBL绑定组建的实例_long13131462101的博客-程序员ITS203

可以利用绑定方法创建具有复合功能的控件1.被绑定的标签常由样式表指向绑定元素定义的.xml,如: xbltest.css中#shortcutlistbutton_popup{ min-width:200px; min-height:300px; -moz-binding:url(chrome://proj/content/bindings/...

Wwise 空间音频方案_橘右京小白的博客-程序员ITS203_空间音频方案

在UE-Wwise中,有两种原生的方式可以去更新声障声笼参数值:基于射线检测 基于空间音频组件AkSpatialAudioVolume首先介绍射线检测方案。如果ak激活了声障声笼参数,由两种处逻辑会触发参数更新。调用PostEvent进行音频播放时,会进行一次计算更新,UpdateObstructionOcclusion接口中,会计算ak和listener的阻挡情况,当存在阻挡时,会基于阻挡物体的BoundingBox,继续打24根射线,检测阻挡物对ak和listener的阻挡

软件加壳的原理及实现_一节散人的博客-程序员ITS203_加壳原理

加壳的实现我是个初学者,所知有限,难免会有错误,如果有人发现了错误,还请指正 先大致说一下加壳的原理,即在原PE文件(后面称之为宿主文件)上加一个新的区段(也就是壳),然后从这个新的区段上开始运行;也就算是成功的加上了壳;下面我们就说一下具体的实现。 这个工程有两个项目,一个用来生成壳的Win32项目(dll类型),另一个是实现加壳的MFC项目; 加壳的项目界面是用MFC实现的,除了原有的类外

干货丨深度迁移学习方法的基本思路_博文视点的博客-程序员ITS203_深度神经网络的迁移系统实现思路

百度前首席科学家、斯坦福大学副教授吴恩达(Andrew Ng)曾经说过:迁移学习将是继监督学习之后的下一个促使机器学习成功商业化的驱动力。本文选自《深度学习500问:AI工程师面试宝典》,将重点介绍目前最热门的深度迁移学习方法的基本思路。限时5折▼随着迁移学习方法的大行其道,越来越多的研究人员开始使用深度神经网络进行迁移学习。与传统的非深度迁移学习方法相比,深度迁移学习直接提升了在不同任务上的学习效果,并且由于深度迁移学习直接对原始数据进行学习,所以它与非深度迁移学习方法相比有...

mysql 5.1 db2i_oracle,db2,mysql类比之一常用类似知识点_汉服资讯的博客-程序员ITS203

oracle,db2,mysql类比》作为三种数据库一个类比,目的在于通过类比,了解现在数据库相似点与异同点,同时可以帮助大家在了解一种数据库,能够迅速地学会其他数据库。初步定义为oracle,db2,mysql三种数据库,以后可能还是追加informix,sysbase,sql server等数据库。本篇作为首篇,目的是让大家对这三种数据库常用的知识点有一个感知的认识。一、常用知识点1、查看可以...

随便推点

oracle数据库和sql有什么区别,sql server 和oracle数据库的区别_Louielim087的博客-程序员ITS203

sql server 和oracle数据库的区别: 1.性能方面 两者最大的区别:就是其应用平台的差异.sql server数据库只能部署在微软的操作系统上.而oracle数据库 其不到那能够支持微软的操作系统.而且还可以支持开源的操作系统,如linux等等,正是因为oracle是在java 技术平台上开发的,所以,让其在跨平台的操作系统上运行成为了可能. 2.安全性方面 从安全性方面...

Cisco三层交换机的配置详解_看清所苡看轻的博客-程序员ITS203_sw mo tr

当公司网络规模较小、划分的VLAN比较少时,可能单臂路由就可以满足各VLAN间的通信,但是当VLAN较多、网络规模比较大时。那么使用单臂路由技术就显得有点力不从心了,这是我们就要引入三层交换机了。现在大多数新型的catalyst交换机都支持CEF(Cisco快速转发)多层交换,CEF是一种基于拓扑的转发模型,可预先将所有的路由选择信息加入到FIB( forWord information bas...

ubifs 简介_csdn_yds的博客-程序员ITS203_ubifs nor

UBIFS 是运行在ubi之上的文件系统,起源于jffs。实际上就是jffs3. 历史发展如下:jffs (journal flash file system)灵感来自于logfs。随后出现了jffs2,有了不少改进jffs2的出现为flash设备提供了很好的文件系统选择,但是存在以下问题:a):只维护了在内存中的index树,而没有吧这个树存到flash中。

计算机外存断电会丢失吗,外储存器断电后信息会丢失吗_酒业资讯的博客-程序员ITS203

大家好,我是时间财富网智能客服时间君,上述问题将由我为大家进行解答。外储存器断电后信息会丢失与否,分为以下四种情况:1、突然断电时,外存储器已经停止工作,不会丢失。2、断电时,外存储器正在运行,且信息尚未保存,就会丢失。3、断电时,外存储器正在运行系统或程序时,可能丢失(如直接电源关机,损坏系统文件等)。4、外存储器也包括ROM,如只读光盘就不会丢失。外储存器(又称:辅助存储器)是指除计算机内存及...

SpringSessionRedis配置及发现的问题_任重道远莫忘初心的博客-程序员ITS203

最近写项目,需要把session放入Redis中,来实现分布式。我本来要用Tomcat部署Redis这种方法,但是依赖于容器了。无意中发现了SpringSession,这可挺不错的,写完了发现不好用,问度娘也没弄明白,最后我写了2个demo一个springMVC的,一个Spring整合struts2的,发现SpringSession需要SpringMVC的支持。也就是说我的项目用不了了。先说说

数据分析-Matplotlib可视化工具详细介绍_i_chensihuo_888的博客-程序员ITS203

Matplotlib简介Matplotlib是受MATLAB的启发构建的。MATLAB是数据绘图领域广泛使用的语言和工具。MATLAB语言是面向过程的。利用函数的调用,MATLAB中可以轻松的利用一行命令来绘制直线,然后再用一系列的函数调整结果。Matplotlib 是一个 Python 的 2D绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形 。通过Matplotlib,...

推荐文章

热门文章

相关标签