怎么实现这样的皮筋线?(88分)

  • 主题发起人 主题发起人 Hunj
  • 开始时间 开始时间
H

Hunj

Unregistered / Unconfirmed
GUEST, unregistred user!
用delphi的ImageEditor是用选中工具在位图上画一个矩形,
会发现这个选中区域的边界的虚线是流动的,记得photoshop
也有同样的效果,请问怎么在程序中实现?
 
我刚好在一个报表编辑器中玩过这种东东。代码贴给你:
var
FFlowPointIndexBase:integer=0;
FCurrentRect:TRect;

procedure CanvasDrawFlowRect(Canvas:TCanvas);
var
PointIndex:integer;
procedure DrawFlowLine(X,Y,DeltaX,DeltaY,PointCount,PenColor:integer);
var
i:integer;
begin
for i:=0 to PointCount-1 do
begin
if Odd(PointIndex shr 2) then
Canvas.Pixels[X,Y]:=PenColor xor Canvas.Pixels[X,Y];
Inc(X,DeltaX);
Inc(Y,DeltaY);
Inc(PointIndex);
end;
end;
begin
with Canvas,FCurrentRect do
begin
Pen.Color:=Brush.Color;
PointIndex:=FFlowPointIndexBase;
DrawFlowLine(Left,Top,1,0,Right-Left,Pen.Color);
DrawFlowLine(Right,Top,0,1,Bottom-Top,Pen.Color);
DrawFlowLine(Right,Bottom,-1,0,Right-Left,Pen.Color);
DrawFlowLine(Left,Bottom,0,-1,Bottom-Top,Pen.Color);
end;
end;

procedure TRptPanel.TimerDrawMoveRect(Sender: TObject);
begin
CanvasDrawFlowRect(ParentPanel.Canvas);
Dec(FFlowPointIndexBase);
if FFlowPointIndexBase mod 8=0 then
FFlowPointIndexBase:=0;
CanvasDrawFlowRect(ParentPanel.Canvas);
end;

var
FDrawMoveRectFirst:boolean=True;

procedure TRptPanel.DrawMoveRect(x,y,w,h:integer);
begin
if not FDrawMoveRectFirst then
ReportEditor.RectTimer.OnTimer:=nil;
FCurrentRect:=Rect(x,y,x+w,y+h);
CanvasDrawFlowRect(ParentPanel.Canvas);
if FDrawMoveRectFirst then
ReportEditor.RectTimer.OnTimer:=TimerDrawMoveRect;
FDrawMoveRectFirst:=not FDrawMoveRectFirst;
end;

解释一下:
上面这些代码的功能是当用户拖着报表对象移动时,绘制一个流动的虚框。
流动的原理就是通过时钟中断,反复用不同的参数重新绘虚框。
在报表编辑器ReportEditor中有一个时钟控件(中断间隔约50,设到20则流动较快)。其事
件是在 DrawMoveRect 中设置和取消。
CanvasDrawFlowRect的功能是在Canvas上绘制一个虚框,不修改参数在调一次则隐藏此框,
修改FFlowPointIndexBase后CanvasDrawFlowRect绘制的虚框就流动了一点。顺便提一下,
Dec(FFlowPointIndexBase); 使虚框顺时针方向流动,Inc则反之。
DrawMoveRect必须成对调用:鼠标按下时调用一次,移动之前调用一次,移动之后调用一
次,放开时调用一次,临近的量次必须使用相同的参数。
(88分实在是便宜,哎,... 我何时能致富呀?)

 
接受答案了.
 
后退
顶部