📄 jvanimatedimage.pas
字号:
Destroying;
FOnFrameChanged := nil;
FOnStart := nil;
FOnStop := nil;
FGlyph.OnChange := nil;
Active := False;
FGlyph.Free;
inherited Destroy;
end;
procedure TJvAnimatedImage.Loaded;
begin
inherited Loaded;
ResetImageBounds;
UpdateInactive;
end;
{$IFDEF VCL}
function TJvAnimatedImage.GetPalette: HPALETTE;
begin
Result := 0;
if not FGlyph.Empty then
Result := FGlyph.Palette;
end;
{$ENDIF VCL}
procedure TJvAnimatedImage.ImageChanged(Sender: TObject);
begin
Lock;
try
FTransparentColor := FGlyph.TransparentColor and not PaletteMask;
finally
Unlock;
end;
DefineBitmapSize;
PictureChanged;
end;
procedure TJvAnimatedImage.UpdateInactive;
begin
if (not Active) and (FInactiveGlyph >= 0) and
(FInactiveGlyph < FNumGlyphs) and (FGlyphNum <> FInactiveGlyph) then
begin
Lock;
try
FGlyphNum := FInactiveGlyph;
finally
Unlock;
end;
end;
end;
function TJvAnimatedImage.TransparentStored: Boolean;
begin
Result := (FGlyph.Empty and (FTransparentColor <> clNone)) or
((FGlyph.TransparentColor and not PaletteMask) <> FTransparentColor);
end;
{$IFDEF VCL}
procedure TJvAnimatedImage.SetTransparent(const Value:Boolean);
begin
if Value <> FTransparent then
begin
Lock;
try
FTransparent := Value;
finally
Unlock;
end;
PictureChanged;
end;
end;
{$ENDIF VCL}
procedure TJvAnimatedImage.SetTransparentColor(Value: TColor);
begin
if Value <> TransparentColor then
begin
Lock;
try
FTransparentColor := Value;
finally
Unlock;
end;
PictureChanged;
end;
end;
procedure TJvAnimatedImage.SetOrientation(Value: TGlyphOrientation);
begin
if FOrientation <> Value then
begin
Lock;
try
FOrientation := Value;
finally
Unlock;
end;
ImageChanged(FGlyph);
end;
end;
procedure TJvAnimatedImage.SetGlyph(Value: TBitmap);
begin
Lock;
try
FGlyph.Assign(Value);
finally
Unlock;
end;
end;
procedure TJvAnimatedImage.SetStretch(Value: Boolean);
begin
if Value <> FStretch then
begin
Lock;
try
FStretch := Value;
finally
Unlock;
end;
PictureChanged;
if Active then
Repaint;
end;
end;
procedure TJvAnimatedImage.SetCenter(Value: Boolean);
begin
if Value <> FCenter then
begin
Lock;
try
FCenter := Value;
finally
Unlock;
end;
PictureChanged;
if Active then
Repaint;
end;
end;
procedure TJvAnimatedImage.SetGlyphNum(Value: Integer);
begin
if Value <> FGlyphNum then
begin
if (Value < FNumGlyphs) and (Value >= 0) then
begin
Lock;
try
FGlyphNum := Value;
finally
Unlock;
end;
UpdateInactive;
FrameChanged;
PictureChanged;
end;
end;
end;
procedure TJvAnimatedImage.SetInactiveGlyph(Value: Integer);
begin
if Value < 0 then
Value := -1;
if Value <> FInactiveGlyph then
begin
if (Value < FNumGlyphs) or (csLoading in ComponentState) then
begin
Lock;
try
FInactiveGlyph := Value;
UpdateInactive;
finally
Unlock;
end;
FrameChanged;
PictureChanged;
end;
end;
end;
procedure TJvAnimatedImage.SetNumGlyphs(Value: Integer);
begin
Lock;
try
FNumGlyphs := Value;
if FInactiveGlyph >= FNumGlyphs then
begin
FInactiveGlyph := -1;
FGlyphNum := 0;
end
else
UpdateInactive;
ResetImageBounds;
finally
Unlock;
end;
FrameChanged;
PictureChanged;
end;
procedure TJvAnimatedImage.DefineBitmapSize;
begin
Lock;
try
FNumGlyphs := 1;
FGlyphNum := 0;
FImageWidth := 0;
FImageHeight := 0;
if (FOrientation = goHorizontal) and (FGlyph.Height > 0) and
(FGlyph.Width mod FGlyph.Height = 0) then
FNumGlyphs := FGlyph.Width div FGlyph.Height
else
if (FOrientation = goVertical) and (FGlyph.Width > 0) and
(FGlyph.Height mod FGlyph.Width = 0) then
FNumGlyphs := FGlyph.Height div FGlyph.Width;
ResetImageBounds;
finally
Unlock;
end;
end;
procedure TJvAnimatedImage.ResetImageBounds;
begin
if FNumGlyphs < 1 then
FNumGlyphs := 1;
if FOrientation = goHorizontal then
begin
FImageHeight := FGlyph.Height;
FImageWidth := FGlyph.Width div FNumGlyphs;
end
else
{if Orientation = goVertical then}
begin
FImageWidth := FGlyph.Width;
FImageHeight := FGlyph.Height div FNumGlyphs;
end;
end;
procedure TJvAnimatedImage.AdjustSize;
begin
{$IFDEF VCL}
if not (csReading in ComponentState) then
if AutoSize and (FImageWidth > 0) and (FImageHeight > 0) then
SetBounds(Left, Top, FImageWidth, FImageHeight);
{$ENDIF VCL}
end;
procedure TJvAnimatedImage.DoPaintImage;
var
BmpIndex: Integer;
SrcRect, DstRect: TRect;
{$IFDEF VisualCLX}
Bmp: TBitmap;
{$ENDIF VisualCLX}
begin
if (not Active) and (FInactiveGlyph >= 0) and
(FInactiveGlyph < FNumGlyphs) then
BmpIndex := FInactiveGlyph
else
BmpIndex := FGlyphNum;
{ copy image from parent and back-level controls }
{$IFDEF VCL}
if Transparent then
CopyParentImage(Self, Canvas);
{$ENDIF VCL}
if (FImageWidth > 0) and (FImageHeight > 0) then
begin
if Orientation = goHorizontal then
SrcRect := Bounds(BmpIndex * FImageWidth, 0, FImageWidth, FImageHeight)
else
{if Orientation = goVertical then}
SrcRect := Bounds(0, BmpIndex * FImageHeight, FImageWidth, FImageHeight);
if Stretch then
DstRect := ClientRect
else
if Center then
DstRect := Bounds((ClientWidth - FImageWidth) div 2,
(ClientHeight - FImageHeight) div 2, FImageWidth, FImageHeight)
else
DstRect := Rect(0, 0, FImageWidth, FImageHeight);
{$IFDEF VCL}
with DstRect do
StretchBitmapRectTransparent(Canvas, Left, Top, Right - Left,
Bottom - Top, SrcRect, FGlyph, FTransparentColor);
{$ENDIF VCL}
{$IFDEF VisualCLX}
Bmp := TBitmap.Create;
try
Bmp.Width := SrcRect.Right - SrcRect.Left;
Bmp.Height := SrcRect.Bottom - SrcRect.Top;
Bmp.TransparentColor := FTransparentColor;
Bmp.Canvas.StretchDraw(Rect(0, 0, Bmp.Width, Bmp.Height), FGlyph);
Canvas.StretchDraw(DstRect, Bmp);
finally
Bmp.Free;
end;
{$ENDIF VisualCLX}
end;
end;
procedure TJvAnimatedImage.BufferedPaint;
begin
PaintImage;
if {$IFDEF VCL} Transparent or {$ENDIF} FGlyph.Empty then
PaintDesignRect;
end;
procedure TJvAnimatedImage.TimerExpired(Sender: TObject);
begin
if csPaintCopy in ControlState then
Exit;
if Visible and (FNumGlyphs > 1) and (Parent <> nil) and
Parent.HandleAllocated then
begin
Lock;
try
if FGlyphNum < FNumGlyphs - 1 then
Inc(FGlyphNum)
else
FGlyphNum := 0;
if (FGlyphNum = FInactiveGlyph) and (FNumGlyphs > 1) then
if FGlyphNum < FNumGlyphs - 1 then
Inc(FGlyphNum)
else
FGlyphNum := 0;
Canvas.Lock;
try
FTimerRepaint := True;
if AsyncDrawing and Assigned(FOnFrameChanged) then
FTimer.Synchronize(FrameChanged)
else
FrameChanged;
DoPaintControl;
finally
FTimerRepaint := False;
Canvas.Unlock;
end;
finally
Unlock;
end;
end;
end;
procedure TJvAnimatedImage.FrameChanged;
begin
if Assigned(FOnFrameChanged) then
FOnFrameChanged(Self);
end;
procedure TJvAnimatedImage.Stop;
begin
if not (csReading in ComponentState) then
if Assigned(FOnStop) then
FOnStop(Self);
end;
procedure TJvAnimatedImage.Start;
begin
if not (csReading in ComponentState) then
if Assigned(FOnStart) then
FOnStart(Self);
end;
{$IFDEF VCL}
function TJvAnimatedImage.CanAutoSize(var NewWidth, NewHeight: Integer): Boolean;
begin
Result := True;
if not (csDesigning in ComponentState) and
(FImageWidth > 0) and (FImageHeight > 0) then
begin
if Align in [alNone, alLeft, alRight] then
NewWidth := FImageWidth;
if Align in [alNone, alTop, alBottom] then
NewHeight := FImageHeight;
end;
end;
{$ENDIF VCL}
procedure TJvAnimatedImage.SetInterval(Value: Cardinal);
begin
FTimer.Interval := Value;
end;
function TJvAnimatedImage.GetInterval: Cardinal;
begin
Result := FTimer.Interval;
end;
procedure TJvAnimatedImage.SetActive(Value: Boolean);
begin
if FActive <> Value then
begin
if Value then
begin
FTimer.OnTimer := TimerExpired;
FTimer.Enabled := True;
FActive := FTimer.Enabled;
Start;
end
else
begin
FTimer.Enabled := False;
FTimer.OnTimer := nil;
FActive := False;
UpdateInactive;
FrameChanged;
Stop;
PictureChanged;
end;
end;
end;
procedure TJvAnimatedImage.SetAsyncDrawing(Value: Boolean);
begin
if FAsyncDrawing <> Value then
begin
Lock;
try
{if Value then
HookBitmap;}
if Assigned(FTimer) then
FTimer.SyncEvent := not Value;
FAsyncDrawing := Value;
finally
Unlock;
end;
end;
end;
{$IFDEF VCL}
procedure TJvAnimatedImage.ReadOpaque(Reader: TReader);
begin
Transparent := not Reader.ReadBoolean;
end;
procedure TJvAnimatedImage.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineProperty('Opaque', ReadOpaque, nil, False);
end;
{$ENDIF VCL}
{$IFDEF UNITVERSIONING}
initialization
RegisterUnitVersion(HInstance, UnitVersioning);
finalization
UnregisterUnitVersion(HInstance);
{$ENDIF UNITVERSIONING}
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -