首先,你这个矩形应该是一个控件,可以直接从TCustomControl中继承下来,
重写其Paint方法即可。还需要一个AttachSizer方法如下:
procedure AttachSizer(Sender: TObject);
begin
TSizer.Create(FOwner, Sender as TCustomControl, FDefaultWidth, FDefaultHeight);
end;
其次,如下写一个TSizer控件,这是一个透明包含控件,在选定矩形控件后, 调用其AttachSizer方法动态创建TSizer控件。 声明如下:
const
sc_DragMove: LongInt = $F012; type
TSizer = class(TCustomControl)
private
FControl: TCustomControl;
FRectList: array[1..8] of TRect;
FPosList: array[1..8] of Integer;
public
constructor Create(AOwner: TComponent; AControl: TCustomControl);
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateHandle; override;
procedure WmNcHitTest(var Msg: TWmNcHitTest); message wm_NcHitTest;
procedure WmSize(var Msg: TWmSize); message wm_Size;
procedure WmLButtonDown(var Msg: TWmLButtonDown); message wm_LButtonDown;
procedure WmMove(var Msg: TWmMove); message wm_Move;
procedure Paint; override;
procedure SizerControlExit(Sender: TObject);
end;
实现如下:
constructor TSizer.Create(AOwner: TComponent; AControl: TCustomControl);
var
R: TRect;
begin
inherited Create(AOwner);
FControl := AControl;
//制定OnExit事件的处理程序
OnExit := SizerControlExit;
//设置大小和位置
R := FControl.BoundsRect;
//缩小边界
InflateRect(R, 2, 2);
BoundsRect := R;
//设置父组件
Parent := FControl.Parent;
//创建位置列表
FPosList[1] := htTopLeft;
FPosList[2] := htTop;
FPosList[3] := htTopRight;
FPosList[4] := htRight;
FPosList[5] := htBottomRight;
FPosList[6] := htBottom;
FPosList[7] := htBottomLeft;
FposList[8] := htLeft;
end; //设置新控件为透明 procedure TSizer.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.ExStyle := Params.ExStyle + ws_ex_Transparent;
end; procedure TSizer.CreateHandle;
begin
inherited CreateHandle;
SetFocus;
end; procedure TSizer.SizerControlExit(Sender: TObject);
begin
Free;
end; procedure TSizer.WmSize(var Msg: TWmSize);
var
R: TRect;
begin
R := BoundsRect;
InflateRect(R, -2, -2);
FControl.BoundsRect := R;
//设置几个点
FRectList[1] := Rect(0, 0, 5, 5);
FRectList[2] := Rect(Width div 2 - 3, 0, Width div 2 + 2, 5);
FRectList[3] := Rect(Width - 5, 0, Width, 5);
FRectList[4] := Rect(Width - 5, Height div 2 - 3, Width, Height div 2 + 2);
FRectList[5] := Rect(Width - 5, Height - 5, Width, Height);
FRectList[6] := Rect(Width div 2 - 3, Height - 5, Width div 2 + 2, Height);
FRectList[7] := Rect(0, Height - 5, 5, Height);
FRectList := Rect(0, Height div 2 - 3, 5, Height div 2 + 2);
end; procedure TSizer.Paint;
var
i: integer;
begin
Canvas.Brush.Color := clBlack;
for i := 1 to 8 do
Canvas.Rectangle(FRectList[i].Left, FRectList[i].Top, FRectList[i].Right, FRectList[i].Bottom);
end; procedure TSizer.WmNcHitTest(var Msg: TWmNcHitTest);
var
Pt: TPoint;
I: Integer;
begin
Pt := Point(Msg.XPos, Msg.YPos);
Pt := ScreenToClient(Pt);
Msg.Result := 0;
for i := 1 to 8 do
if PtInRect(FRectList[i], Pt) then
Msg.Result := FPosList[i]; if Msg.Result = 0 then
inherited;
end; procedure TSizer.WmLButtonDown(var Msg: TWmLButtonDown);
const
SC_DragMove = $F012;
begin
//传递一个消息
Perform(wm_SysCommand, sc_DragMove, 0);
end; procedure TSizer.WmMove(var Msg: TWmMove);
var
R: TRect;
begin
R := BoundsRect;
InflateRect(R, -2, -2);
FControl.Invalidate;
FControl.BoundsRect := R;
end;
重写其Paint方法即可。还需要一个AttachSizer方法如下:
procedure AttachSizer(Sender: TObject);
begin
TSizer.Create(FOwner, Sender as TCustomControl, FDefaultWidth, FDefaultHeight);
end;
其次,如下写一个TSizer控件,这是一个透明包含控件,在选定矩形控件后, 调用其AttachSizer方法动态创建TSizer控件。 声明如下:
const
sc_DragMove: LongInt = $F012; type
TSizer = class(TCustomControl)
private
FControl: TCustomControl;
FRectList: array[1..8] of TRect;
FPosList: array[1..8] of Integer;
public
constructor Create(AOwner: TComponent; AControl: TCustomControl);
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateHandle; override;
procedure WmNcHitTest(var Msg: TWmNcHitTest); message wm_NcHitTest;
procedure WmSize(var Msg: TWmSize); message wm_Size;
procedure WmLButtonDown(var Msg: TWmLButtonDown); message wm_LButtonDown;
procedure WmMove(var Msg: TWmMove); message wm_Move;
procedure Paint; override;
procedure SizerControlExit(Sender: TObject);
end;
实现如下:
constructor TSizer.Create(AOwner: TComponent; AControl: TCustomControl);
var
R: TRect;
begin
inherited Create(AOwner);
FControl := AControl;
//制定OnExit事件的处理程序
OnExit := SizerControlExit;
//设置大小和位置
R := FControl.BoundsRect;
//缩小边界
InflateRect(R, 2, 2);
BoundsRect := R;
//设置父组件
Parent := FControl.Parent;
//创建位置列表
FPosList[1] := htTopLeft;
FPosList[2] := htTop;
FPosList[3] := htTopRight;
FPosList[4] := htRight;
FPosList[5] := htBottomRight;
FPosList[6] := htBottom;
FPosList[7] := htBottomLeft;
FposList[8] := htLeft;
end; //设置新控件为透明 procedure TSizer.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.ExStyle := Params.ExStyle + ws_ex_Transparent;
end; procedure TSizer.CreateHandle;
begin
inherited CreateHandle;
SetFocus;
end; procedure TSizer.SizerControlExit(Sender: TObject);
begin
Free;
end; procedure TSizer.WmSize(var Msg: TWmSize);
var
R: TRect;
begin
R := BoundsRect;
InflateRect(R, -2, -2);
FControl.BoundsRect := R;
//设置几个点
FRectList[1] := Rect(0, 0, 5, 5);
FRectList[2] := Rect(Width div 2 - 3, 0, Width div 2 + 2, 5);
FRectList[3] := Rect(Width - 5, 0, Width, 5);
FRectList[4] := Rect(Width - 5, Height div 2 - 3, Width, Height div 2 + 2);
FRectList[5] := Rect(Width - 5, Height - 5, Width, Height);
FRectList[6] := Rect(Width div 2 - 3, Height - 5, Width div 2 + 2, Height);
FRectList[7] := Rect(0, Height - 5, 5, Height);
FRectList := Rect(0, Height div 2 - 3, 5, Height div 2 + 2);
end; procedure TSizer.Paint;
var
i: integer;
begin
Canvas.Brush.Color := clBlack;
for i := 1 to 8 do
Canvas.Rectangle(FRectList[i].Left, FRectList[i].Top, FRectList[i].Right, FRectList[i].Bottom);
end; procedure TSizer.WmNcHitTest(var Msg: TWmNcHitTest);
var
Pt: TPoint;
I: Integer;
begin
Pt := Point(Msg.XPos, Msg.YPos);
Pt := ScreenToClient(Pt);
Msg.Result := 0;
for i := 1 to 8 do
if PtInRect(FRectList[i], Pt) then
Msg.Result := FPosList[i]; if Msg.Result = 0 then
inherited;
end; procedure TSizer.WmLButtonDown(var Msg: TWmLButtonDown);
const
SC_DragMove = $F012;
begin
//传递一个消息
Perform(wm_SysCommand, sc_DragMove, 0);
end; procedure TSizer.WmMove(var Msg: TWmMove);
var
R: TRect;
begin
R := BoundsRect;
InflateRect(R, -2, -2);
FControl.Invalidate;
FControl.BoundsRect := R;
end;
解决方案 »
- 可以把TClientWinSocket换成TTcpClient吗?
- 我快急死了,大家帮忙看一下!是用SOCKET传文件的程序
- 问二个比较幼稚的问题,但还是高分请教。
- 在线等待, websnap的数据库字段问题!
- 用fastreport做报表时,读取字段日期格式是yyyy-mm-dd的在打印时用yyyy年mm月dd日格式 怎么做呀!急急!!!!!在线等待
- 为什么窗体会闪动?
- indy 9装不了怎么办啊?
- Sql语句的难题!在线等!解决了立刻给分!!
- 这个问题难住我了!!!你遇到过吗?
- 谁知道是窗体最大化的消息是什么?
- 按ctrl+空格时 它说:"List Index out of bounds(0)"
- 使用colortoRGB函数后,返回值为longint型的整数,怎样才知道R为多少,G为多少,B为多少。比如colortoRGB(clred)=255;RGB(255,0,0).
//任意摆布一个控件(拖动、放大、缩小)******************************************
//==============================================================================
procedure ManipulateControl(Control: TControl; Shift: TShiftState; X, Y, Precision: integer);
var SC_MANIPULATE: Word;
begin
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的最左侧**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (X<=Precision) and (Y>Precision) and (Y<Control.Height-Precision)
then begin
SC_MANIPULATE := $F001;
Control.Cursor := crSizeWE;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的最右侧**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>=Control.Width-Precision) and (Y>Precision) and (Y<Control.Height-Precision)
then begin
SC_MANIPULATE := $F002;
Control.Cursor := crSizeWE;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的最上侧**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>Precision) and (X<Control.Width-Precision) and (Y<=Precision)
then begin
SC_MANIPULATE := $F003;
Control.Cursor := crSizeNS;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的左上角**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X<=Precision) and (Y<=Precision)
then begin
SC_MANIPULATE := $F004;
Control.Cursor := crSizeNWSE;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的右上角**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>=Control.Width-Precision) and (Y<=Precision)
then begin
SC_MANIPULATE := $F005;
Control.Cursor := crSizeNESW ;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的最下侧**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>Precision) and (X<Control.Width-Precision) and (Y>=Control.Height-Precision)
then begin
SC_MANIPULATE := $F006;
Control.Cursor := crSizeNS;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的左下角**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X<=Precision) and (Y>=Control.Height-Precision)
then begin
SC_MANIPULATE := $F007;
Control.Cursor := crSizeNESW;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的右下角**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>=Control.Width-Precision) and (Y>=Control.Height-Precision)
then begin
SC_MANIPULATE := $F008;
Control.Cursor := crSizeNWSE;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的客户区(移动整个控件)******************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>5) and (Y>5) and (X<Control.Width-5) and (Y<Control.Height-5)
then begin
SC_MANIPULATE := $F009;
Control.Cursor := crSizeAll;
end
else begin
SC_MANIPULATE := $F000;
Control.Cursor := crDefault;
end;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if Shift=[ssLeft] then
begin
ReleaseCapture;
Control.Perform(WM_SYSCOMMAND, SC_MANIPULATE, 0);
end;
end;example://~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
procedure TForm_Main.Button1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
Caption := IntToStr(X) + '/' + IntToStr(Y);
ManipulateControl((Sender as TControl), Shift, X, Y, 10);
end;
10为精度
(转载)
//任意摆布一个控件(拖动、放大、缩小)******************************************
//==============================================================================
procedure ManipulateControl(Control: TControl; Shift: TShiftState; X, Y, Precision: integer);
var SC_MANIPULATE: Word;
begin
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的最左侧**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (X<=Precision) and (Y>Precision) and (Y<Control.Height-Precision)
then begin
SC_MANIPULATE := $F001;
Control.Cursor := crSizeWE;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的最右侧**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>=Control.Width-Precision) and (Y>Precision) and (Y<Control.Height-Precision)
then begin
SC_MANIPULATE := $F002;
Control.Cursor := crSizeWE;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的最上侧**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>Precision) and (X<Control.Width-Precision) and (Y<=Precision)
then begin
SC_MANIPULATE := $F003;
Control.Cursor := crSizeNS;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的左上角**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X<=Precision) and (Y<=Precision)
then begin
SC_MANIPULATE := $F004;
Control.Cursor := crSizeNWSE;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的右上角**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>=Control.Width-Precision) and (Y<=Precision)
then begin
SC_MANIPULATE := $F005;
Control.Cursor := crSizeNESW ;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的最下侧**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>Precision) and (X<Control.Width-Precision) and (Y>=Control.Height-Precision)
then begin
SC_MANIPULATE := $F006;
Control.Cursor := crSizeNS;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的左下角**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X<=Precision) and (Y>=Control.Height-Precision)
then begin
SC_MANIPULATE := $F007;
Control.Cursor := crSizeNESW;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的右下角**********************************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>=Control.Width-Precision) and (Y>=Control.Height-Precision)
then begin
SC_MANIPULATE := $F008;
Control.Cursor := crSizeNWSE;
end
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//光标在控件的客户区(移动整个控件)******************************************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if (X>5) and (Y>5) and (X<Control.Width-5) and (Y<Control.Height-5)
then begin
SC_MANIPULATE := $F009;
Control.Cursor := crSizeAll;
end
else begin
SC_MANIPULATE := $F000;
Control.Cursor := crDefault;
end;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if Shift=[ssLeft] then
begin
ReleaseCapture;
Control.Perform(WM_SYSCOMMAND, SC_MANIPULATE, 0);
end;
end;example://~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
procedure TForm_Main.Button1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
Caption := IntToStr(X) + '/' + IntToStr(Y);
ManipulateControl((Sender as TControl), Shift, X, Y, 10);
end;
10为精度
(转载)