CB的Form最小化时无动画的原因

问: 我现在也搞不懂,甚至认为无法让CB的主窗口有动画的效果。 因为在任务条上的按钮所代表的窗口是Application窗口,而不是 Project所选定的Mainform。如果强行让Mainform动态地Minimize, 就会最小化到桌面的左下角去了。

答:

我基本上同意你的看法。Delphi & BCB 中的的主窗口都是TApplication,一般情况下,这个窗口居于屏幕中间,大小为0x0。底部TaskBar上的按钮

也是TApplication窗口。应用程序的主窗口如TForm1,不是TApplicaiton的子窗口,但他不具有WS_EX_APPWINDOW的属性,所以不在TaskBar上产生 Button。当最小化的时候,由于TApplication窗口是0x0的,所以如果有动 化会很难看,所以VCL中采用SystemParametersInfo这个API使得最小化时 TApplication窗口无动化。至于TForm1,因为底部Taskbar上的Button不是 他的,所以VCL中直接HIDE了TForm1。这样,使得整体上看起来无动化。

可以在VCL的源码forms.pas中发现如下代码:

procedure TApplication.Minimize;
begin
if not IsIconic(FHandle) then
begin
NormalizeTopMosts;
SetActiveWindow(FHandle);
ShowWinNoAnimate(FHandle, SW_MINIMIZE);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
if Assigned(FOnMinimize) then FOnMinimize(Self);
end;
end;
procedure TApplication.Restore;
begin
if IsIconic(FHandle) then
begin
SetActiveWindow(FHandle);
ShowWinNoAnimate(FHandle, SW_RESTORE);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{以下省略}
end;
再看一下 ShowWinNoAnimate:
procedure ShowWinNoAnimate(Handle: HWnd; CmdShow: Integer);
var
Animation: Boolean;
begin
Animation := GetAnimation;
if Animation then SetAnimation(False); (1)
^^^^^^^^^^^^^^^^^^^^^
ShowWindow(Handle, CmdShow);
if Animation then SetAnimation(True);
end;
再看一下 SetAnimation:
procedure SetAnimation(Value: Boolean);
var
Info: TAnimationInfo;
begin
Info.cbSize := SizeOf(TAnimationInfo);
BOOL(Info.iMinAnimate) := Value;
SystemParametersInfo(SPI_SETANIMATION, SizeOf(Info), @Info, 0);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
原来在这里。
end;
让我们再看一下当TForm1要Minimize时他干什么。因为TForm是从TCustomForm
继承过来的,他自己没有响应WM_SYSCOMMAND的方法,所以使用的是
TCustomForm的。
procedure TCustomForm.WMSysCommand(var Message: TWMSysCommand);
begin
if (Message.CmdType and $FFF0 = SC_MINIMIZE) and
(Application.MainForm = Self) then
Application.Minimize
^^^^^^^^^^^^^^^^^^^^这一句的执行结果是最小化了TApplication,隐藏了
Form1。
else
inherited;
end;
你可以注释掉以上的(1)句,就会发现Tapplication最小化时有了动化,但
很难看。
哦有一个解决方法如下:
首先是要用SetWindowLong将Form1变成WS_EX_APPWINDOW,但这样一来旧必须
隐藏Application窗口。使用ShowWindow(application.handle,SW_HIDE);另外,
我们还必须改VCL的源码。在Forms.pas中,将上面那个TCustomForm.WMSysCommand
注释掉if,只剩下inherited,这样,Form1在最小化时旧不会击活application
的窗口了。具体改变方法如下。
1.拷贝一个Forms.pas到当前目录,从Project Source中删除缺省的Forms单元,
然后将Forms.pas作为一个新单元加入到Project中。
2.更改Project Source如下:
program Project1;
uses
windows,
^^^^^^^^^
Unit1 in 'Unit1.pas' {Form1},
Forms in 'forms.pas';
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
SetWindowLong(form1.handle,GWL_EXSTYLE,GetWindowLong(form1.handle,
GWL_EXSTYLE) or WS_EX_APPWINDOW);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
form1.show;
^^^^^^^^^^^
showwindow(application.handle,sw_hide);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Application.Run;
end.
以上打了 ^ 的均为添加的代码。
3.将Forms.pas中的TCustomForm.WMSysCommand更改为如下:
大家也可以试一试不改的效果。
procedure TCustomForm.WMSysCommand(var Message: TWMSysCommand);
begin
{ if (Message.CmdType and $FFF0 = SC_MINIMIZE) and
(Application.MainForm = Self) then
Application.Minimize
else} -------------------------------- 注释掉了。
inherited;
end;

通过以上步骤,基本上旧可以实现动画缩放了。

BTW:这种方法实现也还有一定缺陷,那为大峡有更好的方法请提出来

供大家交流。

时间: 2024-12-21 23:53:58

CB的Form最小化时无动画的原因的相关文章

C#编写最小化时隐藏为任务栏图标的Window appllication.

window C#编写最小化时隐藏为任务栏图标的Window appllication. 1.设置WinForm窗体属性showinTask=false 2.加notifyicon控件notifyIcon1,为控件notifyIcon1的属性Icon添加一个icon图标. 3.添加窗体最小化事件(首先需要添加事件引用): this.SizeChanged += new System.EventHandler(this.Form1_SizeChanged); //上面一行是主窗体Initializ

怎么让程序最小化时不在任务栏上显示,而在左下角显示

问题描述 怎么让程序最小化时不在任务栏上显示,而在左下角显示 解决方案 解决方案二:窗体中有个属性:ShowInTaskbar,设定为false,就不会在任务栏中出现了解决方案三:是右下角吧有现成的控件啊好像是什么No开头的呵呵自己看看吧解决方案四:窗体隐藏起来,有个叫hide的方法.小图标那个是叫什么T..Ico的控件解决方案五:添加NotifyIcon控件,然后重载OnSizeChangedprotectedoverridevoidOnSizeChanged(EventArgse){base

C#实现系统托盘及窗体最小化时隐藏为任务栏图标的Window appllication

1.设置窗体属性showintask=false 2.加notifyicon控件notifyicon1,为控件notifyicon1的属性icon添加一个icon图标. 3.添加窗体最小化事件(首先需要添加事件引用): //this.sizechanged+=newsystem.eventhandler(this.form1_sizechanged); //上面一行是主窗体initializecomponent()方法中需要添加的引用 privatevoidform1_sizechanged(o

让程序在前端显示和最小化时在系统栏里

程序缩成图标!  /*参数说明:hWnd,不用多说了吧? uId,图标排在系统栏中的位置,设为0即可 hIcon,图标 s,鼠标移到图标上要显示的话 */ /*注意:你必须自定义一个窗口消息MYWM_ICON, #define MYWM_ICON  (WM_APP+100) 在窗口循环中响应该消息: case MYWM_ICON:switch(lParam){  case WM_LBUTTONDOWN:  case WM_RBUTTONDOWN:} 以响应鼠标在该程序图标上的击键动作. 如果你想

窗口最小化后,点击托盘窗口显示动画是从左下角显示到屏幕中央

问题描述 protectedoverridevoidOnResize(EventArgse){if(WindowState==FormWindowState.Minimized){//最小化时所需的操作//this.Location=newPoint(System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width-this.Width,System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height-th

[WPF]如何在关闭非模态子窗体时用消息框确认:解决最小化窗体时抛出的异常

又是一个看起来很简单的问题.像下面这样在Closing里弹出个MessageBox确认一下不就行了? public static void OnWindowClosing(object sender, CancelEventArgs e) { if (MessageBox.Show(string.Format("Are you sure to close the {0}?", (sender as Window).Title), "Confirm", Message

VB.NET实现窗体图标最小化到状态栏

本文所使用的编程环境是Microsoft Visual Studio 2005,首先打开Visual Studio.在文件(File)菜单上,单击新建项目(New Project).在新建项目(New Project)对话框的模板(Templates)窗格中,单击Windows应用程序(WindowsApplication).单击确定(ok). 想要将窗体图标最小化时自动隐藏到任务栏,我们可以使用一个控件,这个控件的名字叫做NotifyIcon控件,打开左侧的工具箱找到NotifyIcon控件直

如何用代码来最小化或恢复程序

你能够用下面三种方法之一来实现它. 方法一:发送一条Windows消息到主窗口的Handle属性或 Application->Handle.这条消息就是 WM_SYSCOMMAND,将 wParam 设为 SC_MINIMIZE 或 SC_RESTORE.你可以调用SendMessage API函数来发送消息. // 设置WPARAM为SC_MINIMIZE来最小化窗口 SendMessage(Application->Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0

C#实现WinForm窗口最小化到系统托盘

  C#编写最小化时隐藏为任务栏图标的 Window appllication.   1.设置WinForm窗体属性showinTask=false 2.加notifyicon控件notifyIcon1,为控件notifyIcon1的属性Icon添加一个icon图标. 3.添加窗体最小化事件(首先需要添加事件引用): this.SizeChanged += new System.EventHandler(this.Form1_SizeChanged); //上面一行是主窗体InitializeC