控件移动类的实现之二

翻译|其它|编辑:郝浩|2005-02-03 11:43:00.000|阅读 1130 次

概述:

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>


面是TDragClass的源代码,比如多,可以拷去机上试试,再慢慢看:


//------TDragClass------------------------

unit uDrag;


interface

uses Windows, Messages,Classes,SysUtils,Controls,Graphics,

uDragPoint,StdCtrls;

type

//控件的八个点,用于拉动大小

TPointRec=record

LeftTop:TDragPoint;

LeftBottom:TDragPoint;

RightTop:TDragPoint;

RightButton:TDragPoint;

LeftMid:TDragPoint;

TopMid:TDragPoint;

RightMid:TDragPoint;

ButtonMid:TDragPoint;

end;



TDragClass=class

private

FConList:TList; //保存控件的列表

FCurActiveCon:Integer; //当前活动控件

FPointRec:TPointRec; //当前控件的边缘的八个小点

//跳跃式移动的成员

FisMoveStep:Boolean;

FMoveStep:integer;

MoveX,MoveY:integer;

//控件事件相关的成员

FConMouseDown:TMouseEvent;

FConMouseMove:TMouseMoveEvent;

FConMouseup:TMouseEvent;

isDown:Boolean;

prevP,nextP:TPoint;

protected

//-------对移动点的操作--

procedure CreateDragPoint(PointParent:TWinControl);

procedure SetPointPos(posRect:TRect);

procedure SetPointParent(PointParent:TWinControl);

procedure SetPointEvent;

procedure SetCurActiveCon(curCon:Pointer);

//----------------------

procedure MoveLeftTopPoint;

procedure AlignLeftTop;

procedure MoveLeftBottomPoint;

procedure AlignLeftBottom;

procedure MoveRightTopPoint;

procedure AlignRightTop;

procedure MoveRightBottomPoint;

procedure AlignRightBottom;

procedure MoveLeftMidPoint;

procedure AlignLeftMid;

procedure MoveTopMidPoint;

procedure AlignTopMid;

procedure MoveRightMidPoint;

procedure AlignRightMid;

procedure MoveBottomMidPoint;

procedure AlignBottomMid;

procedure reSizeCon;

//当前控件事件和移动点事件处理------------

procedure ConMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure ConMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

procedure ConMouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure PointMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

procedure PointMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

procedure PointMouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);



procedure SetisMoveStep(value:Boolean);

procedure SetMoveStep(value:integer);

public

constructor create(PointParent:TWinControl);

destructor destroy; override;

function addControl(AddCon:Pointer):Boolean; //important

procedure SetPointVisible(Visibled:Boolean);

property isMoveStep:Boolean read FisMoveStep write SetisMoveStep;

property MoveStep:Integer read FMoveStep write SetMoveStep;

end;



implementation



{ TDragClass }



constructor TDragClass.create(PointParent:TWinControl);

begin

inherited Create;

FConList:=TList.Create;

FCurActiveCon:=-1;

isDown:=False;

FisMoveStep:=False;

FMoveStep:=5;



FConMouseDown:=ConMouseDown;

FConMouseMove:=ConMouseMove;

FConMouseup:=ConMouseUp;



CreateDragPoint(PointParent);

SetPointVisible(false);

SetPointEvent;

end;



destructor TDragClass.destroy;

begin

FreeAndNil(FConList);

FPointRec.LeftTop.Free;

FPointRec.LeftBottom.Free;

FPointRec.RightTop.Free;

FPointRec.RightButton.Free;

FPointRec.LeftMid.Free;

FPointRec.TopMid.Free;

FPointRec.RightMid.Free;

FPointRec.ButtonMid.Free;

inherited;

end;

//加一个控件进入拖拉类

function TDragClass.addControl(AddCon: Pointer): Boolean;

var TempCon:TControl; R:TRect;

i:integer;

begin

result:=True;

if TControl(AddCon).Parent=nil then

begin

result:=false;

exit;

end;

//如果该控件已经在列表中了,则加入失败

for i:=0 to FConList.Count-1 do

if Integer(AddCon)=Integer(FConList.Items[i]) then

begin

result:=false;

exit;

end;

//将控件加入列表中,并指定当前的控件的索引

FConList.Add(AddCon);

FCurActiveCon:=FConList.Count-1;

TempCon:=TControl(AddCon);

TempCon.Cursor:=crSizeAll;

TempCon.Parent.DoubleBuffered:=True; //使用双缓冲技术

//折中方案,指定控件鼠标事件

TButton(TempCon).OnMouseDown:=FconMouseDown;

TButton(TempCon).OnMouseMove:=FconMouseMove;

TButton(TempCon).OnMouseUp:=FconMouseUp;

//画控件周围的八个小点

R.Left:=TempCon.Left;

R.Top:=TempCon.Top;

R.Right:=TempCon.Left+TempCon.Width;

R.Bottom:=TempCon.Top+TempCon.Height;

SetPointParent(TempCon.Parent);

SetPointPos(R);

SetPointVisible(true);

end;

//设置八小点的可见性

procedure TDragClass.SetPointVisible(Visibled: Boolean);

begin

FPointRec.LeftTop.Visible:=Visibled;

FPointRec.LeftBottom.Visible:=Visibled;

FPointRec.RightTop.Visible:=Visibled;

FPointRec.RightButton.Visible:=Visibled;

FPointRec.LeftMid.Visible:=Visibled;

FPointRec.TopMid.Visible:=Visibled;

FPointRec.RightMid.Visible:=Visibled;

FPointRec.ButtonMid.Visible:=Visibled;

end;

//设置小点事件

procedure TDragClass.SetPointEvent;

begin

FPointRec.LeftTop.OnMouseDown:=PointMouseDown;

FPointRec.LeftTop.OnMouseMove:=PointMouseMove;

FPointRec.LeftTop.onMouseUp:=PointMouseUp;

FPointRec.LeftBottom.OnMouseDown:=PointMouseDown;

FPointRec.LeftBottom.OnMouseMove:=PointMouseMove;

FPointRec.LeftBottom.onMouseUp:=PointMouseUp;

FPointRec.RightTop.OnMouseDown:=PointMouseDown;

FPointRec.RightTop.OnMouseMove:=PointMouseMove;

FPointRec.RightTop.onMouseUp:=PointMouseUp;

FPointRec.RightButton.OnMouseDown:=PointMouseDown;

FPointRec.RightButton.OnMouseMove:=PointMouseMove;

FPointRec.RightButton.onMouseUp:=PointMouseUp;

FPointRec.LeftMid.OnMouseDown:=PointMouseDown;

FPointRec.LeftMid.OnMouseMove:=PointMouseMove;

FPointRec.LeftMid.onMouseUp:=PointMouseUp;

FPointRec.TopMid.OnMouseDown:=PointMouseDown;

FPointRec.TopMid.OnMouseMove:=PointMouseMove;

FPointRec.TopMid.onMouseUp:=PointMouseUp;

FPointRec.RightMid.OnMouseDown:=PointMouseDown;

FPointRec.RightMid.OnMouseMove:=PointMouseMove;

FPointRec.RightMid.onMouseUp:=PointMouseUp;

FPointRec.ButtonMid.OnMouseDown:=PointMouseDown;

FPointRec.ButtonMid.OnMouseMove:=PointMouseMove;

FPointRec.ButtonMid.onMouseUp:=PointMouseUp;

end;

//确定控件边缘八个小点的位置

procedure TDragClass.SetPointPos(posRect: TRect);

begin

FPointRec.LeftTop.Left:=posRect.Left-6;

FPointRec.LeftTop.Top:=posRect.Top-6;



FPointRec.LeftBottom.Left:=PosRect.Left-6;

FPointRec.LeftBottom.Top:=PosRect.Bottom;



FPointRec.RightTop.Left:=posRect.Right;

FPointRec.RightTop.Top:=posRect.Top-6;



FPointRec.RightButton.Left:=PosRect.Right;

FPointRec.RightButton.Top:=PosRect.Bottom;



FPointRec.LeftMid.Left:=posRect.Left-6;

FPointRec.LeftMid.Top:=(posRect.Top+posRect.Bottom) div 2 - 3;



FPointRec.TopMid.Left:=(posRect.Left+posRect.Right) div 2 -3;

FPointRec.TopMid.Top:=PosRect.Top-6;



FPointRec.RightMid.Left:=posRect.Right;

FPointRec.RightMid.Top:=(posRect.Top+posRect.Bottom) div 2 - 3;



FPointRec.ButtonMid.Left:=(posRect.Left+posRect.Right) div 2 -3;

FPointRec.ButtonMid.Top:=PosRect.Bottom;

end;

//创建八个小点

procedure TDragClass.CreateDragPoint(PointParent:TWinControl);

begin

FPointRec.LeftTop:=TDragPoint.Create(nil);

FPointRec.LeftTop.Cursor:=crSizeNWSE;

FPointRec.LeftBottom:=TDragPoint.Create(nil);

FPointRec.LeftBottom.Cursor:=crSizeNESW;

FPointRec.RightTop:=TDragPoint.Create(nil);

FPointRec.RightTop.Cursor:=crSizeNESW;

FPointRec.RightButton:=TDragPoint.Create(nil);

FPointRec.RightButton.Cursor:=crSizeNWSE;

FPointRec.LeftMid:=TDragPoint.Create(nil);

FPointRec.LeftMid.Cursor:=crSizeWE;

FPointRec.TopMid:=TDragPoint.Create(nil);

FPointRec.TopMid.Cursor:=crSizeNS;

FPointRec.RightMid:=TDragPoint.Create(nil);

FPointRec.RightMid.Cursor:=crSizeWE;

FPointRec.ButtonMid:=TDragPoint.Create(nil);

FPointRec.ButtonMid.Cursor:=crSizeNS;

SetPointParent(PointParent);

end;

//------当前控件事件处理-------------------------

//处理点下的事件

procedure TDragClass.ConMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

var TempCon:TControl; R:TRect;

begin

if Button=mbLeft then

begin

isDown:=True;

GetCursorPos(PrevP);

end;

TempCon:=TControl(Sender);

SetPointParent(TempCon.Parent);

R.Left:=TempCon.Left;

R.Top:=TempCon.Top;

R.Right:=TempCon.Left+TempCon.Width;

R.Bottom:=TempCon.Top+TempCon.Height;

MoveX:=0; MoveY:=0;

SetPointPos(R);

SetPointvisible(true);

SetCurActiveCon(TempCon);

end;

//处理当前控件移动的消息

procedure TDragClass.ConMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

var offsetX,offsetY:integer; con:TControl;

r:TRect;

begin

if isDown and (Shift=[ssLeft])then

begin

GetCursorPos(nextP);

offsetX:=NextP.X-PrevP.X;

offSetY:=NextP.Y-PrevP.Y;

Con:=TControl(Sender);

if not FisMoveStep then

begin

Con.Left:=Con.Left+offSetX;

Con.Top:=Con.Top+offSetY;

end

else begin

MoveX:=MoveX+offsetX;

MoveY:=MoveY+offsetY;

if Abs(MoveX)>=FMoveStep then

begin

Con.Left:=Con.Left+MoveX;

MoveX:=0;

end;

if Abs(MoveY)>FMoveStep then

begin

Con.Top:=Con.Top+MoveY;

MoveY:=0;

end;

end;

R.Left:=Con.Left;

R.Top:=Con.Top;

R.Right:=Con.Left+Con.Width;

R.Bottom:=Con.Top+Con.Height;

SetPointPos(R);

prevP:=nextP;

end;

end;

//处理当前控件鼠标弹起的消息

procedure TDragClass.ConMouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

isDown:=False;

end;

//------------------------

//设置八个点的父子关系

procedure TDragClass.SetPointParent(PointParent: TWinControl);

begin

FPointRec.LeftTop.Parent:=PointParent;

FPointRec.LeftBottom.Parent:=PointParent;

FPointRec.RightTop.Parent:=PointParent;

FPointRec.RightButton.Parent:=PointParent;

FPointRec.LeftMid.Parent:=PointParent;

FPointRec.TopMid.Parent:=PointParent;

FPointRec.RightMid.Parent:=PointParent;

FPointRec.ButtonMid.Parent:=PointParent;

end;

//得到当前活动窗口

procedure TDragClass.SetCurActiveCon(curCon: Pointer);

var i:integer;

begin

for i:=0 to FConList.Count-1 do

if Integer(curCon)=Integer(FConList.Items[i]) then

begin

FCurActiveCon:=i;

break;

end;

end;

//----------------------------------

//八个小点的处理消息

procedure TDragClass.PointMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

if Button= mbLeft then

begin

moveX:=0; moveY:=0;

if Sender=FPointRec.LeftTop then

begin

FpointRec.LeftTop.isDown:=True;

GetCursorPos(FPointRec.LeftTop.PrevP);

end

else if Sender=FPointRec.RightTop then

begin

FpointRec.RightTop.isDown:=True;

GetCursorPos(FPointRec.RightTop.PrevP);

end

else if Sender=FPointRec.LeftBottom then

begin

FpointRec.LeftBottom.isDown:=True;

GetCursorPos(FPointRec.LeftBottom.PrevP);

end

else if Sender=FPointRec.RightButton then

begin

FpointRec.RightButton.isDown:=True;

GetCursorPos(FPointRec.RightButton.PrevP);

end

else if Sender=FPointRec.LeftMid then

begin

FpointRec.LeftMid.isDown:=True;

GetCursorPos(FPointRec.LeftMid.PrevP);

end

else if Sender=FPointRec.TopMid then

begin

FpointRec.TopMid.isDown:=True;

GetCursorPos(FPointRec.TopMid.PrevP);

end

else if Sender=FPointRec.RightMid then

begin

FpointRec.RightMid.isDown:=True;

GetCursorPos(FPointRec.RightMid.PrevP);

end

else if Sender=FPointRec.ButtonMid then

begin

FpointRec.ButtonMid.isDown:=True;

GetCursorPos(FPointRec.ButtonMid.PrevP);

end;

end;

end;



procedure TDragClass.PointMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

begin

if Shift=[ssLeft] then

begin

if FPointRec.LeftTop.isDown then

begin

MoveLeftTopPoint;

reSizeCon

end

else if FPointRec.LeftBottom.isDown then

begin

MoveLeftBottomPoint;

reSizeCon

end

else if FPointRec.RightTop.isDown then

begin

MoveRightTopPoint;

reSizeCon

end

else if FPointRec.RightButton.isDown then

begin

MoveRightBottomPoint;

reSizeCon

end

else if FPointRec.LeftMid.isDown then

begin

MoveLeftMidPoint;

reSizeCon

end

else if FPointRec.TopMid.isDown then

begin

MoveTopMidPoint;

reSizeCon

end

else if FPointRec.RightMid.isDown then

begin

MoveRightMidPoint;

reSizeCon

end

else if FPointRec.ButtonMid.isDown then

begin

MoveBottomMidPoint;

reSizeCon

end

end;

end;

 

procedure TDragClass.PointMouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

if Button= mbLeft then

begin

if (FpointRec.LeftTop.isDown) and

(Sender=FpointRec.LeftTop) then

FpointRec.LeftTop.isDown:=False

else if (FpointRec.LeftBottom.isDown) and

(Sender=FpointRec.LeftBottom) then

FpointRec.LeftBottom.isDown:=False

else if (FpointRec.RightTop.isDown) and

(Sender=FpointRec.RightTop) then

FpointRec.RightTop.isDown:=False

else if (FpointRec.RightButton.isDown) and

(Sender=FpointRec.RightButton) then

FpointRec.RightButton.isDown:=False

else if (FpointRec.LeftMid.isDown) and

(Sender=FpointRec.LeftMid) then

FpointRec.LeftMid.isDown:=False

else if (FpointRec.TopMid.isDown) and

(Sender=FpointRec.TopMid) then

FpointRec.TopMid.isDown:=False

else if (FpointRec.RightMid.isDown) and

(Sender=FpointRec.RightMid) then

FpointRec.RightMid.isDown:=False

else if (FpointRec.ButtonMid.isDown) and

(Sender=FpointRec.ButtonMid) then

FpointRec.ButtonMid.isDown:=False;

end;

end;

//左顶点的移动

procedure TDragClass.MoveLeftTopPoint;

var offsetX,offsetY:Integer;

begin

GetCursorPos(FPointRec.LeftTop.NextP);

offsetX:=FPointRec.LeftTop.NextP.X-FPointRec.LeftTop.PrevP.X;

offSetY:=FPointRec.LeftTop.NextP.Y-FPointRec.LeftTop.PrevP.Y;

if not FisMoveStep then

begin

FPointRec.LeftTop.Left:=FPointRec.LeftTop.Left+offsetX;

FPointRec.LeftTop.Top:=FPointRec.LeftTop.Top+offsetY;

end

else begin

MoveX:=MoveX+offsetX;

MoveY:=MoveY+offsetY;

if Abs(moveX)>=FMoveStep then

begin

FPointRec.LeftTop.Left:=FPointRec.LeftTop.Left+moveX;

moveX:=0;

end;

if Abs(moveY)>=FMoveStep then

begin

FPointRec.LeftTop.Top:=FPointRec.LeftTop.Top+moveY;

moveY:=0;

end;

end;

FPointRec.LeftTop.PrevP:=FPointRec.LeftTop.NextP;

AlignLeftTop;

end;

//其他点对齐左右点

 


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP