Contributor: UDO JUERSS
{
 This component uses the VGA standard 8x16 font. No resources are used.
 properties description:
 property BackGround: Background color of panel. Not visible if size is 1,
 because pixeldensity is too high.
 property BevelOuter: as usual.
 property BevelInner: as usual.
 property BevelWidth: as usual.
 property Characters: How many Character are displayed in panel.
 Increasing this slows down the outputspeed.
 property OffColor: Color of Pixels not set in character.
 property OnColor: Color of Pixels set in character.
 property OnComplete: Fired if output of RunText completed.
 property Running: Flag if horizontal scrolling is active.
 property RunText: Outputstring.
 property ScrollBy: Number of pixels per horizontal scroll.
 property ScrollInterval: Cycletime of horizontal scrolling.
 property Size: Size of output. If set to 1 character size is 8x16
 pixels. Increasing size decreases display contrast.
 Contact: Udo Juerss, 57078 Siegen, Germany, CompuServe [101364,526]
 Previously published by me: Luffing switch (March 8. 1996)
 Scaleable LED light (March 10. 1996)
 If someone makes useful enhances or corrections to these components,
 please send me an update!
 March 11. 1996
}
unit
 Marquee;
{------------------------------------------------------------------------------}
interface
uses
 WinTypes, WinProcs, Messages, Classes, Graphics, Controls, ExtCtrls;
{------------------------------------------------------------------------------}
const
 Dual: array[0..7] of Byte = (1,2,4,8,16,32,64,128);
{------------------------------------------------------------------------------}
type
 TMarquee = class(TGraphicControl)
 private
 Timer: TTimer;
 FBackGround: TColor;
 FBevelOuter: TPanelBevel;
 FBevelInner: TPanelBevel;
 FBevelWidth: Byte;
 FBkGnd: TColor;
 FCharacters: Byte;
 FScrollInterval: Word;
 FOffColor: TColor;
 FOnColor: TColor;
 FOnComplete: TNotifyEvent;
 FRunning: Boolean;
 FRunText: string;
 FSize: Byte;
 FScrollBy: Byte;
 Border:Byte;
 Index: Byte;
 WorkString: string;
 PixelPos: Byte;
 CharOfs: Word;
 TextLen: Byte;
 XPos: Integer;
 YPos: Integer;
 procedure Draw;
 procedure DrawText(Shift:Boolean);
 procedure GetCharData(Character: Char);
 procedure PutVerticalPixels(Horizontal: Byte);
 procedure Setup;
 procedure ShiftString;
 procedure TimerShift(Sender: TObject);
 protected
 procedure DrawBevel(Rect: TRect);
 procedure SetBackGround(Value: TColor);
 procedure SetBevelOuter(Value: TPanelBevel);
 procedure SetBevelInner(Value: TPanelBevel);
 procedure SetBevelWidth(Value: Byte);
 procedure SetCharacters(Value: Byte);
 procedure SetScrollInterval(Value: Word);
 procedure SetOffColor(Value: TColor);
 procedure SetOnColor(Value: TColor);
 procedure SetRunning(Value: Boolean);
 procedure SetRunText(Value: string);
 procedure SetSize(Value: Byte);
 procedure SetScrollBy(Value: Byte);
 public
 constructor Create(AOwner: TComponent); override;
 destructor Destroy; override;
 procedure Clear;
 procedure Paint; override;
 published
 property BackGround: TColor read FBackGround write SetBackGround default clBlack;
 property BevelOuter: TPanelBevel read FBevelOuter write SetBevelOuter default bvRaised;
 property BevelInner: TPanelBevel read FBevelInner write SetBevelInner default bvLowered;
 property BevelWidth: Byte read FBevelWidth write SetBevelWidth default 2;
 property Characters: Byte read FCharacters write SetCharacters default 7;
 property ScrollInterval: Word read FScrollInterval write SetScrollInterval default 50;
 property OffColor: TColor read FOffColor write SetOffColor default clGray;
 property OnColor: TColor read FOnColor write SetOnColor default clLime;
 property OnComplete: TNotifyEvent read FOnComplete write FOnComplete;
 property Running: Boolean read FRunning write SetRunning default False;
 property RunText: string read FRunText write SetRunText;
 property ScrollBy: Byte read FScrollBy write SetScrollBy default 1;
 property Size: Byte read FSize write SetSize default 2;
 end;
{------------------------------------------------------------------------------}
procedure GetFontOfs(CharSet: Byte; var FntOfs: Word);
function SegC000: Word;
procedure Register;
implementation
{------------------------------------------------------------------------------}
var
 CharArray: array[0..15] of Byte;
 FontPtr: Pointer;
 FontOfs: Word;
{------------------------------------------------------------------------------}
procedure GetFontOfs(CharSet: Byte; var FntOfs: Word); assembler;
asm
 push bp
 mov ax,1130h
 mov bh,CharSet
 int 10h
 mov ax,bp
 pop bp
 les di,FntOfs
 stosw
end;
{------------------------------------------------------------------------------}
function SegC000: Word; external 'KERNEL' Index 195;
{------------------------------------------------------------------------------}
constructor TMarquee.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
 Parent:=AOwner as TWinControl;
 Canvas.Brush.Style:=bsSolid;
 Timer:=nil;
 FBackGround:=clBlack;
 FBevelOuter:=bvRaised;
 FBevelInner:=bvLowered;
 FBevelWidth:=2;
 FCharacters:=7;
 FScrollInterval:=50;
 FOffColor:=clGray;
 FOnColor:=clLime;
 FOnComplete:=nil;
 FRunning:=False;
 FRunText:='RunText ';
 FSize:=2;
 FScrollBy:=1;
 Border:=2;
 GetFontOfs(6,FontOfs);
 FontPtr:=Ptr(Ofs(SegC000),FontOfs);
 PixelPos:=0;
 TextLen:=Length(FRunText);
 Index:=0;
 WorkString:=FRunText;
 Setup;
 Draw;
end;
{------------------------------------------------------------------------------}
destructor TMarquee.Destroy;
begin
 if FRunning then SetRunning(False);
 inherited Destroy;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.Paint;
begin
 Draw;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.Clear;
var
 Temp: Byte;
begin
 Temp:=FOnColor;
 FOnColor:=FOffColor;
 DrawText(False);
 FOnColor:=Temp;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.Draw;
var
 R: TRect;
begin
 R:=GetClientRect;
 DrawBevel(R);
 Canvas.Pen.Color:=FBackGround;
 Canvas.Brush.Color:=FBackGround;
 InflateRect(R,-Border,-Border);
 Canvas.FillRect(R);
 DrawText(False);
end;
{------------------------------------------------------------------------------}
procedure TMarquee.DrawBevel(Rect: TRect);
var
 TopColor: TColor;
 BottomColor: TColor;
 procedure SetColors(Bevel: TPanelBevel);
 begin
 TopColor:=clBtnHighlight;
 if Bevel = bvLowered then TopColor:=clBtnShadow;
 BottomColor:=clBtnShadow;
 if Bevel = bvLowered then BottomColor:=clBtnHighlight;
 end;
begin
 if FBevelOuter  bvNone then
 begin
 SetColors(BevelOuter);
 Frame3D(Canvas,Rect,TopColor,BottomColor,BevelWidth);
 end;
 if FBevelInner  bvNone then
 begin
 SetColors(FBevelInner);
 Frame3D(Canvas,Rect,TopColor,BottomColor,FBevelWidth);
 end;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.DrawText(Shift: Boolean);
var
 Pos: Byte;
 I: Byte;
 R: TRect;
begin
 R:=GetClientRect;
 XPos:=R.Left + Border;
 YPos:=R.Top + Border;
 GetCharData(WorkString[1]);
 for I:=PixelPos to 7 do PutVerticalPixels(I);
 for Pos:=2 to FCharacters do
 begin
 GetCharData(WorkString[Pos]);
 for I:=0 to 7 do PutVerticalPixels(I);
 end;
 GetCharData(WorkString[Succ(FCharacters)]);
 for I:=0 to PixelPos do PutVerticalPixels(I);
 if Shift then Inc(PixelPos,FScrollBy);
 if PixelPos> 7 then
 begin
 PixelPos:=0;
 ShiftString;
 end;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.GetCharData(Character: Char); assembler;
asm
 push ds
 push ds
 pop es
 mov di,offset CharArray
 xor bh,bh
 mov bl,Character
 shl bx,4
 lds si,FontPtr
 add si,bx
 mov cx,16
@MovsLoop: push cx
 lodsb
 mov ah,0
 mov cx,8
@RolLoop: rol al,1
 adc ah,0
 ror ah,1
 loop @RolLoop
 mov al,ah
 stosb
 pop cx
 loop @MovsLoop
 pop ds
end;
{------------------------------------------------------------------------------}
procedure TMarquee.PutVerticalPixels(Horizontal: Byte);
var
 Vertical: Byte;
begin
 for Vertical:=0 to 15 do
 begin
 if CharArray[Vertical] and Dual[Horizontal]> 0 then
 Canvas.Pixels[XPos,YPos + Vertical * FSize]:=FOnColor
 else Canvas.Pixels[XPos,YPos + Vertical * FSize]:=FOffColor;
 end;
 Inc(XPos,FSize);
end;
{------------------------------------------------------------------------------}
procedure TMarquee.TimerShift(Sender: TObject);
begin
 DrawText(True);
end;
{------------------------------------------------------------------------------}
procedure TMarquee.ShiftString;
begin
 Inc(Index);
 if FCharacters>= TextLen - Index then
 begin
 WorkString:=Copy(FRunText,Succ(Index),TextLen - Index);
 WorkString:=WorkString + Copy(RunText,1,Succ(FCharacters) - (TextLen - Index));
 end
 else WorkString:=Copy(FRunText,Succ(Index),Succ(FCharacters));
 if Index>= TextLen then
 begin
 Index:=0;
 if Assigned(FOnComplete) then FOnComplete(Self);
 end;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.Setup;
begin
 Width:=FSize * 8 * FCharacters + 2 * Border + 1;
 Height:=FSize * 16 + 2 * Border;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.SetBackGround(Value: TColor);
begin
 if FBackGround  Value then
 begin
 FBackGround:=Value;
 Draw;
 end;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.SetBevelOuter(Value: TPanelBevel);
begin
 if FBevelOuter  Value then
 begin
 FBevelOuter:=Value;
 if FBevelOuter  bvNone then Border:=FBevelWidth else Border:=0;
 if FBevelInner  bvNone then Inc(Border,FBevelWidth);
 Setup;
 Draw;
 end;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.SetBevelInner(Value: TPanelBevel);
begin
 if FBevelInner  Value then
 begin
 FBevelInner:=Value;
 if FBevelOuter  bvNone then Border:=FBevelWidth else Border:=0;
 if FBevelInner  bvNone then Inc(Border,FBevelWidth);
 Setup;
 Draw;
 end;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.SetBevelWidth(Value: Byte);
begin
 if FBevelWidth  Value then
 begin
 FBevelWidth:=Value;
 if FBevelOuter  bvNone then Border:=FBevelWidth else Border:=0;
 if FBevelInner  bvNone then Inc(Border,FBevelWidth);
 Setup;
 Draw;
 end;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.SetCharacters(Value: Byte);
var
 I: Byte;
begin
 if Value < 1 then Value:=1 else if Value> 80 then Value:=80;
 if FCharacters  Value then
 begin
 FCharacters:=Value;
 if TextLen < FCharacters then begin for I:=TextLen to FCharacters do FRunText:=FRunText + ' '; TextLen:=Byte(FRunText[0]); end; SetUp; Draw; end; end; {------------------------------------------------------------------------------} procedure TMarquee.SetScrollInterval(Value: Word); begin if FScrollInterval  Value then
 begin
 FScrollInterval:=Value;
 if FRunning and Assigned(Timer) then Timer.Interval:=FScrollInterval;
 end;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.SetSize(Value: Byte);
begin
 if Value < 1 then Value:=1 else if Value> 8 then Value:=8;
 if FSize  Value then
 begin
 FSize:=Value;
 SetUp;
 Draw;
 end;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.SetScrollBy(Value: Byte);
begin
 if Value < 1 then Value:=1 else if Value> 8 then Value:=8;
 if FScrollBy  Value then FScrollBy:=Value;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.SetOffColor(Value: TColor);
begin
 if FOffColor  Value then
 begin
 FOffColor:=Value;
 Draw;
 end;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.SetOnColor(Value: TColor);
begin
 if FOnColor  Value then
 begin
 FOnColor:=Value;
 Draw;
 end;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.SetRunning(Value: Boolean);
begin
 if FRunning  Value then
 begin
 FRunning:=Value;
 if FRunning then
 begin
 Timer:=TTimer.Create(Self);
 Timer.Interval:=FScrollInterval;
 Timer.OnTimer:=TimerShift;
 Timer.Enabled:=True;
 end
 else if Assigned(Timer) then
 begin
 Timer.Free;
 Timer:=nil;
 end;
 end;
end;
{------------------------------------------------------------------------------}
procedure TMarquee.SetRunText(Value: string);
var
 I: Byte;
begin
 Index:=0;
 FRunText:=Value;
 TextLen:=Byte(FRunText[0]);
 if TextLen < FCharacters then for I:=TextLen to FCharacters do FRunText:=FRunText + ' ';
 TextLen:=Byte(FRunText[0]);
end;
{------------------------------------------------------------------------------}
procedure Register;
begin
 RegisterComponents('Udo|s',[TMarquee]);
end;
{------------------------------------------------------------------------------}
initialization
end.


AltStyle によって変換されたページ (->オリジナル) /