俺最近看完了Delphi6 Develop Guid 的关于编写控件的章节,算是学有所成吧:今天俺用Delphi编写了第一个控件。尽管还是参考了书上的例子,但是小弟收获甚多啊!确实啊,真正的高手应该是那群控件编写者啊!现在把部分代码贴出来给大家看看。需要的请到这里下载:
http://blog.blogchina.com/upload/2004-12-10/20041210235227604838.rar
unit MHMarquee;interfaceuses
SysUtils, Windows, Classes, Forms, Controls, Graphics,
Messages, ExtCtrls, Dialogs;const
ScrollPixels = 1; // num of pixels for each scroll
TimerInterval = 50; // time between scrolls in ms
implementationconstructor TMHMarquee.Create(AOwner: TComponent);
{ constructor for TMHMarquee class } procedure DoTimer;
{ procedure sets up TMHMarquee's timer }
begin
FTimer := TTimer.Create(Self);
with FTimer do
begin
Enabled := False; Interval := TimerInterval;
OnTimer := DoTimerOnTimer;
end;
end;begin
inherited Create(AOwner);
FItems := TStringList.Create; { instanciate string list }
DoTimer; { set up timer }
{ set instance variable default values }
Width := 100;
Height := 75;
FActive := False;
FCircleShow := false; //初始没有循环播放
FScrollRight := false; //初始向右
BevelWidth := 3;
// FJust := tjCenter;
FSideWidth:= BorderWidth+2*BevelWidth;
end;destructor TMHMarquee.Destroy;
{ destructor for TMHMarquee class }
begin
SetActive(False);
FTimer.Free; // free allocated objects
FItems.Free;
inherited Destroy;
end;procedure TMHMarquee.DoTimerOnTimer(Sender: TObject);
{ This method is executed in respose to a timer event }
begin
IncLine;
{ only repaint within borders }
InvalidateRect(Handle, @InsideRect, False);
end;procedure TMHMarquee.IncLine;
{ this method is called to increment a line }
begin
if FScrollRight then ////向右 if Marquee is scrolling upward
begin
{ Check to see if marquee has scrolled to end yet }
if FItems.Count * LineHi + width+FSideWidth >= CurrLine then
{ not at end, so increment current line }
Inc(CurrLine, ScrollPixels)
else
begin
if FCircleShow then //循环处理
SetStartLine
else
SetActive(False);
end;
end
else begin // if Marquee is scrolling downward
{ Check to see if marquee has scrolled to end yet }
if CurrLine >= FSideWidth then
{ not at end, so decrement current line }
Dec(CurrLine, ScrollPixels)
else
begin
if FCircleShow then
SetStartLine
else
SetActive(False);
end;
end;
end;procedure TMHMarquee.SetItems(Value: TStringList);
procedure DoFItems;
var
tList:TstringList;
i,j:integer;
tStr1,tStr:WideString; //使用unicode,可以兼容所有的字符
begin
tList := TstringList.Create;
try
for i:=0 to Value.Count-1 do
begin
tStr1:=Value[i];
tStr:='';
while j<= Length(tStr1) do
begin
tStr :=tStr+tStr1[j]+#13;
inc(j);
tList.Add(string(tStr));
end;
FItems.Assign(tList);
finally
tList.Free;
end; end;begin
if FItems <> Value then
DoFItems;
end;procedure TMHMarquee.SetLineWidth
;
{ this virtual method sets the LineHi instance variable }
var
Metrics : TTextMetric;
begin
{ get metric info for font }
GetTextMetrics(Canvas.Handle, Metrics);
{ 获得每个汉字的最大宽度 }
LineHi := Metrics.tmMaxCharWidth ;
end;procedure TMHMarquee.SetStartLine;
{ this virtual method initializes the CurrLine instance variable }
begin
// initialize current line to top if scrolling up, or...
if FScrollRight then CurrLine := FSideWidth //向右
// bottom if scrolling down
else CurrLine := VRect.right-width+FSideWidth ; //向左
end;procedure TMHMarquee.PaintLine(R: TRect; LineNum: Integer);
{ this method is called to paint each line of text onto MemBitmap }
var
S: string;
begin
{ Copy next line to local variable for clarity }
S := FItems.Strings[LineNum];
{ Draw line of text onto memory bitmap }
DrawText(MemBitmap.Canvas.Handle, PChar(s), Length(s),R,DT_LEFT); //画一列文字end;
procedure TMHMarquee.FillBitmap;
var
x, i : Integer;
R: TRect;
begin
SetLineWidth; // set height of each line
{ VRect rectangle represents entire memory bitmap }
VRect := Rect(0, 0, Width*2+ LineHi * FItems.Count,Height);
{ InsideRect rectangle represents interior of beveled border }//?
InsideRect := Rect(FSideWidth, FSideWidth, Width - (FSideWidth),
Height - (FSideWidth));
R := Rect(InsideRect.Left, InsideRect.Top, InsideRect.Left+LineHi, InsideRect.Bottom);
SetStartLine;
MemBitmap.Height := Height; // initialize memory bitmap
with MemBitmap do
begin
Width := VRect.Right;
with Canvas do
begin
Font := Self.Font;
Brush.Color := Color;
FillRect(VRect);
Brush.Style := bsClear;
end;
end;
x := width;
i := 0;
repeat
R.left := x;
R.Right:= x+Linehi;
PaintLine(R, i);
{ increment y by the height (in pixels) of a line }
inc(x, LineHi);
inc(i);
until i >= FItems.Count; // repeat for all lines
end;procedure TMHMarquee.Paint;
{ this virtual method is called in response to a }
{ Windows paint message }
begin
if FActive then
{ Copy from memory bitmap to screen }
BitBlt(Canvas.Handle, insideRect.Left , insideRect.Top , width-2*FSideWidth, height-2*FSideWidth,
MemBitmap.Canvas.Handle, currLine, FSideWidth, srcCopy)
else
inherited Paint;
end;procedure TMHMarquee.SetActive(Value: Boolean);
{ called to activate/deactivate the marquee }
begin
if Value and (not FActive) and (FItems.Count > 0) then
begin
FActive := True; // set active flag
MemBitmap := TBitmap.Create;
FillBitmap; // Paint Image on bitmap
FTimer.Enabled := True; // start timer
end
else if (not Value) and FActive then
begin
FTimer.Enabled := False; // disable timer,
if Assigned(FOnDone) // fire OnDone event,
then FOnDone(Self);
FActive := False; // set FActive to False
MemBitmap.Free; // free memory bitmap
Invalidate; // clear control window
end;
end;procedure TMHMarquee.SetTimerActive(Value: Boolean);
begin
if assigned(FTimer) and FActive then //只对Factive=true有效
begin
if FTimer.Enabled and (not Value) then
FTimer.Enabled := false
else if (not FTimer.Enabled) and Value then
FTimer.Enabled := true; end;end;procedure TMHMarquee.SetTimerInterval(Value: integer);
begin
if Value<=0 then exit;
if FTimer.Enabled = true then
begin
SetTimerActive(false);
FTimer.Interval := Value;
SetTimerActive(true);
end
else
FTimer.Interval := Value;
end;procedure TMHMarquee.SetCircleShow(Value: Boolean);
begin
if FCircleShow <> Value then
FCircleShow := Value;
end;end.
http://blog.blogchina.com/upload/2004-12-10/20041210235227604838.rar
unit MHMarquee;interfaceuses
SysUtils, Windows, Classes, Forms, Controls, Graphics,
Messages, ExtCtrls, Dialogs;const
ScrollPixels = 1; // num of pixels for each scroll
TimerInterval = 50; // time between scrolls in ms
implementationconstructor TMHMarquee.Create(AOwner: TComponent);
{ constructor for TMHMarquee class } procedure DoTimer;
{ procedure sets up TMHMarquee's timer }
begin
FTimer := TTimer.Create(Self);
with FTimer do
begin
Enabled := False; Interval := TimerInterval;
OnTimer := DoTimerOnTimer;
end;
end;begin
inherited Create(AOwner);
FItems := TStringList.Create; { instanciate string list }
DoTimer; { set up timer }
{ set instance variable default values }
Width := 100;
Height := 75;
FActive := False;
FCircleShow := false; //初始没有循环播放
FScrollRight := false; //初始向右
BevelWidth := 3;
// FJust := tjCenter;
FSideWidth:= BorderWidth+2*BevelWidth;
end;destructor TMHMarquee.Destroy;
{ destructor for TMHMarquee class }
begin
SetActive(False);
FTimer.Free; // free allocated objects
FItems.Free;
inherited Destroy;
end;procedure TMHMarquee.DoTimerOnTimer(Sender: TObject);
{ This method is executed in respose to a timer event }
begin
IncLine;
{ only repaint within borders }
InvalidateRect(Handle, @InsideRect, False);
end;procedure TMHMarquee.IncLine;
{ this method is called to increment a line }
begin
if FScrollRight then ////向右 if Marquee is scrolling upward
begin
{ Check to see if marquee has scrolled to end yet }
if FItems.Count * LineHi + width+FSideWidth >= CurrLine then
{ not at end, so increment current line }
Inc(CurrLine, ScrollPixels)
else
begin
if FCircleShow then //循环处理
SetStartLine
else
SetActive(False);
end;
end
else begin // if Marquee is scrolling downward
{ Check to see if marquee has scrolled to end yet }
if CurrLine >= FSideWidth then
{ not at end, so decrement current line }
Dec(CurrLine, ScrollPixels)
else
begin
if FCircleShow then
SetStartLine
else
SetActive(False);
end;
end;
end;procedure TMHMarquee.SetItems(Value: TStringList);
procedure DoFItems;
var
tList:TstringList;
i,j:integer;
tStr1,tStr:WideString; //使用unicode,可以兼容所有的字符
begin
tList := TstringList.Create;
try
for i:=0 to Value.Count-1 do
begin
tStr1:=Value[i];
tStr:='';
while j<= Length(tStr1) do
begin
tStr :=tStr+tStr1[j]+#13;
inc(j);
tList.Add(string(tStr));
end;
FItems.Assign(tList);
finally
tList.Free;
end; end;begin
if FItems <> Value then
DoFItems;
end;procedure TMHMarquee.SetLineWidth
;
{ this virtual method sets the LineHi instance variable }
var
Metrics : TTextMetric;
begin
{ get metric info for font }
GetTextMetrics(Canvas.Handle, Metrics);
{ 获得每个汉字的最大宽度 }
LineHi := Metrics.tmMaxCharWidth ;
end;procedure TMHMarquee.SetStartLine;
{ this virtual method initializes the CurrLine instance variable }
begin
// initialize current line to top if scrolling up, or...
if FScrollRight then CurrLine := FSideWidth //向右
// bottom if scrolling down
else CurrLine := VRect.right-width+FSideWidth ; //向左
end;procedure TMHMarquee.PaintLine(R: TRect; LineNum: Integer);
{ this method is called to paint each line of text onto MemBitmap }
var
S: string;
begin
{ Copy next line to local variable for clarity }
S := FItems.Strings[LineNum];
{ Draw line of text onto memory bitmap }
DrawText(MemBitmap.Canvas.Handle, PChar(s), Length(s),R,DT_LEFT); //画一列文字end;
procedure TMHMarquee.FillBitmap;
var
x, i : Integer;
R: TRect;
begin
SetLineWidth; // set height of each line
{ VRect rectangle represents entire memory bitmap }
VRect := Rect(0, 0, Width*2+ LineHi * FItems.Count,Height);
{ InsideRect rectangle represents interior of beveled border }//?
InsideRect := Rect(FSideWidth, FSideWidth, Width - (FSideWidth),
Height - (FSideWidth));
R := Rect(InsideRect.Left, InsideRect.Top, InsideRect.Left+LineHi, InsideRect.Bottom);
SetStartLine;
MemBitmap.Height := Height; // initialize memory bitmap
with MemBitmap do
begin
Width := VRect.Right;
with Canvas do
begin
Font := Self.Font;
Brush.Color := Color;
FillRect(VRect);
Brush.Style := bsClear;
end;
end;
x := width;
i := 0;
repeat
R.left := x;
R.Right:= x+Linehi;
PaintLine(R, i);
{ increment y by the height (in pixels) of a line }
inc(x, LineHi);
inc(i);
until i >= FItems.Count; // repeat for all lines
end;procedure TMHMarquee.Paint;
{ this virtual method is called in response to a }
{ Windows paint message }
begin
if FActive then
{ Copy from memory bitmap to screen }
BitBlt(Canvas.Handle, insideRect.Left , insideRect.Top , width-2*FSideWidth, height-2*FSideWidth,
MemBitmap.Canvas.Handle, currLine, FSideWidth, srcCopy)
else
inherited Paint;
end;procedure TMHMarquee.SetActive(Value: Boolean);
{ called to activate/deactivate the marquee }
begin
if Value and (not FActive) and (FItems.Count > 0) then
begin
FActive := True; // set active flag
MemBitmap := TBitmap.Create;
FillBitmap; // Paint Image on bitmap
FTimer.Enabled := True; // start timer
end
else if (not Value) and FActive then
begin
FTimer.Enabled := False; // disable timer,
if Assigned(FOnDone) // fire OnDone event,
then FOnDone(Self);
FActive := False; // set FActive to False
MemBitmap.Free; // free memory bitmap
Invalidate; // clear control window
end;
end;procedure TMHMarquee.SetTimerActive(Value: Boolean);
begin
if assigned(FTimer) and FActive then //只对Factive=true有效
begin
if FTimer.Enabled and (not Value) then
FTimer.Enabled := false
else if (not FTimer.Enabled) and Value then
FTimer.Enabled := true; end;end;procedure TMHMarquee.SetTimerInterval(Value: integer);
begin
if Value<=0 then exit;
if FTimer.Enabled = true then
begin
SetTimerActive(false);
FTimer.Interval := Value;
SetTimerActive(true);
end
else
FTimer.Interval := Value;
end;procedure TMHMarquee.SetCircleShow(Value: Boolean);
begin
if FCircleShow <> Value then
FCircleShow := Value;
end;end.
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货