`

Delph做的百叶窗小程序

阅读更多
做了一个百叶窗小程序
碰到了几个问题,比如说两个用到LoadFromFile函数的地方第一次可以识别相对路径
而如果我更改了其中一个的路径使其变为硬盘上某个绝对路径
那另外一个LoadFromFile就不能识别原先的相对路径了,很奇怪
我采取了加判断绕过这个问题的方法
先上代码,主要的是shutter单元,是作为一个组件来编写的
另外还写了个测试单元。主要针对Shutter的某些属性进行设置从而测试Shutter

unit Shutter;
{ CopyRight@ Swetter }
interface

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

const
{位图344*500,沿Y轴等分成10块
yInc存储了每块的高度
BitMapWid存储了位图的宽度
BitMapHei存储了位图的高度
ShowPixels为随Timer每次递增的行宽度
TimerInterval为Timer的时间间隔}
YInc = 50;
// ShowPixels = 1;
BitMapWid = 344;
BitMapHei = 500;
// TimerInterval = 50;

type
EShutterError = class(Exception);

TShutter = class(TCustomPanel)
private
FMemBitMap: TBitmap;
FMemMskBtMp: TBitmap;
FTimer: TTimer;
FActive: Boolean;
FCurrHei: Integer;
FVRect: TRect;
{FOpen指示百叶窗打开与关闭效果,true则百叶窗打开,false则百叶窗关闭
FDone指示位图是否显示完毕
FViewPic指示是否要查看原图
true为查看原图,此时FCurrHei值直接为yInc而不置0
false为不查看原图,此时在SetActive为false后FCurrHei置0
FNFrstm指示在百叶窗打开模式下(即清空图像)是否已贴上原图
false为未贴上原图,需重新贴一次;true为已贴上原图,可以开始贴屏蔽图}
FOpen: Boolean;
FDone: Boolean;
FViewPic: Boolean;
FOnDone: TNotifyEvent;
FNFrstm: Boolean;
FBkFileName: string;
FFgFileName: string;
ShowPixels: Integer;
TimerInterval: Integer;
procedure IncWid;
procedure SetActive(AValue: Boolean);
procedure ActOnTimer(Sender: TObject);
procedure DoTimer;
protected
procedure Paint; override;
procedure FillBitmap; virtual;
public
procedure CoordinateTimer;
procedure ImageChanged;
property Pixel: Integer read ShowPixels write ShowPixels;
property Interval: Integer read TimerInterval write TimerInterval;
property BkFileName: string read FBkFileName write FBkFileName;
property FgFileName: string read FFgFileName write FFgFileName;
property NFrstm: Boolean read FNFrstm write FNFrstm;
property Open: Boolean read FOpen write FOpen;
property ViewPic: Boolean read FViewPic write FViewPic;
property Active: Boolean read FActive write SetActive;
property Done: Boolean read FDone write FDone;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
{ Publish inherited properties: }
property OnDone: TNotifyEvent read FOnDone write FOnDone;
property Align;
property Alignment;
property BevelInner;
property BevelOuter;
property BevelWidth;
property BorderWidth;
property BorderStyle;
property Color;
property Ctl3D;
property Font;
property Locked;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property Visible;
property OnClick;
property OnDblClick;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnResize;
end;

implementation

{ TShutter }

procedure TShutter.DoTimer;
begin
with FTimer do
begin
Enabled := False;
Interval := TimerInterval;
OnTimer := ActOnTimer;
end;
end;

constructor TShutter.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
TimerInterval := 50;
ShowPixels := 1;
FTimer := TTimer.Create(Self);
DoTimer;
{ 实例初始化的值 }
Width := 344;
Height := 500;
FActive := False;
BevelWidth := 3;
FFgFileName := '.\pics\pic.bmp';
FBkFileName := '.\pics\view.bmp';
end;

destructor TShutter.Destroy;
begin
SetActive(False);
FTimer.Free;
inherited Destroy;
end;

procedure TShutter.ActOnTimer(Sender: TObject);
begin
IncWid;
InvalidateRect(Handle, @FVRect, false);
end;

procedure TShutter.FillBitmap;
begin
//FVRect存储了整张内存位图的区域大小
FVRect := Rect(0, 0, BitMapWid, BitMapHei);
//初始化FMemBitMap的宽度和高度
FMemMskBtMp:= TBitmap.Create;
FMemBitMap := TBitmap.Create;
FMemMskBtMp.Width := BitMapWid;
FMemMskBtMp.Height:= BitMapHei;
FMemBitMap.Width := BitMapWid;
FMemBitMap.Height := BitMapHei;
try
if FBkFileName <> '.\pics\view.bmp' then
FMemMskBtMp.LoadFromFile(FBkFileName);
if FFgFileName <> '.\pics\pic.bmp' then
FMemBitMap.LoadFromFile(FFgFileName);
except
on EFOpenError DO
MessageBox(Handle,'打开文件出错,请重试','提示',MB_OK);
end;
end;

procedure TShutter.IncWid;
begin
if not FOpen and (not FDone) then
begin
if FCurrHei + ShowPixels <= yInc then Inc(FCurrHei, ShowPixels) //为保存位图,不要SetActive(False) else FDone := True; end else if FOpen and(not FDone) then begin if FCurrHei - ShowPixels >= 0 then
Dec(FCurrHei, ShowPixels)
else
FDone := True;
end;
end;

procedure TShutter.Paint;
var
i: Integer;
begin
//如果要查看背景图,直接贴上去
if FViewPic then
BitBlt(Canvas.Handle, 0, 0, BitMapWid, BitMapHei,
FMemBitMap.Canvas.Handle, 0, 0, srcCopy);

if FActive and not FOpen then
for i := 0 to 9 do
BitBlt(Canvas.Handle, 0, i*YInc, BitMapWid, FCurrHei,
FMemBitMap.Canvas.Handle, 0, i*YInc, srcCopy)
else if FActive and FOpen then
begin
if not NFrstm then
begin
for i := 0 to 9 do
BitBlt(Canvas.Handle, 0, i*YInc, BitMapWid, YInc,
FMemBitMap.Canvas.Handle, 0, i*YInc, SRCCOPY);
NFrstm := True;
end
else
for i := 0 to 9 do
BitBlt(Canvas.Handle, 0, i*YInc , BitMapWid, YInc - FCurrHei,
FMemMskBtMp.Canvas.Handle, 0, i*YInc, SRCCOPY);
end
else inherited Paint;
end;

procedure TShutter.SetActive(AValue: Boolean);
begin
if AValue and (not FActive) then
begin
FActive := True;
FillBitmap;
{FViewPic,true则查看位图
FOpen,True则为百叶窗打开模式}
if not FOpen then
FCurrHei := 0
else
FCurrHei := YInc;

try
FTimer.Enabled := True; 
except
EShutterError.Create('Timer初始化出错');
end;
end
else if (not AValue) and FActive then
begin
FTimer.Enabled := False; //停止计时
if Assigned(FOnDone) // fire OnDone event,
then FOnDone(Self);
FActive := False; //停止组件
FMemBitMap.Free; //释放内存位图
FMemMskBtMp.Free; //释放屏蔽位图
Invalidate; //清空组件窗口内容
end;
end;

procedure TShutter.ImageChanged;
begin
if (FMemMskBtMp <> nil) and (FMemBitMap <> nil) then
begin
FMemMskBtMp.FreeImage; //释放所占用的位图资源免得重新加载错误
FMemBitMap.FreeImage;
end;
FillBitmap;
end;

procedure TShutter.CoordinateTimer;
begin
DoTimer;
end;

end.


基本上运行效果还是可以的
但是从代码中可以看到很多的boolean值的参数
它们是用来判断功能从而有选择的调用BitBlt函数
设计还是不够好,其实可以用case语句来区分不同功能
我用了太多的boolean来判断导致扩展起来很不方便,容易出BUG
分享到:
评论

相关推荐

    Delphi实现的百叶窗小程序

    在本案例中,我们讨论的是一个使用Delphi编程语言实现的百叶窗小程序。Delphi是一款强大的Windows应用程序开发工具,以其高效的编译器和面向对象的 Pascal 语言闻名。 首先,我们来了解一下Delphi的基本概念。...

    unigui_slider百叶窗

    Unigui Slider 百叶窗组件是用于Unigui应用程序中的一个强大且灵活的控件。Unigui是一个基于Web的、用Delphi语言开发的用户界面框架,它允许开发者创建富客户端应用,同时提供了丰富的组件库来简化开发流程。百叶窗...

    34种图像特效

    “百叶窗”特效则可能是一种逐格揭示图像的过渡效果,类似于百叶窗一扇扇打开,常用于过渡动画中,增加用户体验的连贯性和趣味性。 “渲染特效(浓雾、反转等)”则是对图像颜色和环境的处理。比如,“浓雾”特效...

    delphi7 copyrect 图片切换效果

    例如,如果要实现一个百叶窗效果,我们可以将一张图片分割成多个小矩形(就像百叶窗的叶片),然后按照一定的顺序依次复制到目标位图上。这种操作可以通过循环和计数器变量来控制,每次只复制一部分,逐渐揭示下一张...

    delphi实现图像之间的平滑过渡

    1. **百叶窗效果**:百叶窗效果是将图像分割成多个小矩形,然后逐个显现或隐藏,模拟百叶窗打开或关闭的过程。这需要计算每个矩形的大小、位置,并根据时间进度控制它们的透明度。可以使用Timer组件来控制动画的节奏...

    delphi图像各种特技 左开 右开 百叶

    在Delphi中,可以使用多个小图像块(就像百叶窗的叶片)并控制它们的显示顺序和速度来实现。 4. **横中开**:图像从中间水平方向向两侧展开,可以想象为一扇门从中线向两边推开。这可以通过分割图像并分别移动两半...

    图像特效Dephi实现

    本项目以Delphi编程语言实现,展示了如何利用Delphi的图形库和自定义算法来设计各种图像特效,如飞入、百叶窗和马赛克等。Delphi是一种强大的对象 Pascal 编程工具,以其高效的编译器和丰富的组件库闻名,常用于开发...

    delphi 开发经验技巧宝典源码

    0101 使用Div函数做整除操作 68 0102 使用DivMod函数返回两个操作数相除的商和余数 68 0103 使用Power函数返回底数的任何次幂 69 0104 使用Round函数将实数四舍五入为整数 69 0105 使用Sqr函数计算指定数的...

    delphi 开发经验技巧宝典源码06

    0101 使用Div函数做整除操作 68 0102 使用DivMod函数返回两个操作数相除的商和余数 68 0103 使用Power函数返回底数的任何次幂 69 0104 使用Round函数将实数四舍五入为整数 69 0105 使用Sqr函数计算指定数的...

Global site tag (gtag.js) - Google Analytics