//执行AnimateWindow之后窗体没有重绘
//应该算Delphi、或者是Windows的Bug吧!天知道~~
procedure TForm1.FormShow(Sender: TObject);
begin
AnimateWindow(Handle, 800, AW_CENTER);
Repaint; //加一句试试
end;
//应该算Delphi、或者是Windows的Bug吧!天知道~~
procedure TForm1.FormShow(Sender: TObject);
begin
AnimateWindow(Handle, 800, AW_CENTER);
Repaint; //加一句试试
end;
begin
AnimateWindow(Handle, 800, AW_ACTIVATE or AW_CENTER); //别忘AW_ACTIVATE,我说调试怎么这样别扭
Repaint; //加一句试试
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
AnimateWindow(Handle, 800, AW_HIDE or AW_CENTER);
end;
self.Refresh(); // 加上这句
原因是 TImage 不是TWinControl类,没有消息循环,得不到系统发给他重画的消息,而这类的东西是由VCL来负责画的。
两位研究一下。
原因很简单,但是解决方法很麻烦。
MSDN文档说窗体中的控件的windows程序必须处理WM_PRINT或WM_PRINTCLIENT消息,使它们与AnimateWindow API函数一起使用。这些消息当Windows需要在屏幕以外的显示环境(如打印机,在这里使屏幕外位图)绘图时被使用。该文档说普通控件和对话框的窗口程序已经处理了这些消息。 这就解释了一些控件绘图正常:例如TButton, TCheckBox和TRadioButton它们拥有和管理底下的按钮控件,这样它们能正确的处理消息。 绘图有错误的控件是一种中间类型,它们拥有按钮控件但是一些部分使应用Dephi的TCanvas而不是Windows GDI绘制的,如TEdit, TRichEdit和其他这样的控件。 不可见的控件是完全不拥有普通控件的那些,它们都是TGraphic的后代,如TShape和TBevel。这些控件决不会画出来,因为它们接收不到需要的消息。 但是,对从TWinControl衍生出来的Delphi对象,你可以这样从中间截取和处理WM_PRINTCLIENT消息:unit TestGroupBox; interface uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls; type
TTestGroupBox = class(TGroupBox)
private
{ Private declarations }
protected
{ Protected declarations }
procedure WMPrintClient(var Msg: TMessage); message WM_PRINTCLIENT; public
{ Public declarations }
published
{ Published declarations }
end; procedure Register; implementation procedure Register;
begin
RegisterComponents(''Test'', [TTestGroupBox]);
end; { TTestGroupBox } procedure TTestGroupBox.WMPrintClient(var Msg: TMessage);
begin
PaintTo(HDC(Msg.WParam), 0, 0);
end; end. 这是一个从TGroupBox派生出来的例子组件。由于TGroupBox拥有的不是一个普通窗口控件,WM_PRINTCLIENT没有被处理。程序添加消息处理函数并在一个不同的显示环境中使用PaintTo方法,这些都是直接了当的。 现在是麻烦的部分了:你窗体的每一个控件都必须这样修改,而且你必须修改你所有的对象才能安全使用AnimateWindow API函数。
可TStringGrid、TDBGrid等从TWinControl继承下来的控件也有这样的问题 :(
原因关注中... ...
不知道你的测试结果是什么,能用的是什么控件来调试呢?
如下是一狠招。procedure TForm1.FormShow(Sender: TObject);
var
I: Integer;
begin
AnimateWindow(Handle, 800, AW_ACTIVATE or AW_CENTER); //别忘AW_ACTIVATE,我说调试怎么这样别扭
for I := 0 to ComponentCount - 1 do
if Components[I] is TControl then
TControl(Components[I]).Repaint;
end;
你要显示哪个控件(TWinControl)只要在 AnimateWindow(Handle, 800, AW_CENTER) 后加上 XXX.Repaint( XXX可以为你的Image1) 就可以了
AnminateWindow 这个是win2k出来才正式宣布出来的。可能borland当时没考虑到。新版的delphi 7估计重新写了这些控件的消息处理。
to pazee: 是呀,编程不可能什么都考虑进去。实现功能先好久没有进行这样愉快的技术交流了,感谢大家 :)
我是这样做的:
procedure TFrmBase.FormShow(Sender: TObject); procedure RefreshControl(Control: TControl); ///可能包含子控件,也要刷新
var
i : integer;
begin
Control.Invalidate;
if Control is TWinControl then
for i := 0 to TWinControl(Control).ControlCount - 1 do
RefreshControl(TWinControl(Control).Controls[i]);
end;begin
AnimateWindow(Handle, 200, AW_SLIDE + AW_CENTER);///动画显示
RefreshControl(Self); ///使用动画之后,必须Refresh,否则控件看不到!
SetActiveWindow(Handle); ///激活窗口
end;