⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linepic.pas

📁 很不错的delphi 画失量图的delphi源代码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
////////////////////////
//王昌雨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 + -