600大洋,如何防止界面贴图引起的闪烁 ( 积分: 300 )

  • 主题发起人 主题发起人 可爱小猪
  • 开始时间 开始时间

可爱小猪

Unregistered / Unconfirmed
GUEST, unregistred user!
如题
大家尽量提出自己的方法
分不够可以在加
 
如题
大家尽量提出自己的方法
分不够可以在加
 
设置Form.DoubleBuffered :=True;
 
在Form的OnActivate写 Form.Repaint; image1.update;之类的,
或者写image1.visible := False; image1.visible := True;这样可以只闪一下吧。
 
一个思路:
设置好位置,把需要显示的都读出来,然后再根据你的条件设置其中的一个显示,一个隐藏,闪烁能减少很多
 
同志门
不是这样滴
听 nutrundelphi 说是底色和背景色的变换
同志们深入点了
我在加300分了
努力啊
 
1在切换时尝试使用 api 函数 :lockwindowupdate 也许是 lockwindowsupdate,禁止在作处理时

对窗体或控件的刷新 ,等完成后再刷新 ,可以解决闪烁的问题。

2 其实先 DisableAlign ,切换以后再 EnableAlign 也可以达到同样的效果


3 可利用类 Tcanvas 的 CopyRect 方法实现
 
能否讲解下这写原理
楼上的方法好象有点漏洞
 
要想不闪烁,当然要用到直接写视频缓冲区的方法了,通过DirectX技术创建一个表面,然后可以为其设上几个后备作图缓冲区,系统利用硬件的页切换来实现高速贴图,其实一点儿也不玄,记得DelphiX控件包里有好几个例子,如果用Delphi开发的话就更简单了,拖一个表面,然后把它当Image一样操作就能达到效果。
如果这种方法还是会产生闪烁,那么只可能是机器的性能太差了。
 
呵呵
楼上都说到这个了,牛
在仔细讲解个先了 firstboy
老兄
 
这是一个在背景图上显示另外一个图的函数,速度不错

unit Pic;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics;

procedure KenCopyRect(BmpFront, BmpBackGround: TBitmap; X, Y: Integer;
TransColor: TColor; UseTransColor: Boolean = True);
//功能描述:实现Bmp图片透明叠加
//参数表:
// BmpFront TBitmap 前景图片
// BmpBackGround TBitmap 背景图片
// X Integer 前景图片相对于背景图片的X轴坐标
// Y Integer 前景图片相对于背景图片的Y轴坐标
// TransColor TColor 前景图片上需要透明的颜色,即前景图片上的该颜色位置用背景替代
// UseTransColor Boolean 是否使用透明色,如果不使用,则自动选取前景图片左下角的颜色为透明色
//返回值:
// 无
//备注:
// 叠加后的图片在BmpBackGround中


implementation

procedure KenCopyRect(BmpFront, BmpBackGround: TBitmap; X, Y: Integer;
TransColor: TColor; UseTransColor: Boolean = True);
var
i, j: Integer;
PSource,PTarget: PbyteArray;
begin
if (BmpFront = nil) or (BmpBackGround = nil) then
exit;

BmpFront.PixelFormat := pf24bit;
BmpBackGround.PixelFormat := pf24bit;

if not UseTransColor then
TransColor := BmpFront.Canvas.Pixels[0, BmpFront.Height - 1];

for i := 0 to BmpFront.Height - 1 do
begin
if i + y > BmpBackGround.Height - 1 then
break;
PTarget := BmpBackGround.ScanLine[i + y];
PSource := BmpFront.ScanLine;
for j := 0 to BmpFront.Width - 1 do
begin
if x + j > BmpBackGround.Width - 1 then
break;

if RGB(PSource[j*3], PSource[j*3 + 1], PSource[j*3 + 2]) <> TransColor then
begin
PTarget[x*3 + j*3] := PSource[j*3];
PTarget[x*3 + j*3 + 1] := PSource[j*3 + 1];
PTarget[x*3 + j*3 + 2] := PSource[j*3 + 2];
end;
end;
end;
end;

end.
 
其实很简单
防止界面贴图引起的闪烁,闪烁是怎样引起的呢?是因为在贴图前,先画了背景,然后再画图,所以闪烁。
界面贴图,是在界面的private里声明:
procedure WMEraseBkgnd(var Message: TMessage); message WM_ERASEBKGND;

然后
procedure XXX.WMEraseBkgnd(var Message: TMessage);
begin
message.Result:=0;
end;
这样就不绘制背景了。
 
楼主说的尽是废话, 具体的要求都没有说清楚。
 
怎么没有人说 不贴图
自画什么的
反正讨论就是做 漂亮见面的事情
贴图闪,至于用DirectX
觉得没有必要
wanpeng, :
哪个很慢
通常是一行一行画的
 
同意xuxiaohan的意见, 其实一楼已经给出了正确答案.
所以后面的都是废话
 
一楼所说的方法确实有效,但容易占用过高的系统资源,如果界面的图形变化比较频繁,那么对系统资源的占用会很高,可以应用建立一个图片需要更新时可以将其贴出来,同时需要加以更新!
 
不是啊
我的意思是做漂亮的窗体
用setwindow的函数
要怎么来搞窗体的见面之类的
看见皮肤控件那些功能的实现
 
设 buffer 会好一点
 
试一下

unit Unit1;

interface

uses
Types,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, jpeg, ExtCtrls, StdCtrls, ImgList;

type
TForm1 = class(TForm)
Label1: TLabel;
Timer1: TTimer;
Image1: TImage;
i1: TImageList;
Label3: TLabel;
Label2: TLabel;
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
img:TImage;
i:integer;
implementation

{$R *.dfm}

procedure TForm1.Timer1Timer(Sender: TObject);
var
r,r1:TRect;
begin
//image1为背景图片
//image1.visible:=false;
//label1.visible:=false;
//label2.visible:=false;
//不闪烁的关键是所有操作先在img上进行(label1,label2不可见),最后一次制到窗体

img.Width :=image1.Width ;
img.Height :=image1.Height;
label1.Left :=(label1.Left +1);
label2.Left:=label1.Left +1;

label3.Left :=label1.left;//单纯移动方法1(闪烁)
self.Canvas.Font.Assign(label3.Font);
self.Canvas.TextOut(label3.Left ,label3.Top-60,label3.Caption);//单纯移动方法2(闪烁)

if label1.Left> self.Width then label1.Left:=-label1.Width-i1.Width;
r.TopLeft:=point(0,0);
r.BottomRight:=point(image1.Width ,image1.Height);
r1.TopLeft:=point(0,0);
r1.BottomRight:=point(image1.Picture.Width ,image1.Picture.Height);


img.Canvas.Brush.Style :=bsClear;
img.Canvas.CopyMode:=cmSrcCopy;

//img.Canvas.CopyRect(r,image1.Canvas ,r1);
img.Canvas.StretchDraw(r, image1.Picture.Graphic);

i1.Draw(img.Canvas,label1.left+label1.Width,label1.Top,i div 4);

//特殊方法(不闪烁)
img.Canvas.Font.Assign(label2.Font);
img.Canvas.TextOut(label2.Left ,label2.Top,label2.Caption);
img.Canvas.Font.Assign(label1.Font);
img.Canvas.TextOut(label1.Left ,label1.Top,label1.Caption);

self.Canvas.CopyRect(r,img.Canvas ,r);
i:=(i+1) mod 32;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
img:=TImage.Create(self);

end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
img.Free;
end;

end.
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部