源起:

近期所介入的几个项目中,最后视频生成窗体,为一模态对话框。因生成时间可能较长,所以其窗体可以最小化,它最小化时同时最小化主程序,唤醒时主程序再复原。

代码亦是8年前本人所写,一直那样用了,也没什么不妥,但总感觉显示效果有优化空间,回头看看当初代码少了些简练。于是用些时间做些验证,寻得相对好点的优化方案。

1、最初实现:

方式是接管模态窗体WM_SYSCOMMAND消息,拦截SC_MINIMIZE窗体最小化消息值进行处理,代码如下:

type
TfrmModal = class(TForm)
Edit1: TEdit;
private
{ Private declarations }
procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND; ... procedure TfrmModal.WMSysCommand(var Msg: TWMSysCommand);
begin
if Msg.CmdType = SC_MINIMIZE then
Application.Minimize
else
inherited;
end;

此代码工作效果,如下动画:

它有两个问题:

i. 任务栏唤起时,对话框直接显示出来,然后才是主窗体从任务栏上动画出来。

ii. 显示出来后,焦点没有落在它身上,需要点击下主窗体触发,焦点才会移到它上面。

这就是它的瑕疵。可是如何优化呢?

反复调整消息处理次序,并抓取在此过程中它的系统消息,终于找到一个相对好点的方案,如方案2.

2、方案优化

与1大同小异,调整WM_SYSCOMMAND消息处理函数处理机制,并加入WM_SHOWWINDOW消息处理,代码如下:

type
TfrmModal = class(TForm)
Edit1: TEdit;
private
{ Private declarations }
procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
procedure WMShowWindow(var Msg: TWMShowWindow); message WM_SHOWWINDOW; ... procedure TfrmModal.WMShowWindow(var Msg: TWMShowWindow);
begin
inherited;
if Self.WindowState = wsMinimized then
begin
Self.WindowState := wsNormal;
Application.BringToFront;
end;
end; procedure TfrmModal.WMSysCommand(var Msg: TWMSysCommand);
begin
inherited;
if Msg.CmdType = SC_MINIMIZE then
Application.Minimize;
end;

因为没有忽略SC_MINIMIZE消息,此窗体亦被最小化,那么在WM_SHOWWINDOW消息中,对它重唤起。

效果如下图:

两图对比可见,方案1之两点问题,完美解决。

Delphi: 模态窗体最小化的更多相关文章

  1. delphi模态窗体最小化会隐藏的问题

    在使用delphi创建模态窗体的时候最小化窗体会导致最小化的窗体不可见,再次点击主窗体才会显示. 在这个模态窗体中增加以下函数 procedure WmSysCommand(var msg: TMes ...

  2. Delphi 7下最小化到系统托盘

    在Delphi 7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本.定义如下: 123456789   _NOTIFY ...

  3. Delphi 7下最小化到系统托盘(主要是WM_TRAYMSG和WM_SYSCOMMAND消息)

    在Delphi 7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本.定义如下: 123456789   _NOTIFY ...

  4. Windows 窗体最小化和隐藏的区别及恢复

    应用程序有托盘图标,窗体最小化或者隐藏窗体时,点击托盘图标需要恢复窗体显示,并且恢复之前的现实状体,正常大小或者最大化显示.例如:最大化显示窗体时,点击最小化按钮,窗体最小化,点击托盘图标将最大化显示 ...

  5. WPF实现窗体最小化后小图标在右边任务栏下

    一 基本功能 1. 这里是用 NotifyIcon 控件来实现,但 WPF 下没有 NotifyIcon  控件,怎么办,用 WinForm 下的呗. 先引用  .NET 自带的两个程序集 Syste ...

  6. c# 窗体最小化后截图实现

    我们知道,当我们需要对Control进行截图时,我们可以使用Control.DrawToBitmap()进行截图, 那么问题来了,当我们的窗体最小化了,我们还怎么截图呢? 当窗体最小化的时候,我们知道 ...

  7. WinForm实现窗体最小化后小图标在右边任务栏下

    一 基本功能1.  首先新建一个窗体,然后拖入一个名为 NotifyIcon 的控件,名字我没有改,就那个名字 2. 我的应用程序下有些图标文件,这里我用这个图标,我选择 013.ico 3. 选择 ...

  8. delphi将程序最小化至右下角

    程序新手,如果有不恰当的地方,请大家帮忙改正! 1.下载并安装Raize.v5.5控件,delphi版本为:delphi 7.0. 2.添加RzTrayIcon控件.PopupMenu控件至窗体上. ...

  9. Winform 窗体最小化隐藏在桌面右下角:转

    ICO文件要放到 bin\Debug 下 1.给主窗体添加 NotifyIcon 控件 2.窗体加载事件里 private void MainF_Load(object sender, EventAr ...

随机推荐

  1. WDA-6-EP系统管理/内容管理/用户管理

    主要是将EP端系统管理.内容管理.用户管理相关内容进行下梳理. 1.系统管理 1.1系统前景 1.2对象锁定 解锁相关对象 2.内容管理 2.1基本介绍 门户桌面-组件: 四大内容: iViews:可 ...

  2. vue:vue引入组建的多种写法

    vue的路由组件中,引入模块的两种写法:(@等价于..)死的写法:不是按需加载1:import Index from '@/components/Index'(import Index from '. ...

  3. python语言中的数据类型

    一.内存管理 1.python解释器的垃圾回收机制 垃圾:当一个值上没有人绑定任何变量名时(当引用计数为0),该值就是一个垃圾. python解释器运行时会检测值的引用计数,当引用计数=0该值会被清除 ...

  4. PHP对redis操作详解

    /*1.Connection*/$redis = new Redis();$redis->connect('127.0.0.1',6379,1);//短链接,本地host,端口为6379,超过1 ...

  5. HTML 样式兼容不同设备类型

    在项目中遇到在屏幕上显示的效果和打印时显示的效果不同,可以使用media属性来指定用于不同的媒介时使用的样式. media属性值: 值 描述 screen 计算机屏幕显示(默认) tty 电传打字机以 ...

  6. [CI]CodeIgniter快速开发指南

    ---------------------------------------------------------------------------------------------------- ...

  7. [原创]HTML 用div模拟select下拉框

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML xmlns=" ...

  8. easyui中的几个问题

    easyui中的tree,采用url参数读取json,无法显示.有可能是vs的IIS不支持,$.ajax 原因待测试,有知道的朋友也可以贴代码,我解决的一个办法是 $(function () { $. ...

  9. C# 图像处理: 获取当前活动窗口句柄,获取窗口大小及位置

    需调用API函数 需在开头引入命名空间 using System.Runtime.InteropServices; 获取当前窗口句柄:GetForegroundWindow() [DllImport( ...

  10. Android开发最佳实践《IT蓝豹》

    Android开发最佳实践   移动开发Android经验分享应用GoogleMaterial Design 摘要:前 段时间,Google公布了Android开发最佳实践的一系列课程,涉及到一些平时 ...