先让canvas.brush.style:=bsclear;然后再画图就透明了
解决方案 »
- [重大问题] 用D7 写个空窗体也报毒, 大家这样吗?
- 初学者的一个问题(急)
- 真麻烦。。。用直线画弧线。
- 一个最简单的问题,怎样使按钮变灰,再变过来?
- 高难度的Oracle和SQLServer的问题!?!?
- 怎样让标题栏上的字幕走来走去。
- 您好,请教如下问题,谢谢。
- 一个关于ado数据库查询的问题!困扰我很久了,请大家帮帮忙!谢谢!
- 学了几年计算机,明白了一个道理
- 请教高手:如何关闭一个窗口或隐藏一个窗口?我是新手,我只知在工程-->设置了autocreate,那一运行就出现一个登录窗口,输入密码正确我就show主窗口,但登录窗口就关不掉了!
- 各位大虾,谁的Delphi6.0的密码能告诉我,我重重有分
- 高分就求IE类似的收藏夹,急
再画第二个图。
使用BitBlt函数(API)
声请俩个DC资源
一个作为前台的缓冲区,画完后将其拷贝到屏幕。
另一个作为后台,有新图画到其上。然后拷贝到前台缓冲区。触发OnPanit事件。
的Left和Top属性,势必会造成闪烁。这个问题的解决是使用缓冲区的技术,还是
先看一个例子。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
StdCtrls, Buttons, ExtDlgs, ExtCtrls;
type
TForm1 = class(TForm)
OpenDlg: TOpenPictureDialog;
BitBtn1: TBitBtn;
Timer1: TTimer;
procedure BitBtn1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
CurrentX, CurrentY: integer;
WorkImage, BackImage, DispImage: TBitmap;
implementation
{$R *.DFM}
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if OpenDlg.Execute then begin
DispImage := TBitmap.Create;
DispImage.LoadFromFile(OpenDlg.FileName);
WorkImage := TBitmap.Create;
BackImage := TBitmap.Create;
WorkImage.Width := Form1.Width;
WorkImage.Height := Form1.Height;
BackImage.Width := DispImage.Width;
BackImage.Height := DispImage.Height;
WorkImage.Canvas.CopyRect(Rect(0, 0, Form1.Width, Form1.Height),
Form1.Canvas, Rect(0, 0, Form1.Width, Form1.Height));
//保存背景
BackImage.Canvas.CopyRect(Rect(0, 0, DispImage.Width, DispImage.Height),
WorkImage.Canvas,
Rect(CurrentX, CurrentY, CurrentX +
DispImage.Width, CurrentY + DispImage.Height));
//要显示的内容放到WorkImage中
WorkImage.Canvas.CopyRect(Rect(CurrentX, CurrentY, CurrentX +
DispImage.Width, CurrentY + DispImage.Height),
DispImage.Canvas,
Rect(0, 0, DispImage.Width, DispImage.Height));
//显示在窗体上
Form1.Canvas.CopyRect(Rect(CurrentX, CurrentY, CurrentX +
DispImage.Width, CurrentY + DispImage.Height),
WorkImage.Canvas,
Rect(CurrentX, CurrentY, CurrentX + DispImage.Width,
CurrentY + DispImage.Height));
Timer1.Enabled := True;
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
//将保存的背景复制到工作画布上
WorkImage.Canvas.CopyMode := cmSrcCopy;
WorkImage.Canvas.CopyRect(Rect(CurrentX, CurrentY, CurrentX +
DispImage.Width, CurrentY + DispImage.Height),
BackImage.Canvas,
Rect(0, 0, DispImage.Width, DispImage.Height));
Inc(CurrentX, 2);
//将新位置上的背景保存
BackImage.Canvas.CopyRect(Rect(0, 0, DispImage.Width, DispImage.Height),
WorkImage.Canvas,
Rect(CurrentX, CurrentY,
CurrentX + DispImage.Width,
CurrentY + DispImage.Height));
//将位图复制到新位置上
WorkImage.Canvas.CopyRect(Rect(CurrentX, CurrentY,
CurrentX + DispImage.Width,
CurrentY + DispImage.Height),
DispImage.Canvas,
Rect(0, 0, DispImage.Width, DispImage.Height));
//将结果画到窗体上
Form1.Canvas.CopyRect(Rect(CurrentX - 2, CurrentY,
CurrentX + DispImage.Width,
CurrentY + DispImage.Height),
WorkImage.Canvas,
Rect(CurrentX - 2, CurrentY,
CurrentX + DispImage.Width,
CurrentY + DispImage.Height));
end;
initialization
CurrentX := 0;
CurrentY := 0;
end.
这项技术使用了多重TBitmap对象和TCanvas组件协调地工作,制造了平滑且无闪烁
的位图的移动。它的关键是在于使所有的点在"屏幕后面"移动,只将结果复制到屏
幕上。在移动之前,需要做一些初始化工作:
//将背景复制到WorkImage上
WorkImage.Canvas.CopyRect(Rect(0, 0, Form1.Width, Form1.Height), Form1.
Canvas, Rect(0, 0, Form1.Width, Form1.Height));
//保存背景
BackImage.Canvas.CopyRect(Rect(0, 0, DispImage.Width, DispImage.Height),
WorkImage.Canvas, Rect(CurrentX, CurrentY, CurrentX + DispImage.Width,
CurrentY + DispImage.Height));
//要显示的内容放到WorkImage中
WorkImage.Canvas.CopyRect(Rect(CurrentX, CurrentY, CurrentX +
DispImage.Width,
CurrentY + DispImage.Height), DispImage.Canvas, Rect(0, 0, DispImage.
Width,
DispImage.Height));
//显示在窗体上
Form1.Canvas.CopyRect(Rect(CurrentX, CurrentY, CurrentX + DispImage.
Width,
CurrentY + DispImage.Height), WorkImage.Canvas, Rect(CurrentX, CurrentY,
CurrentX + DispImage.Width, CurrentY + DispImage.Height));
SaveImage在运动位图下持有了保存的图像,接着又将运动图像复制到WorkImage上
,又将运动图像复制到WorkImage上,再将WorkImage复制到窗体的Canvas上,这样
,用户就可以看到图像了。
一旦存储了背景,要想实际地移动位图,就必须做好以下四件事:
1.将以前的背景复位;
2.保存新位置的背景;
3.将移动了的位图复制到新的位置;
4.将综合了的区域复制到实际的显示表面。这些动作通过以下代码实现:
//将保存的背景复制到工作画布上
WorkImage.Canvas.CopyMode := cmSrcCopy;
WorkImage.Canvas.CopyRect(Rect(CurrentX, CurrentY, CurrentX +
DispImage.Width,
CurrentY + DispImage.Height), BackImage.Canvas, Rect(0, 0, DispImage.
Width,
DispImage.Height));
Inc(CurrentX, 2);
//将新位置上的背景保存
BackImage.Canvas.CopyRect(Rect(0, 0, DispImage.Width, DispImage.Height),
WorkImage.Canvas, Rect(CurrentX, CurrentY, CurrentX + DispImage.Width,
CurrentY +
DispImage.Height));
//将位图复制到新位置上
WorkImage.Canvas.CopyRect(Rect(CurrentX, CurrentY, CurrentX +
DispImage.Width,
CurrentY + DispImage.Height), DispImage.Canvas, Rect(0, 0, DispImage.
Width,
DispImage.Height));
//将结果画到窗体上
Form1.Canvas.CopyRect(Rect(CurrentX - 2, CurrentY, CurrentX +
DispImage.Width,
CurrentY + DispImage.Height), WorkImage.Canvas, Rect(CurrentX - 2,
CurrentY,
CurrentX + DispImage.Width, CurrentY + DispImage.Height));
此处的重要技术就是关于位图的不同画布属性和主窗体自身的CopyRect的连续运用
。CopyRect是Delphi封装在TCanvas中的Windows API调用,它有两个对应目的矩形
和源矩形的参数,还有一个对应源画布的参数。CopyRect有两个非常严格的要求:
1.CopyRect要求调用的目标画布必须有一个可用的Windows HDC,否则会产生一个
通常保护错(GPF)。
2.源画布也必须有一个可用的Windows HDC,而且必须含有信息,否则也会产生一
个通常保护错(GPF)。
如果不对这两点进行控制,CopyRect将会成为程序的一个潜在威胁。
fillrect(rect(0,0,image.width,image.height));