📄 linepic.pas
字号:
////////////////////////
//王昌雨2004-05-28
//直线
///////////////////////
unit LinePic;
interface
uses Windows,Classes,Controls,Graphics,Math,
PicConst,Picbase,PicFuns;
const
FOCUS_NUM=2;
type
TLinePic=Class(TPicBase)
private
StartPos:TPoint;
EndPos:TPoint;
OldStartPos:TPoint;
OldEndPos:TPoint;
FocusPoint:Array[1..FOCUS_NUM]of TPoint;
LineKeyState:TShiftState;
procedure GetFocusPoints;
protected
public
constructor Create;
destructor Destroy; override;
procedure DrawPic(ACanvas:TCanvas); override; //在acanvas上画图
procedure MovePic(ACanvas:TCanvas; APoint:TPoint); override; //在acanvas上移动
function MouseInPicRegion(ACanvas:TCanvas;APoint:TPoint): MOUSE_POS; override; //鼠标位置
function CreatePicRgn(ACanvas:TCanvas): HRGN; override; //产生图元区域的句柄
procedure DrawFocusRect(ACanvas:TCanvas); override; //在Acanvas上画焦点
procedure PicChangeing(ACanvas:TCanvas; mouseInPos: MOUSE_POS; chooseRect:TRect;
mouseDownOldX, mouseDownOldY, mouseOldX, mouseOldY, mouseX, mouseY:Integer); override;
procedure PicChangedUpdate(ACanvas:TCanvas; mouseInPos: MOUSE_POS; chooseRect: TRect; //选择图元形成的矩形
mouseDownOldX, mouseDownOldY: Integer; mouseX, mouseY: Integer); override; //鼠标当前的坐标
//鼠标响应
procedure ParentMouseDown(ACanvas:TCanvas;CursorNum:Integer; Button: TMouseButton;Shift: TShiftState; APoint:TPoint); override;
procedure ParentMouseUp(ACanvas:TCanvas;CursorNum:Integer; Button: TMouseButton; Shift: TShiftState; APoint:TPoint); override;
procedure ParentMouseMove(ACanvas:TCanvas;CursorNum:Integer; Shift: TShiftState;APoint:TPoint); override;
//键盘响应
procedure ParentKeyDown(ACanvas:TCanvas;CursorNum:Integer; var Key: Word; mouse: TPoint; Shift:TShiftState); override;
procedure ParentKeyUp(ACanvas:TCanvas;CursorNum:Integer; var Key: Word; mouse: TPoint; Shift: TShiftState); override;
//判断(x,y) 点是否在图元矩形区域内
procedure AssignPic(SourcePic: TPicBase); override;
//保存和读取数据
procedure GetClassDataFromChar(var Len:Integer; var Buf:Array of Char); override;
procedure SaveClassDataToChar(var Len:Integer; var Buf:Array of Char); override;
//非重载函数
//绘图函数
procedure DrawLinePic(ACanvas: TCanvas; startPoint:TPoint; endPoint:TPoint);
published
//property 的实现方法
property PicStartPoint:TPoint read StartPos write StartPos;
property PicEndPoint: TPoint read EndPos write EndPos;
////////////////////////由基类继承
property PicPen;
property PicBrush;
Property PicFont;
property PicRect;
property Choosed;
property PicId;
property FocusPen;
property FocusBrush;
property DrawEndEvent;
property PicIndex;
end;
implementation
constructor TLinePic.Create;
begin
Inherited Create;
end;
destructor TLinePic.Destroy;
begin
inherited Destroy;
end;
procedure TLinePic.DrawPic(ACanvas:TCanvas); //在acanvas上画图
var
pp: array[1..2] of TPoint;
dt: array[1..2] of TPoint;
begin
ACanvas.Pen := PicPen;
ACanvas.Brush :=PicBrush;
ACanvas.Font := PicFont;
pp[1]:=StartPos;
pp[2]:=EndPos;
LpToDp(ACanvas.Handle,pp[1],2);
dt[1]:=pp[1];
dt[2]:=pp[2];
DrawLinePic(ACanvas, dt[1], dt[2]);
if Choosed then DrawFocusRect(ACanvas);
end;
procedure TLinePic.MovePic(ACanvas:TCanvas; APoint:TPoint); //在acanvas上移动
var
tmprect:TRect;
begin
Inc(startPos.x, APoint.X);
Inc(startPos.y, APoint.y);
Inc(endpos.x, APoint.x);
Inc(endpos.y, APoint.y);
//调整图元矩形区域
tmprect.Left := Min(startPos.x, endPos.x);
tmprect.Top := Min(startPos.y, endpos.Y);
tmprect.Right := Max(startPos.x, endpos.x);
tmprect.Bottom := Max(startPos.y, endPos.y);
if tmprect.Right = tmprect.Left then Inc(tmprect.Right, 2);
if tmprect.Top = tmprect.Bottom then Inc(tmprect.Bottom, 2);
PicRect:=tmpRect;
end;
procedure TLinePic.GetFocusPoints;
begin
focusPoint[1] := startPos; //起点
focusPoint[2] := endPos; //终点
end;
function TLinePic.MouseInPicRegion(ACanvas:TCanvas;APoint:TPoint): MOUSE_POS; //鼠标位置
var
mPoint: Tpoint;
mRect: TRect;
FocusNumber: Integer; //焦点数量
i: Integer;
lineHRGN: HRGN;
begin
result := POS_OUT;
focusNumber := FOCUS_NUM; // =2 焦点数量
lineHRGN := CreatePicRgn(ACanvas);
//CreateLineRgn(startPoint.x,startPoint.y,endPoint.x,endPoint.y);//,Top,Right,Bottom);
if not Choosed then begin //图元未选中,只要判断是否在图元区域即可
if PtInRegion(lineHrgn, APoint.x, APoint.y) = True then result := POS_CENTER
end else begin //图元被选中,不仅要判断是否在图元区域,还需要判断在图元的具体位置
if PtInRegion(lineHrgn, APoint.x, APoint.y) = True then result := POS_CENTER;
GetFocusPoints; //焦点坐标
LpToDp(ACanvas.Handle,focuspoint[1],focusnumber);
mPoint:=APoint;
for i := 1 to focusNumber do begin
with mRect do begin
Left := focusPoint[i].x - FOCUS_SIZE;
Top := focusPoint[i].y - FOCUS_SIZE;
Right := focusPoint[i].x + FOCUS_SIZE;
Bottom := focusPoint[i].y + FOCUS_SIZE;
end;
if PtInRect(mRect, mPoint) = True then begin
Result := MOUSE_POS(Ord(POS_LINESTART)- 1 + i);
Break;
end
end;
end;
DeleteObject(lineHrgn);
end;
function TLinePic.CreatePicRgn(ACanvas:TCanvas): HRGN; //产生图元区域的句柄
var
pp: array[1..2] of TPoint;
begin
pp[1] := StartPos;
pp[2] := EndPos;
LpToDp(ACanvas.Handle,pp[1],2);
Result := CreateLineRgn(pp[1].x, pp[1].y, pp[2].x, pp[2].y);
end;
procedure TLinePic.DrawFocusRect(ACanvas:TCanvas); //在Acanvas上画焦点
var
mLine: TRect;
FocusNumber: Integer; //焦点数量
i: Integer;
begin
focusNumber := FOCUS_NUM; //=2 焦点数量
GetFocusPoints; //焦点坐标
LpToDp(ACanvas.Handle,FocusPoint[1],FocusNumber);
ACanvas.Pen:=FocusPen;
ACanvas.Brush:=FocusBrush;
for i := 1 to focusNumber do begin //绘制焦点矩形
mLine.Left := focusPoint[i].x - FOCUS_SIZE;
mLine.Top := focusPoint[i].y - FOCUS_SIZE;
mLine.Right := focusPoint[i].x + FOCUS_SIZE;
mLine.Bottom := focusPoint[i].y + FOCUS_SIZE;
ACanvas.Rectangle(mLine.Left, mLine.Top, mLine.Right, mLine.Bottom);
end;
end;
//鼠标响应
procedure TLinePic.ParentMouseDown(ACanvas:TCanvas;CursorNum:Integer; Button: TMouseButton;Shift: TShiftState; APoint:TPoint);
begin
if Button = mbRight then Exit;
//设置pen的格式
ACanvas.Pen:=PicPen;
ACanvas.Pen.Mode:=pmXor;
//设置Brush的格式
ACanvas.Brush:=PicBrush;
StartPos:=APoint; //设置图元的起点
EndPos := APoint; //置终点坐标
OldStartPos := StartPos;
OldEndPos := endPos;
end;
procedure TLinePic.ParentMouseMove(ACanvas:TCanvas;CursorNum:Integer; Shift: TShiftState;APoint:TPoint);
var
center: TPoint;
lineAngle: Integer;
distance: Single;
begin
oldendPos:=APoint;
if (ssLeft in shift) then begin //鼠标左键按下
DrawLinePic(ACanvas, StartPos,EndPos);
if (ssShift in shift) and (ssCtrl in shift) then begin
Center.x := (startPos.x + endPos.x) div 2;
Center.y := (startPos.y + endPos.y) div 2;
distance := Sqrt(Sqr(APoint.x - Center.x) + Sqr(APoint.y - Center.y)); //鼠标位置与起点之间的距离
lineAngle := Round(ArcTan2(APoint.y - startPos.y, APoint.x - startPos.x) * 180 / Pi);//角度
lineAngle := Round(lineAngle / MinAngle + 0.4899) * MinAngle; //保证角度为MinAngle度的倍数
startPos.x := Center.x - Round(distance * Cos(lineAngle * Pi / 180));
startPos.y := Center.y - Round(distance * Sin(lineAngle * Pi / 180));
endPos.x := Center.x + Round(distance * Cos(lineAngle * Pi / 180));
endPos.y := Center.y + Round(distance * Sin(lineAngle * Pi / 180));
end else if ssCtrl in shift then begin //ssCtrl 键按下 以中心点为起点绘制椭圆
Center.x := (startPos.x + endPos.x) div 2;
Center.y := (startPos.y + endPos.y) div 2;
startPos.x := center.x - (APoint.x - center.x);
startPos.y := center.y - (APoint.y - center.y);
endPos.x := center.x + (APoint.x - center.x);
endPos.y := center.y + (APoint.y - center.y);
end else if ssShift in shift then begin //Shift 键按下 以左上角为起点绘制圆
distance := Sqrt(Sqr(APoint.x - startPos.x) + Sqr(APoint.y - startPos.y)); //鼠标位置与起点之间的距离
lineAngle := Round(ArcTan2(APoint.y - startPos.y, APoint.x - startPos.x) * 180 / Pi); //角度
lineAngle := Round(lineAngle / MinAngle + 0.4899) * MinAngle; //保证角度为MinAngle度的倍数
endPos.x := startPos.x + Round(distance * Cos(lineAngle * Pi / 180));
endPos.y := startPos.y + Round(distance * Sin(lineAngle * Pi / 180));
end else begin
EndPos := APoint;
end;
DrawLinePic(ACanvas, StartPos,EndPos);
end;
end;
procedure TLinePic.ParentMouseUp(ACanvas:TCanvas;CursorNum:Integer; Button: TMouseButton; Shift: TShiftState; APoint:TPoint);
var
tmpRect:TRect;
pp: array[1..2] of TPoint;
begin
//保证绘制的图元尺寸的最小值
if ((Abs(endPos.x - startPos.x) < MinCellSize) and (Abs(endPos.y - startPos.y) < MinCellSize)) then begin
endPos.x := startpos.x + MinCellSize;
endPos.y := startpos.y + MinCellSize;
end;
pp[1] := startPos;
pp[2] := endPos;
DpToLp(ACanvas.Handle, pp, 2);
startPos := pp[1];
endPos := pp[2];
tmpRect.Left := Min(startPos.x, endPos.x);
tmpRect.Top := Min(startPos.y, endPos.y);
tmpRect.Right := Max(startPos.x, endPos.x);
tmpRect.Bottom := Max(startPos.y, endPos.y);
if tmpRect.Left =tmpRect.Right then Inc(tmpRect.Right);
if tmpRect.Top =tmpRect.Bottom then Inc(tmpRect.Bottom);
StartPos:=tmprect.TopLeft;
EndPos:=tmprect.BottomRight;
PicRect:=tmpRect;
//绘制矩形
ACanvas.Pen := PicPen;
ACanvas.Brush := PicBrush;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -