📄 circpic.pas
字号:
///////////////////////
//王昌雨
//2003-06-10
//矩形
///////////////////////
unit CircPic;
interface
uses Windows,Graphics,Math,Classes,Controls,
PicConst,PicBase,PicFuns;
const
FOCUS_NUM=8;
type
TCircPic=Class(TPicBase)
private
StartPos:TPoint;
EndPos:TPoint;
FocusPoint:Array[1..FOCUS_NUM] of TPoint;
CircKeyState: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 ParentMouseDown(ACanvas:TCanvas;CursorNum:Integer; Button: TMouseButton;Shift: TShiftState; APoint:TPoint); override;
procedure ParentMouseMove(ACanvas:TCanvas;CursorNum:Integer; Shift: TShiftState;APoint:TPoint); override;
procedure ParentMouseUp(ACanvas:TCanvas;CursorNum:Integer; Button: TMouseButton; 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;
//图象改变
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; //鼠标当前的坐标
//位置代码可参见 PicConst.pas
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 DrawCircPic(ACanvas: TCanvas; startPoint:TPoint; endPoint:TPoint);
//property 的实现方法
published
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 TCircPic.Create;
begin
inherited Create;
end;
destructor TCircPic.Destroy;
begin
inherited Destroy;
end;
procedure TCircPic.DrawPic(ACanvas:TCanvas); //在acanvas上画图
var
pp: array[1..2] of TPoint;
drawStartPoint: Tpoint;
drawEndPoint: Tpoint;
begin
drawStartPoint := startPos;
drawEndPoint := endPos;
pp[1] := drawStartPoint;
pp[2] := drawEndPoint;
LpToDp(ACanvas.Handle, pp[1], 2); //取得设备坐标
drawStartPoint := pp[1];
drawEndPoint:=pp[2];
ACanvas.Pen:=PicPen;
ACanvas.Brush:=PicBrush;
ACanvas.Font:=PicFont;
DrawCircPic(ACanvas, drawStartPoint, drawEndPoint);
if Choosed then DrawFocusRect(ACanvas);;
end;
procedure TCircPic.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 TCircPic.GetFocusPoints;
begin
focusPoint[1] := startPos; //左上
focusPoint[2] := Point((StartPos.X+ endPos.X)div 2, StartPos.Y); //上中
focusPoint[3] := Point(EndPos.X,StartPos.Y); //右上
focusPoint[4] := Point(StartPos.X,(StartPos.Y+ endPos.Y)div 2); //左中
focusPoint[5] := Point(EndPos.X,(StartPos.Y+ endPos.Y)div 2); //右中
focusPoint[6] := Point(StartPos.X,EndPos.Y); //左下
focusPoint[7] := Point((StartPos.X + endPos.X)div 2, EndPos.Y); //下中
focusPoint[8] := endPos; //终点
end;
function TCircPic.MouseInPicRegion(ACanvas:TCanvas;APoint:TPoint): MOUSE_POS; //鼠标位置
var
mPoint: Tpoint;
mRect: TRect;
FocusNumber: Integer; //焦点数量
i: Integer;
fPicHRGN: HRGN;
begin
result := POS_OUT;
focusNumber := FOCUS_NUM; // =2 焦点数量
fPicHRGN := CreatePicRgn(ACanvas);
//CreateLineRgn(startPoint.x,startPoint.y,endPoint.x,endPoint.y);//,Top,Right,Bottom);
if not Choosed then begin //图元未选中,只要判断是否在图元区域即可
if PtInRegion(fPicHRGN, APoint.x, APoint.y) = True then result := POS_CENTER
end else begin //图元被选中,不仅要判断是否在图元区域,还需要判断在图元的具体位置
if PtInRegion(fPicHRGN, 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_LEFTTOP)- 1 + i);
Break;
end
end;
end;
DeleteObject(fPicHRGN);
end;
function TCircPic.CreatePicRgn(ACanvas:TCanvas): HRGN; //产生图元区域的句柄
var
tempHrgn: HRGN;
diff: Integer;
mRect: TRect;
pp: array[1..2] of TPoint;
begin
diff := 3; //内外矩形与与指定矩形的差距
mRect := PicRect;
with mRect do begin
pp[1].x := Left;
pp[1].y := Top;
pp[2].x := Right;
pp[2].y := Bottom;
LpToDp(ACanvas.Handle, pp[1], 2);
Left := pp[1].x;
Top := pp[1].y;
Right := pp[2].x;
Bottom := pp[2].y;
end;
if PicBrush.Style=bsClear then begin //透明
Result := CreateEllipticRgn(mRect.Left - diff, mRect.Top - diff, mRect.Right+ diff,
mRect.Bottom + diff);
tempHrgn := CreateEllipticRgn(mRect.Left + diff, mRect.Top + diff,mRect.Right - diff,
mRect.Bottom - diff);
CombineRGN(Result, Result, tempHrgn, RGN_DIFF);
DeleteObject(tempHrgn);
end else begin
Result := CreateEllipticRgn(mRect.Left, mRect.Top, mRect.Right, mRect.Bottom);
end;
end;
procedure TCircPic.DrawFocusRect(ACanvas:TCanvas); //在Acanvas上画焦点
var
mRect: 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 //绘制焦点矩形
mRect.Left := focusPoint[i].x - FOCUS_SIZE;
mRect.Top := focusPoint[i].y - FOCUS_SIZE;
mRect.Right := focusPoint[i].x + FOCUS_SIZE;
mRect.Bottom := focusPoint[i].y + FOCUS_SIZE;
ACanvas.Rectangle(mRect.Left, mRect.Top, mRect.Right, mRect.Bottom);
end;
end;
procedure TCircPic.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; //置终点坐标
end;
procedure TCircPic.ParentMouseMove(ACanvas:TCanvas;CursorNum:Integer;
Shift: TShiftState;APoint:TPoint);
var
center: TPoint;
begin
if (ssLeft in shift) then begin //鼠标左键按下
DrawCircPic(ACanvas, StartPos,EndPos);
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 begin
EndPos := APoint;
end;
DrawCircPic(ACanvas, StartPos,EndPos);
end;
end;
procedure TCircPic.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[1], 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;
ACanvas.Font := PicFont;
DrawCircPic(ACanvas, StartPos,EndPos);
if Assigned(DrawEndEvent) then DrawEndEvent(Self);
end;
//键盘响应
procedure TCircPic.ParentKeyDown(ACanvas:TCanvas;CursorNum:Integer; var Key: Word;
mouse: TPoint; Shift:TShiftState);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -