如何实现电影字幕徐徐上升?(50分)

  • 主题发起人 主题发起人 kun
  • 开始时间 开始时间
K

kun

Unregistered / Unconfirmed
GUEST, unregistred user!
我记得好象在那里看过先在canvas 上画然后再擦再画
 
现成的控件可以使用Rxlib中的 TSecretPanel
 
定时器,自己实现,

注意点重画就行了,免得不够平顺:)
 
要注意的不是不够平顺,而是不要闪烁,要用到内存位图。
 
另外关于string常量(打印报表的标题等,每个工厂都不一样)应该放在那里,
放在DLL里调用,还是做成unit里的resourcestring,还是用.rc编成res
又或者别的方法使EXE最小又方便更改.bitmap也一样,bmp应该放在另外一
文件夹里要再调用吧?
 
//读Txt文件内容滚动
unit Scroll1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Buttons, ExtCtrls, ComCtrls, StdCtrls;

type
TForm1 = class(TForm)
Panel1: TPanel;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
SpeedButton3: TSpeedButton;
StatusBar1: TStatusBar;
Panel2: TPanel;
OpenDialog1: TOpenDialog;
Timer1: TTimer;
PaintBox1: TPaintBox;
Memo1: TMemo;
procedure SpeedButton1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
procedure SpeedButton3Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}
const
cLinesDistance=2; //行间距
cPerPix=3; //每次滚动的像素数

var
vBitmap:TBitmap;
iLinesCount:Integer;
iHeight,iTextHeight:Integer;
pHeader,pBitmap:Integer;
SourceRect,TargetRect:TRect;

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
iLoop:Integer;
vProgress:TProgressBar;
begin
Timer1.Enabled:=False;
with OpenDialog1 do
begin
if Execute then
begin
Memo1.Lines.LoadFromFile(FileName);
iLinesCount:=Memo1.Lines.Count;
iTextHeight:=vBitmap.Canvas.TextHeight('赵');
iHeight:=iLinesCount*(cLinesDistance+iTextHeight);
vBitmap.Height:=iHeight;
vProgress:=TProgressBar.Create(Self);
with vProgress do
begin
Parent:=StatusBar1;
Align:=alClient;
Min:=0;
Max:=iLinesCount;
Step:=1;
Visible:=True;
end;
for iLoop:=0 to iLinesCount-1 do
begin
vBitmap.Canvas.TextOut(0,iLoop*(cLinesDistance+iTextHeight),memo1.Lines[iLoop]);
vProgress.StepIt;
end;
vProgress.Free;
StatusBar1.SimpleText:=FileName;
PaintBox1.Refresh;
pHeader:=PaintBox1.Height;
pBitmap:=0;
end;
end;
Timer1.Enabled:=True;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.parent:=Form1;
Memo1.Visible:=False;
Memo1.Width:=Screen.Width;

vBitMap:=TBitmap.Create;
vBitMap.Width:=Screen.Width;
vBitmap.Canvas.Font:=Font;

pHeader:=PaintBox1.Height;
pBitmap:=0;
end;

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
Timer1.Enabled:=False;
end;

procedure TForm1.SpeedButton3Click(Sender: TObject);
begin
Timer1.Enabled:=True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if Application.Active then
begin
with SourceRect do
begin
Left:=0;
Top:=pBitmap;
Right:=PaintBox1.Width;
Bottom:=pBitmap+PaintBox1.Height-pHeader;
end;
with TargetRect do
begin
Left:=0;
Top:=pHeader;
Right:=PaintBox1.Width;
Bottom:=PaintBox1.Height;
end;
PaintBox1.Canvas.CopyRect(TargetRect,vBitmap.canvas,SourceRect);
if pHeader>0 then
begin
pHeader:=pHeader-cLinesDistance;
end
else
pHeader:=0;
if pHeader=0 then
pBitmap:=pBitmap+cLinesDistance;
if pBitmap+PaintBox1.Height>vBitmap.Height then
begin
Timer1.Enabled:=False;
end;
end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
vBitmap.Free;
end;

end.
 
用resourcestring生成的字符串跟直接用rc文件生成的字符串的效果设一样的。
 
以下代码供参考:
在窗体中加入一个定时器与paintBox,Textpos为全局变量,然后:

procedure TAboutBox.Timer1Timer(Sender: TObject);
begin
if textPos=0 then textPos:=PaintBox1.height*任意整数;
PaintBox1.Refresh;
PaintBox1.Canvas.TextOut(0,(textPos) mod PaintBox1.height-16,'AAA');
PaintBox1.Canvas.TextOut(0,(textPos+16) mod PaintBox1.height-16,'BBB');
PaintBox1.Canvas.TextOut(0,(textPos+32) mod PaintBox1.height-16,'CCC');
PaintBox1.Canvas.TextOut(0,(textPos+48) mod PaintBox1.height-16,'DDD');
textPos:=textPos-1;
end;
 
同意eyes4的看法,
 
多人接受答案了。
 
先将需要显示的文字DrawText到内存位图上,
用计时器将有文字的内存位图BitBlt出来。
 
后退
顶部