控件高手看过来!(50分)

  • 主题发起人 主题发起人 casey
  • 开始时间 开始时间
C

casey

Unregistered / Unconfirmed
GUEST, unregistred user!
正在编写一动态显示图象的控件,就是可以搞得像屏保程序那种效果的控件,在控件的Paint事件里希望控件的动态效果只显示一次,以后再paint也是直接显示出图象,不再动态显示了。
具体代码如下
var painted:boolean; //一个全局变量
constructor TTransitionImage.Create(AOwner: TComponent);
begin
painted:=false; //初始化为未画过
end;
procedure TTransitionImage.Paint; //这部分参考TImage
var
Save: Boolean;
begin
if (csDesigning in ComponentState) then
begin
with inherited Canvas do
begin
begin
Pen.Style := psDash;
Brush.Style := bsClear;
Rectangle(0, 0, Width, Height);
end;
Save := FDrawing;
FDrawing := True;
try
with inherited Canvas do
StretchDraw(DestRect, FPicture.Graphic); //直接显示
finally
FDrawing := Save;
end
end
else
begin
if not painted then //如果未画过
begin
painted:=true;
Transitions(FTransition) //动态效果
end
else
with inherited Canvas do
StretchDraw(DestRect, FPicture.Graphic); //直接显示
end;
end;
可结果却是在第一次需要动态显示时直接显示了,但是跟踪调试时
第一次显示动态效果那一段却有执行,以后的Paint的确如程序设计那样
到了直接显示这一段,这样的结果让我大惑不解,希望哪个高手可以指点一下。
 
这里需要补充及更正几点,大家看得更明白些。
TTransition = Class(TCustomImage)
private
painted:boolean;
MyBitmap:TBitamp;
...
end;

procedure TTransitionImage.Transitions(Value: TTransition);
begin
if FPicture.Graphic<>nil then
begin
MyBitmap:=TBitmap.Create;
MyBitmap.Assign(FPicture.Graphic);
case Value of
ttbuilddown builddown; //以该动态显示为例
ttZoomFromPoint: ZoomFromPoint;
end;
TempBitmap.Assign(MyBitmap);
MyBitmap.Free;
end;
end;

procedure TTransitionImage.BuildDown;
var i,step:integer;
MyRect:TRect;
begin
step:= Super(height/FSmooth);
with inherited Canvas do
for i:=0 to step-1 do //动态显示的具体细节
begin
MyRect:=Rect(1,i*FSmooth+1,width,(i+1)*FSmooth+1);
copyrect(MyRect,MyBitmap.canvas,MyRect);
end;
end;
 
很简单,这是由于操作系统窗口绘制的累积效应造成的。
直接运行时,WM_PAINT消息多次发送,由于速度太快,绘制的结果却一直被累积在
内存中,此时由于应用程序一直在初始化,没有空闲CPU时间,所以屏幕上不会有反映。这是操作系统优化的结果。
调试时,CPU很空闲,运行一步就停一步。所以你的程序是正确的。
这种情况很常见,比如启动DELPHI时,用别的窗口覆盖启动画面,再快速切换
回 DELPHI ,启动画面也会出现短暂空白。
最好在你的窗口显示出来以后,再设一个开关,允许动态效果,然后再关掉
这个开关。
不明白的可以参考 Win32 API 关于 WM_PAINT 的文档。
From: BaKuBaKu

 
看到BaKuBaKu的答案,以下是我的改法,终于可以实现了,非常感谢。
painted声明为整形;
{in create} painted:=0;
{in paint}
if painted<3 then //第四次Paint才可见动态效果,真有趣
begin
painted:=painted+1;
Transitions(FTransition) //动态效果
end
else
with inherited Canvas do
StretchDraw(DestRect, FPicture.Graphic); //直接显示
end;
 
后退
顶部