?? arccpic.pas
字號:
unit ArccPic;
interface
uses Windows,Graphics,Math,Classes,Controls,
PicConst,PicBase,PicFuns;
const
FOCUS_NUM=10;
type
TArccType=(Arcc_Arc,Arcc_Sector,Arcc_Chord); //圓弧,扇形, 玄
type
TArcDrawState=(ARC_DRAW,ARC_SET); //準備畫,開始畫,設置
type
TArccPic=Class(TPicBase)
private
StartPos:TPoint;
EndPos:TPoint;
FocusPoint:Array[1..FOCUS_NUM] of TPoint;
ArcStartPos:TPoint;
ArcEndPos:TPoint;
fArccType:TArccType;
//ArccKeyState:TShiftState;
fDrawState: TArcDrawState;
procedure GetFocusPoints;
procedure SetPicArccType(aArccType:TArccType);
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 DrawArccPic(ACanvas: TCanvas; startPoint:TPoint; endPoint:TPoint;ArcsPoint:TPoint;ArcePoint:TPoint);
//property 的實現方法
published
property PicStartPoint:TPoint read StartPos write StartPos;
property PicEndPoint: TPoint read EndPos write EndPos;
property PicArcStart: TPoint read ArcStartPos write ArcStartPos;
property PicArcStop: TPoint read ArcEndPos Write ArcEndPos;
property PicArccType: TArccType read fArccType write SetPicArccType;
property PicPen;
property PicBrush;
Property PicFont;
property PicRect;
property Choosed;
property PicId;
property FocusPen;
property FocusBrush;
property DrawEndEvent;
property PicIndex;
end;
implementation
constructor TArccPic.Create;
begin
inherited Create;
FArccType:=ARCC_ARC; //圓弧
fDrawState:=ARC_DRAW; //正在畫
end;
destructor TArccPic.Destroy;
begin
inherited Destroy;
end;
procedure TArccPic.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; //終點
focusPoint[9] := ArcStartPos;
focusPoint[10]:= ArcEndPos;
end;
procedure TArccPic.SetPicArccType(aArccType:TArccType);
begin
if FArccType<>aArccType then fArccType:=aArccType;
end;
procedure TArccPic.DrawPic(ACanvas:TCanvas); //在acanvas上畫圖
var
pp: array[1..4] of TPoint;
drawStartPoint: Tpoint;
drawEndPoint: Tpoint;
DrawarcsPoint: TPoint;
DrawarcePoint: TPoint;
begin
drawStartPoint := startPos;
drawEndPoint := endPos;
drawarcsPoint:=ArcStartPos;
drawarcePoint:=ArcEndPos;
pp[1] := drawStartPoint;
pp[2] := drawEndPoint;
pp[3] := drawarcsPoint;
pp[4] := drawarcePoint;
LpToDp(ACanvas.Handle, pp[1], 4); //取得設備坐標
drawStartPoint := pp[1];
drawEndPoint:=pp[2];
drawarcsPoint:=pp[3];
drawarcePoint:=pp[4];
ACanvas.Pen:=PicPen;
ACanvas.Brush:=PicBrush;
ACanvas.Font:=PicFont;
DrawArccPic(ACanvas, drawStartPoint, drawEndPoint,drawarcsPoint,DrawarcePoint);
if Choosed then DrawFocusRect(ACanvas);
end;
procedure TArccPic.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;
function TArccPic.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 := FocusNumber Downto 1 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
if i>8 then begin
Result := MOUSE_POS(Ord(POS_ARCSTART)- 1 + (i-8));
end else begin
Result := MOUSE_POS(Ord(POS_LEFTTOP)- 1 + i);
end; // =14 圓弧起點
Break;
end
end;
end;
DeleteObject(fPicHrgn);
end;
function TArccPic.CreatePicRgn(ACanvas:TCanvas): HRGN; //產生圖元區域的句柄
var
hrgnFlag: Integer;
tmpHrgn: HRGN;
centerX, centerY: Integer; //圓心坐標
pp: array[1..4] of TPoint;
begin
pp[1] := StartPos;
pp[2] := Endpos;
pp[3] := ArcStartPos;
pp[4] := ArcendPos;
LpToDp(ACanvas.Handle, pp[1], 4);
hrgnFlag:=0; Result:=0;
case fArccType of
Arcc_Arc: //Arc
begin
hrgnFlag := 0; //圓弧
end;
Arcc_Sector: //Chord
begin
if PicBrush.style = bsClear then
hrgnflag := 1 //chird and clear
else
hrgnflag := 2; //chord and solid
end;
Arcc_Chord: //Pie
begin
if PicBrush.style = bsClear then
hrgnflag := 3 //Pie and clear
else
hrgnflag := 4; //Pie and solid
end;
end;
case hrgnFlag of
0: //Arc
begin
Result := CreateArcRgn(pp[1],pp[2],pp[3],pp[4]);
end;
1: //chord and clear
begin
Result := CreateArcRgn(pp[1],pp[2],pp[3],pp[4]);
tmpHrgn := CreateLineRgn(arcStartPos.x, arcStartPos.y,arcEndPos.x, arcEndPos.y);
CombineRGN(Result, Result, tmpHrgn, RGN_OR);
DeleteObject(tmpHrgn);
end;
2: //chord and solid
begin
Result := CreatePieRgn(pp[1],pp[2],pp[3],pp[4],Ord(fArccType));
end;
3: //Pie and clear
begin
centerX := (StartPos.x + endPos.x) div 2; //圓心坐標
centerY := (Startpos.y + endPos.y) div 2;
Result := CreateArcRgn(pp[1],pp[2],pp[3],pp[4]);
//起點至圓心
tmpHrgn := CreateLineRgn(arcStartPos.x, arcStartPos.y, centerX, centerY);
CombineRGN(Result, Result, tmpHrgn, RGN_OR);
//終點至圓心
tmpHrgn := CreateLineRgn(arcEndPos.x, arcEndPos.y, centerX, centerY);
CombineRGN(Result, Result, tmpHrgn, RGN_OR);
DeleteObject(tmpHrgn);
end;
4: //Pie and solid
begin
Result:= CreatePieRgn(pp[1],pp[2],pp[3],pp[4],Ord(fArcctype));
end;
end;
end;
procedure TArccPic.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 //繪制焦點矩形
if i>8 then ACanvas.Brush.Color:=clLime;
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 TArccPic.ParentMouseDown(ACanvas:TCanvas;CursorNum:Integer;
Button: TMouseButton;Shift: TShiftState; APoint:TPoint);
var
pp:TPoint;
begin
if Button = mbRight then Exit;
//設置pen的格式
ACanvas.Pen:=PicPen;
ACanvas.Pen.Mode:=pmXor;
//設置Brush的格式
ACanvas.Brush:=PicBrush;
case fDrawState of
ARC_DRAW:
begin
StartPos:=APoint; //設置圖元的起點
EndPos := APoint; //置終點坐標
ArcStartPos:=APoint;
ArcEndPos:=APoint;
end;
ARC_SET: //確定圓弧的終點,圓弧的起點由mouseUp確定
begin
pp :=PointToCirclePoint(StartPos,EndPos, APoint);
DpToLp(ACanvas.Handle, pp, 1);
ArcEndPos:=pp;
end;
end;
end;
procedure TArccPic.ParentMouseMove(ACanvas:TCanvas;CursorNum:Integer;
Shift: TShiftState;APoint:TPoint);
var
radiu: Integer;
centerX, centerY: Integer;
pp: array[1..4] of TPoint;
begin
case fDrawState of
ARC_DRAW: //確定圓弧半徑和起點
begin
if (ssLeft in Shift) then begin
//清除前一次繪制的圖形
DrawArccPic(ACanvas,StartPos,EndPos,ArcStartPos,ArcEndPos);
//繪制當前的圖形
centerX := (endPos.X + StartPos.x) div 2; //圓心
centerY := (EndPos.y + StartPos.y) div 2;
radiu := round(sqrt(sqr(Apoint.X - centerX) + sqr(Apoint.Y - centerY))); //半徑
StartPos.x := centerX - radiu; //調整圓弧的四角坐標
StartPos.y := centerY - radiu;
endPos.x := centerX + radiu;
EndPos.y := centerY + radiu;
DrawArccPic(ACanvas,StartPos,EndPos,ArcStartPos,ArcEndPos);
end;
end;
ARC_SET: //確定圓弧終點
begin
//設置pen的格式
ACanvas.Pen:=PicPen;
ACanvas.Pen.Mode:=pmXor;
//設置Brush的格式
ACanvas.Brush:=PicBrush;
centerX := (EndPos.x + StartPos.x) div 2; //圓心
centerY := (EndPos.y + StartPos.y) div 2;
//清除前一次繪制的圖形
//if fArccType<>ARCC_SECTOR then begin
ACanvas.MoveTo(centerX, centerY);
ACanvas.LineTo(arcEndPos.x, arcEndPos.y);
//end;
DrawArccPic(ACanvas,StartPos,EndPos,ArcStartPos,ArcEndPos);
//繪制當前的圖形
pp[1] :=PointToCirclePoint(StartPos,EndPos, APoint);
DpToLp(ACanvas.Handle, pp[1], 1);
arcEndPos := pp[1]; //確定新的圓弧終點
//if fArccType<>ARCC_SECTOR then begin
ACanvas.MoveTo(centerX, centerY);
ACanvas.LineTo(arcEndPos.x, arcEndPos.y);
//end;
DrawArccPic(ACanvas,StartPos,EndPos,ArcStartPos,ArcEndPos);
end;
end;
end;
procedure TArccPic.ParentMouseUp(ACanvas:TCanvas;CursorNum:Integer;
Button: TMouseButton; Shift: TShiftState; APoint:TPoint);
var
pp: array[1..4] of TPoint;
tmpRect:TRect;
centerx,centery:Integer;
begin
case fDrawState of
ARC_DRAW: //確定半徑和圓弧的起點
begin
arcStartPos:=APoint;
arcEndPos := APoint;
if ((Abs(EndPos.x - StartPos.x) < MinCellSize) or
(Abs(EndPos.y - StartPos.y) < MinCellSize)) then begin
endPos.x := endPos.x + MinCellSize;
endpos.y := endpos.y + MinCellSize;
end;
pp[1] := StartPos;
pp[2] := EndPos;
pp[3] := arcStartPos;
pp[4] := arcEndPos;
DpToLp(ACanvas.Handle, pp[1], 4);
StartPos := pp[1];
endPos := pp[2];
arcStartPos := pp[3];
arcEndPos := pp[4];
with tmpRect do begin //保證右下角坐標大于,等于左上角坐標
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -