源起:

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

代码亦是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. 使用linux的shell脚本实现在当前行重复动态显示时间等字符串信息(不另起新行)

    ###本脚本在Suse11sp2当中验证正确 #!/bin/sh )) do echo -ne "\r$(date)" sleep 0.3 done ###关键在 echo 的 & ...

  2. UI5-学习篇-3-Local SAP WEB IDE下载

    1.下载地址 https://tools.hana.ondemand.com/#sapui5 有两个版本,针对各自系统环境选择对应的个人版本下载后解压. 个人版:个人试用 生产版:在云平台SCP付费订 ...

  3. Delphi TMemoryStream写入到字符串和字符串写入到流

    一.TMemoryStream数据写入到字符串里 var lvStream:TMemoryStream; s:AnsiString; p: PAnsiChar; begin lvStream:= TM ...

  4. 3.有关于Python列表简述

    一..title() [让所选择的列表元素的第一个字母大写] test = ['no1','No2','No3','No4'] book = "This My " + test[0 ...

  5. 将IP地址字符串转为32位二进制

    def str2bin(s): temp = s.split('.') result = '' for i in range(len(temp)): temp[i] = str(bin(int(tem ...

  6. 2008-03-18 22:58 oracle基础知识小结

    oracle 数据类型: 字段类型                 中文说明                                                  限制条件         ...

  7. 第六次Scrum冲刺

    第六次Scrum冲刺 1.成员今日完成情况 队员 今日完成任务 刘佳 前端构建 李佳 后端设计 周世元 数据设计 杨小妮 博客编写 许燕婷 管理团队当日及次日任务 陈水莲 性能测试用例设计 曾丽丽 性 ...

  8. Constructor构造方法

    我们写一个car类,并写一个无参构造方法. public class Car { int speed; //构造方法名字和 类一致 区分大小写 不需要写返回值 和参数列表 public Car(){ ...

  9. Spring3.0学习1.2(使用annotation)

    使用annotation 首先 xml文件更改  新加xslt <?xml version="1.0" encoding="UTF-8"?> < ...

  10. ArcGIS案例学习笔记2_1_山顶点提取最大值提取

    ArcGIS案例学习笔记2_1_山顶点提取最大值提取 计划时间:第二天上午 目的:最大值提取 教程:Pdf page=343 数据:chap8/ex5/dem.tif 背景知识:等高线种类 基本等高线 ...