?? curvepic.pas
字號:
unit CurvePic;
interface
uses Windows,Graphics,Math,Classes,Controls,
PicConst,PicBase,PicFuns;
const
FOCUS_NUM=8;
type
TCurvePoint=packed record
aPointNum: Integer;
aCurvePoint:Array[0..3] of TPoint;
end;
type
TCurvePic=Class(TPicBase)
private
FocusPoint:Array[1..FOCUS_NUM] of TPoint;
fCurvePoint:TCurvePoint;
MouseFocus: Integer;
OldPoint: TPoint;
procedure GetFocusPoints;
procedure SetCurvePicRect;
function GetCurvePoint:TCurvePoint;
function GetCurvePointNum:Integer;
procedure SetCurvePointNum(V:Integer);
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 DrawCurvePic(ACanvas: TCanvas; aPoints:Array of TPoint);
//property 的實現方法
published
property CurvePoint: TCurvePoint read GetCurvePoint;
property CurvePointNum:Integer read GetCurvePointNum write SetCurvePointNum;
property PicPen;
property PicBrush;
Property PicFont;
property PicRect;
property Choosed;
property PicId;
property FocusPen;
property FocusBrush;
property DrawEndEvent;
property PicIndex;
end;
implementation
constructor TCurvePic.Create;
begin
inherited Create;
fCurvePoint.aPointNum:=0;
MouseFocus:=-1;
end;
destructor TCurvePic.Destroy;
begin
inherited Destroy;
end;
function TCurvePic.GetCurvePointNum:Integer;
begin
Result:=fCurvePoint.aPointNum;
end;
procedure TCurvePic.SetCurvePointNum(V:Integer);
begin
fCurvePoint.aPointNum:=0;
end;
procedure TCurvePic.GetFocusPoints;
var
StartPos,EndPos:TPoint;
begin
StartPos:=PicRect.TopLeft;
EndPos:=PicRect.BottomRight;
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;
procedure TCurvePic.SetCurvePicRect;
var
i:Integer;
tmpRect:TRect;
begin
with tmpRect do begin
Left := fCurvePoint.aCurvePoint[0].x;
Top := fCurvePoint.aCurvePoint[0].y;
Right := fCurvePoint.aCurvePoint[0].x;
Bottom:= fCurvePoint.aCurvePoint[0].y;
end;
with tmpRect do begin
for i := 1 to fCurvePoint.aPointNum-1 do begin
Left := Min(Left, fCurvePoint.aCurvePoint[i].x);
Top := Min(Top, fCurvePoint.aCurvePoint[i].y);
Right := Max(Right, fCurvePoint.aCurvePoint[i].x);
Bottom:= Max(Bottom, fCurvePoint.aCurvePoint[i].y);
end; //調整起點和終點的位置
if Right = Left then Inc(Right);
if Top = Bottom then Inc(Bottom);
end;
PicRect:=tmpRect;
end;
function TCurvePic.GetCurvePoint:TCurvePoint;
begin
Result:=fCurvePoint;
end;
procedure TCurvePic.DrawPic(ACanvas:TCanvas); //在acanvas上畫圖
begin
ACanvas.Pen:=PicPen;
ACanvas.Brush:=PicBrush;
ACanvas.Font:=PicFont;
DrawCurvePic(ACanvas,fCurvePoint.aCurvePoint);
if Choosed then DrawFocusRect(ACanvas);
end;
procedure TCurvePic.MovePic(ACanvas:TCanvas; APoint:TPoint); //在acanvas上移動
var
i: Integer;
begin
for i := 0 to fCurvePoint.aPointNum-1 do begin
Inc(fCurvePoint.aCurvePoint[i].x, APoint.X);
Inc(fCurvePoint.aCurvePoint[i].y, APoint.Y);
end;
//調整圖元矩形區域
SetCurvePicRect;
end;
function TCurvePic.MouseInPicRegion(ACanvas:TCanvas;APoint:TPoint): MOUSE_POS; //鼠標位置
var
mRect: TRect;
mPoint: Tpoint;
i: Integer;
polyHrgn: HRGN;
begin
Result := POS_OUT;
mPoint.x := APoint.X;
mPoint.y := APoint.Y;
polyHrgn := CreatePicRgn(ACanvas); //產生圖元句柄
if not Choosed then begin //圖元未選中,只要判斷是否在圖元區域即可
if PtInRegion(polyHrgn, APoint.x, APoint.y) = True then Result := POS_CENTER
end else begin //圖元被選中,不僅要判斷是否在圖元區域,還需要判斷在圖元的具體位置
if PtInRegion(polyHrgn, APoint.x, APoint.y) = True then Result := POS_CENTER;
GetFocusPoints;
for i := 1 to 8 do begin //先判斷多邊形所在矩形的8個焦點
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(i);
MouseFocus := 0;
break;
end;
end;
for i := 0 to fCurvePoint.aPointNum-1 do begin
with mRect do begin
Left := fCurvePoint.aCurvePoint[i].x - FOCUS_SIZE;
Top := fCurvePoint.aCurvePoint[i].y - FOCUS_SIZE;
Right := fCurvePoint.aCurvePoint[i].x + FOCUS_SIZE;
Bottom := fCurvePoint.aCurvePoint[i].y + FOCUS_SIZE;
end;
if PtInRect(mrect, mPoint) = True then begin
MouseFocus := i;
Result := POS_CURVEPOINT;
break;
end;
end;
end;
DeleteObject(polyHrgn);
end;
function TCurvePic.CreatePicRgn(ACanvas:TCanvas): HRGN; //產生圖元區域的句柄
var
i: Integer;
drawVerPoint: array[0..4] of TPoint;
begin
for i := 0 to 3 do drawVerPoint[i] :=fCurvePoint.aCurvePoint[i];
LpToDp(ACanvas.Handle, drawVerPoint[0], 4);
Result := CreatePolygonRgn(drawVerPoint[0], 4, ALTERNATE);
end;
procedure TCurvePic.DrawFocusRect(ACanvas:TCanvas); //在Acanvas上畫焦點
var
mRect: TRect;
i: Integer;
begin
GetFocusPoints;
ACanvas.Pen:=FocusPen;
ACanvas.Brush:=FocusBrush;
for i := 1 to FOCUS_NUM 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;
for i := 0 to fCurvePoint.aPointNum-1 do begin //繪制焦點矩形
ACanvas.Brush.Color:=clLime;
mRect.Left := fCurvePoint.aCurvePoint[i].x - FOCUS_SIZE;
mRect.Top := fCurvePoint.aCurvePoint[i].y - FOCUS_SIZE;
mRect.Right := fCurvePoint.aCurvePoint[i].x + FOCUS_SIZE;
mRect.Bottom:= fCurvePoint.aCurvePoint[i].y + FOCUS_SIZE;
ACanvas.Rectangle(mRect.Left, mRect.Top, mRect.Right, mRect.Bottom);
end;
end;
//鼠標響應
procedure TCurvePic.ParentMouseDown(ACanvas:TCanvas;CursorNum:Integer; Button: TMouseButton;Shift: TShiftState; APoint:TPoint);
var
i:Integer;
begin
if Button=mbLeft then begin
OldPoint:=APoint;
ACanvas.Pen:=PicPen; //設置pen的格式
ACanvas.Pen.Mode:=pmXor;
//設置Brush的格式
ACanvas.Brush:=PicBrush;
Inc(fCurvePoint.aPointNum); //頂點數量加1
case fCurvePoint.aPointNum of
1: //鼠標第一次按下 bezier 起點
begin
fCurvePoint.aCurvePoint[0]:=APoint;
For i:=1 to 3 do fCurvePoint.aCurvePoint[i]:=fCurvePoint.aCurvePoint[0];
end;
2: // bezier 終點
begin
ACanvas.PolyBezier(fCurvePoint.aCurvePoint);
fCurvePoint.aCurvePoint[3]:=APoint;
PicId:=PIC_CURVE;
end;
3: //bezier 控制點1
begin
ACanvas.PolyBezier(fCurvePoint.aCurvePoint);
fCurvePoint.aCurvePoint[1]:=APoint;
end;
4: //bezier 控制點2
begin
ACanvas.PolyBezier(fCurvePoint.aCurvePoint);
fCurvePoint.aCurvePoint[2]:=APoint;
//曲線的四點輸入完畢 調整總數組中的有關數據
//SetCurvePicRect;
//if Choosed then DrawFocusRect(ACanvas);
//if Assigned(DrawEndEvent) then DrawEndEvent(Self);
end;
end;
end else if Button=mbRight then begin
if fCurvePoint.aPointNum =1 then begin
ACanvas.PolyBezier(fCurvePoint.aCurvePoint);
fCurvePoint.aPointNum:=0;
PicId:=PIC_NONE;
end;
end;
end;
procedure TCurvePic.ParentMouseMove(ACanvas:TCanvas;CursorNum:Integer; Shift: TShiftState;APoint:TPoint);
begin
if fCurvePoint.aPointNum > 0 then begin //繪制多邊形開始
ACanvas.Pen:=PicPen; //設置pen的格式
ACanvas.Pen.Mode:=pmXor;
//設置Brush的格式
ACanvas.Brush:=PicBrush;
case fCurvePoint.aPointNum of
1:
begin
OldPoint:=fCurvePoint.aCurvePoint[3];
ACanvas.PolyBezier(fCurvePoint.aCurvePoint);
fCurvePoint.aCurvePoint[3] := APoint;
ACanvas.PolyBezier(fCurvePoint.aCurvePoint);
end;
2:
begin
OldPoint:=fCurvePoint.aCurvePoint[1];
ACanvas.PolyBezier(fCurvePoint.aCurvePoint);
fCurvePoint.aCurvePoint[1] := APoint;
ACanvas.PolyBezier(fCurvePoint.aCurvePoint);
end;
3:
begin
OldPoint:=fCurvePoint.aCurvePoint[2];
ACanvas.PolyBezier(fCurvePoint.aCurvePoint);
fCurvePoint.aCurvePoint[2] := APoint;
ACanvas.PolyBezier(fCurvePoint.aCurvePoint);
end;
end;
end;
end;
procedure TCurvePic.ParentMouseUp(ACanvas:TCanvas;CursorNum:Integer; Button: TMouseButton; Shift: TShiftState; APoint:TPoint);
begin //
if fCurvePoint.aPointNum=4 then begin
SetCurvePicRect;
if Choosed then DrawFocusRect(ACanvas);
if Assigned(DrawEndEvent) then DrawEndEvent(Self);
end;
end;
//鍵盤響應
procedure TCurvePic.ParentKeyDown(ACanvas:TCanvas;CursorNum:Integer; var Key: Word; mouse: TPoint; Shift:TShiftState);
begin
end;
procedure TCurvePic.ParentKeyUp(ACanvas:TCanvas;CursorNum:Integer; var Key: Word; mouse: TPoint; Shift: TShiftState);
begin
end;
//圖象改變
procedure TCurvePic.PicChangeing(ACanvas:TCanvas; mouseInPos: MOUSE_POS; chooseRect:TRect;
mouseDownOldX, mouseDownOldY, mouseOldX, mouseOldY, mouseX, mouseY:Integer);
var
mouseDiffX: Integer;
mouseDiffY: Integer;
Center:TPoint;
ratex,ratey:Single;
RectW,RectH: Integer; //選擇圖元的寬度和高度
tmpPoint:Array of TPoint;
pp: array[1..3] of TPoint;
i: Integer;
procedure ConverPointXY;
var
j: Integer;
begin
for j:= 0 to fCurvePoint.aPointNum-1 do begin
tmpPoint[j].x := center.x + Round((fCurvePoint.aCurvePoint[j].x - center.x) * rateX);
tmpPoint[j].y := center.y + Round((fCurvePoint.aCurvePoint[j].y - center.y) * rateY);
end;
end;
procedure ChangPointXY; //坐標變換 是否交換起點和鐘點
begin
//頂點坐標變換
LpToDp(ACanvas.Handle, tmpPoint[0],fCurvePoint.aPointNum);
DrawCurvePic(ACanvas, tmpPoint);
end;
begin
pp[1].x := mouseDownOldX;
pp[1].y := mouseDownOldY;
pp[2].x := mouseOldX;
pp[2].y := mouseOldY;
pp[3].x := mouseX;
pp[3].y := mouseY;
DPtoLP(ACanvas.Handle, pp[1], 3);
mouseDownOldX := pp[1].x;
mouseDownOldY := pp[1].y;
mouseOldX := pp[2].x;
mouseOldY := pp[2].y;
mouseX := pp[3].x;
mouseY := pp[3].y;
//設置繪圖方式
ACanvas.Pen.Width := 1;
ACanvas.Pen.Mode := pmXor;
ACanvas.Pen.Style := psDot;
ACanvas.Brush.Style := bsClear;
//初始化變量值
RectW:=ChooseRect.Right - ChooseRect.Left;
RectH:=ChooseRect.Bottom - ChooseRect.Top;
//設置數組長度
SetLength(tmpPoint, fCurvePoint.aPointNum);
//計算選擇圖元的寬度和高度
case mouseInPos of
POS_LEFTTOP: // :Integer = 1 ; //左上
begin
//確定基準點
Center.X:=ChooseRect.Right;
Center.y := ChooseRect.Bottom;
//鼠標當前位置與鼠標Down的差別
mouseDiffX := mouseOldX - mouseDownOldX;
mouseDiffY := mouseOldY - mouseDownOldY;
//計算變化比例
Ratex := (RectW - mouseDiffX) / RectW;
Ratey := (RectH - mouseDiffY) / RectH;
//繪制前一次虛線圖元
ConverPointXY;
ChangPointXY;
//鼠標當前位置與鼠標Down的差別
mouseDiffX := mouseX - mouseDownOldX;
mouseDiffY := mouseY - mouseDownOldY;
//計算變化比例
Ratex := (RectW - mouseDiffX) / RectW;
Ratey := (RectH - mouseDiffY) / RectH;
//繪制當前虛線圖元
ConverPointXY;
ChangPointXY;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -