我的控件。你需要自己写一个注册代码。
unit CcDrag;interfaceuses
Windows, SysUtils, Classes, Graphics, Controls, Forms;type
TMousePosition = (mpNone, mpRightBottom, mpRight, mpBottom);
TCcDrag = class(TGraphicControl)
private
{ Private Declarations }
FMouseDown: Boolean;
FDownPt: TPoint;
FMousePos: TMousePosition;
FOldWidth: Integer;
FOldHeight: Integer;
FLtdControl: TControl;
FAssignControl: Boolean;
FBoundsRect: TRect;
FFixSize: Boolean;
FFixHeight: Integer;
FFixWidth: Integer;
procedure SetLtdControl(const Value: TControl);
procedure AdjustControlBounds(const ABoundsRec: TRect);
procedure SetControlBounds(const ABoundsRect: TRect);
procedure SetFixSize(const Value: Boolean);
protected
{ Protected Declarations }
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure Paint; override;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
// Big Z Add This Procedure
// 避免在限制边缘拖动时的闪烁,使其表现更好!
procedure AdjustPosition(const OffsetX, OffsetY: Integer); virtual;
public
{ Public Declarations }
constructor Create(AOwner: TComponent); override;
published
{ Published Declarations }
property LtdControl: TControl read FLtdControl write SetLtdControl;
// Big Z Add This 2000.07.21 10:20
// 增加一个属性,是否可以改变大小
property FixSize: Boolean read FFixSize write SetFixSize;
property Width default 90;
property Height default 120;
property Align;
property Anchors;
property Constraints;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property Visible;
property OnClick;
{$IFDEF VER130}
property OnContextPopup;
{$ENDIF}
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDock;
property OnStartDrag;
end;implementationconst
OFFSET = 5;procedure TCcDrag.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
{Method implementation code}
inherited MouseDown(Button, Shift, X, Y); if Button = mbLeft then begin
FMouseDown := True;
FDownPt := Point(X, Y);
FOldWidth := Width;
FOldHeight := Height;
if Assigned(FLtdControl) then
FBoundsRect := FLtdControl.BoundsRect;
if FMousePos = mpNone then
Screen.Cursor := crDrag;
end
end; {MouseDown}procedure TCcDrag.MouseMove(Shift: TShiftState; X, Y: Integer);
var
OffsetX, OffsetY: Integer;
begin
{Method implementation code}
inherited MouseMove(Shift, X, Y); if FMouseDown then begin
OffsetX := X - FDownPt.x;
OffsetY := Y - FDownPt.y;
case FMousePos of
mpNone: begin
{Left := OffsetX + Left;
Top := OffsetY + Top;
if FAssignControl then
AdjustControlBounds(FBoundsRect)}
// Big Z Modify Here 2000.07.21 11:18
AdjustPosition(OffsetX, OffsetY);
end;
mpRight: begin
if FOldWidth + OffsetX > 0 then
Width := FOldWidth + OffsetX;
if FAssignControl then
SetControlBounds(FBoundsRect)
end;
mpBottom: begin
if FOldHeight + OffsetY > 0 then
Height := FOldHeight + OffsetY;
if FAssignControl then
SetControlBounds(FBoundsRect)
end;
mpRightBottom: begin
if FOldWidth + OffsetX > 0 then
Width := FOldWidth + OffsetX;
if FOldHeight + OffsetY > 0 then
Height := FOldHeight + OffsetY;
if FAssignControl then
SetControlBounds(FBoundsRect)
end
end;
end
else begin
if (X >= Width - OFFSET) and (Y >= Height - OFFSET) then begin
Cursor := crSizeNWSE;
FMousePos := mpRightBottom;
end
else if X >= Width - OFFSET then begin
Cursor := crSizeWE;
FMousePos := mpRight
end
else if Y >= Height - OFFSET then begin
Cursor := crSizeNS;
FMousePos := mpBottom
end
else begin
Cursor := crDefault;
FMousePos := mpNone
end;
// Big Z Add This 2000.07.21 10:26
// 如果设定了 FixSize 属性,则尺寸的固定的值
if FFixSize then
begin
Cursor := crDefault;
FMousePos := mpNone
end
end
end; {MouseMove}procedure TCcDrag.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
{Method implementation code}
inherited MouseUp(Button, Shift, X, Y); FMouseDown := False;
Screen.Cursor := crDefault
end; {MouseUp}constructor TCcDrag.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
{Add any other initialization code here}
Width := 90;
Height := 120;
end; {Create}procedure TCcDrag.Paint;
procedure PaintDot(X, Y: Integer);
begin
Canvas.Brush.Style := bsSolid;
Canvas.Brush.Color := clBlack;
Canvas.Pen.Style := psSolid;
Canvas.Pen.Color := clBlack;
Canvas.Pen.Mode := pmCopy;
Canvas.Rectangle(X - 2, Y - 2, X + 2, Y + 2);
end;
begin
inherited; Canvas.Pen.Style := psDot;
Canvas.Brush.Style := bsClear;
Canvas.Pen.Color := clRed;
Canvas.Pen.Mode := pmNot;
Canvas.Rectangle(0, 0, Width, Height);
// Big Z Add This 2000.07.21 11:32
if not FFixSize then
begin
PaintDot(Width, Height shr 1);
PaintDot(Width shr 1, Height);
PaintDot(Width, Height)
end;
end;procedure TCcDrag.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation); if (Operation = opReMove) and (AComponent = FLtdControl) then
FLtdControl := nil
end;procedure TCcDrag.SetLtdControl(const Value: TControl);
begin
if FLtdControl <> Value then begin
FLtdControl := Value;
FAssignControl := Assigned(Value);
if FAssignControl then begin
FBoundsRect := Value.BoundsRect;
SetControlBounds(FBoundsRect);
end
end
end;procedure TCcDrag.SetControlBounds(const ABoundsRect: TRect);
begin
if ABoundsRect.Left > Left then
Left := ABoundsRect.Left;
if ABoundsRect.Top > Top then
Top := ABoundsRect.Top;
if ABoundsRect.Right < (Left + Width) then
Width := ABoundsRect.Right - Left;
if ABoundsRect.Bottom < (Top + Height) then
Height := ABoundsRect.Bottom - Top
end;procedure TCcDrag.AdjustControlBounds(const ABoundsRec: TRect);
begin
if ABoundsRec.Left > BoundsRect.Left then
Left := ABoundsRec.Left;
if ABoundsRec.Top > BoundsRect.Top then
Top := ABoundsRec.Top;
if ABoundsRec.Right < BoundsRect.Right then
Left := ABoundsRec.Right - Width;
if ABoundsRec.Bottom < BoundsRect.Bottom then
Top := ABoundsRec.Bottom - Height
end;// Big Z Add This 2000.07.21 10:26
// 如果设定了 FixSize 属性,则尺寸的固定的值
// ----------------------------------------------------------------------------
procedure TCcDrag.SetFixSize(const Value: Boolean);
begin
if FFixSize <> Value then
begin
FFixSize := Value;
end;
end;// Big Z Add This Procedure
// 避免在限制边缘拖动时的闪烁,使其表现更好!
procedure TCcDrag.AdjustPosition(const OffsetX, OffsetY: Integer);
begin
if not FAssignControl then
begin
Left := Left + OffsetX;
Top := Top + OffsetY;
Exit;
end;
if Left + OffsetX < FBoundsRect.Left then
Left := FBoundsRect.Left
else if Left + OffsetX + Width > FBoundsRect.Right then
Left := FBoundsRect.Right - Width
else
Left := Left + OffsetX;
if Top + OffsetY < FBoundsRect.Top then
Top := FBoundsRect.Top
else if Top + OffsetY + Height > FBoundsRect.Bottom then
Top := FBoundsRect.Bottom - Height
else
Top := Top + OffsetY;
end;end.
unit CcDrag;interfaceuses
Windows, SysUtils, Classes, Graphics, Controls, Forms;type
TMousePosition = (mpNone, mpRightBottom, mpRight, mpBottom);
TCcDrag = class(TGraphicControl)
private
{ Private Declarations }
FMouseDown: Boolean;
FDownPt: TPoint;
FMousePos: TMousePosition;
FOldWidth: Integer;
FOldHeight: Integer;
FLtdControl: TControl;
FAssignControl: Boolean;
FBoundsRect: TRect;
FFixSize: Boolean;
FFixHeight: Integer;
FFixWidth: Integer;
procedure SetLtdControl(const Value: TControl);
procedure AdjustControlBounds(const ABoundsRec: TRect);
procedure SetControlBounds(const ABoundsRect: TRect);
procedure SetFixSize(const Value: Boolean);
protected
{ Protected Declarations }
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure Paint; override;
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
// Big Z Add This Procedure
// 避免在限制边缘拖动时的闪烁,使其表现更好!
procedure AdjustPosition(const OffsetX, OffsetY: Integer); virtual;
public
{ Public Declarations }
constructor Create(AOwner: TComponent); override;
published
{ Published Declarations }
property LtdControl: TControl read FLtdControl write SetLtdControl;
// Big Z Add This 2000.07.21 10:20
// 增加一个属性,是否可以改变大小
property FixSize: Boolean read FFixSize write SetFixSize;
property Width default 90;
property Height default 120;
property Align;
property Anchors;
property Constraints;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property Visible;
property OnClick;
{$IFDEF VER130}
property OnContextPopup;
{$ENDIF}
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDock;
property OnStartDrag;
end;implementationconst
OFFSET = 5;procedure TCcDrag.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
{Method implementation code}
inherited MouseDown(Button, Shift, X, Y); if Button = mbLeft then begin
FMouseDown := True;
FDownPt := Point(X, Y);
FOldWidth := Width;
FOldHeight := Height;
if Assigned(FLtdControl) then
FBoundsRect := FLtdControl.BoundsRect;
if FMousePos = mpNone then
Screen.Cursor := crDrag;
end
end; {MouseDown}procedure TCcDrag.MouseMove(Shift: TShiftState; X, Y: Integer);
var
OffsetX, OffsetY: Integer;
begin
{Method implementation code}
inherited MouseMove(Shift, X, Y); if FMouseDown then begin
OffsetX := X - FDownPt.x;
OffsetY := Y - FDownPt.y;
case FMousePos of
mpNone: begin
{Left := OffsetX + Left;
Top := OffsetY + Top;
if FAssignControl then
AdjustControlBounds(FBoundsRect)}
// Big Z Modify Here 2000.07.21 11:18
AdjustPosition(OffsetX, OffsetY);
end;
mpRight: begin
if FOldWidth + OffsetX > 0 then
Width := FOldWidth + OffsetX;
if FAssignControl then
SetControlBounds(FBoundsRect)
end;
mpBottom: begin
if FOldHeight + OffsetY > 0 then
Height := FOldHeight + OffsetY;
if FAssignControl then
SetControlBounds(FBoundsRect)
end;
mpRightBottom: begin
if FOldWidth + OffsetX > 0 then
Width := FOldWidth + OffsetX;
if FOldHeight + OffsetY > 0 then
Height := FOldHeight + OffsetY;
if FAssignControl then
SetControlBounds(FBoundsRect)
end
end;
end
else begin
if (X >= Width - OFFSET) and (Y >= Height - OFFSET) then begin
Cursor := crSizeNWSE;
FMousePos := mpRightBottom;
end
else if X >= Width - OFFSET then begin
Cursor := crSizeWE;
FMousePos := mpRight
end
else if Y >= Height - OFFSET then begin
Cursor := crSizeNS;
FMousePos := mpBottom
end
else begin
Cursor := crDefault;
FMousePos := mpNone
end;
// Big Z Add This 2000.07.21 10:26
// 如果设定了 FixSize 属性,则尺寸的固定的值
if FFixSize then
begin
Cursor := crDefault;
FMousePos := mpNone
end
end
end; {MouseMove}procedure TCcDrag.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
{Method implementation code}
inherited MouseUp(Button, Shift, X, Y); FMouseDown := False;
Screen.Cursor := crDefault
end; {MouseUp}constructor TCcDrag.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
{Add any other initialization code here}
Width := 90;
Height := 120;
end; {Create}procedure TCcDrag.Paint;
procedure PaintDot(X, Y: Integer);
begin
Canvas.Brush.Style := bsSolid;
Canvas.Brush.Color := clBlack;
Canvas.Pen.Style := psSolid;
Canvas.Pen.Color := clBlack;
Canvas.Pen.Mode := pmCopy;
Canvas.Rectangle(X - 2, Y - 2, X + 2, Y + 2);
end;
begin
inherited; Canvas.Pen.Style := psDot;
Canvas.Brush.Style := bsClear;
Canvas.Pen.Color := clRed;
Canvas.Pen.Mode := pmNot;
Canvas.Rectangle(0, 0, Width, Height);
// Big Z Add This 2000.07.21 11:32
if not FFixSize then
begin
PaintDot(Width, Height shr 1);
PaintDot(Width shr 1, Height);
PaintDot(Width, Height)
end;
end;procedure TCcDrag.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation); if (Operation = opReMove) and (AComponent = FLtdControl) then
FLtdControl := nil
end;procedure TCcDrag.SetLtdControl(const Value: TControl);
begin
if FLtdControl <> Value then begin
FLtdControl := Value;
FAssignControl := Assigned(Value);
if FAssignControl then begin
FBoundsRect := Value.BoundsRect;
SetControlBounds(FBoundsRect);
end
end
end;procedure TCcDrag.SetControlBounds(const ABoundsRect: TRect);
begin
if ABoundsRect.Left > Left then
Left := ABoundsRect.Left;
if ABoundsRect.Top > Top then
Top := ABoundsRect.Top;
if ABoundsRect.Right < (Left + Width) then
Width := ABoundsRect.Right - Left;
if ABoundsRect.Bottom < (Top + Height) then
Height := ABoundsRect.Bottom - Top
end;procedure TCcDrag.AdjustControlBounds(const ABoundsRec: TRect);
begin
if ABoundsRec.Left > BoundsRect.Left then
Left := ABoundsRec.Left;
if ABoundsRec.Top > BoundsRect.Top then
Top := ABoundsRec.Top;
if ABoundsRec.Right < BoundsRect.Right then
Left := ABoundsRec.Right - Width;
if ABoundsRec.Bottom < BoundsRect.Bottom then
Top := ABoundsRec.Bottom - Height
end;// Big Z Add This 2000.07.21 10:26
// 如果设定了 FixSize 属性,则尺寸的固定的值
// ----------------------------------------------------------------------------
procedure TCcDrag.SetFixSize(const Value: Boolean);
begin
if FFixSize <> Value then
begin
FFixSize := Value;
end;
end;// Big Z Add This Procedure
// 避免在限制边缘拖动时的闪烁,使其表现更好!
procedure TCcDrag.AdjustPosition(const OffsetX, OffsetY: Integer);
begin
if not FAssignControl then
begin
Left := Left + OffsetX;
Top := Top + OffsetY;
Exit;
end;
if Left + OffsetX < FBoundsRect.Left then
Left := FBoundsRect.Left
else if Left + OffsetX + Width > FBoundsRect.Right then
Left := FBoundsRect.Right - Width
else
Left := Left + OffsetX;
if Top + OffsetY < FBoundsRect.Top then
Top := FBoundsRect.Top
else if Top + OffsetY + Height > FBoundsRect.Bottom then
Top := FBoundsRect.Bottom - Height
else
Top := Top + OffsetY;
end;end.
解决方案 »
- SPComm串口通讯,数据出现遗漏,速手无策ing,求救啊 ~~~~~~
- 求Delphi 5.x 分布式多层应用电子商务篇配套光盘原码
- cxgrid 可以实现 自定义排序规则吗?
- 在XP里如何不让任务管理器关闭一个我写的后台服务程序啊!!!
- [求助] 请各位大侠帮忙 !!!!!!
- 紧急求助,如何识别字符串中的Email地址?
- 救命啊。DELPHI 6。0的Quick Report问题。急急!
- 老鱼,系统报错如下//牛虻
- 我用NMSmtp组件发送邮件,第一次能够成功,然后
- ACCESS 的密码在DELPHI中能解不??
- 如何在windows环境下访问unix数据库
- 如何检测CDROM的当前状态?
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;const
SC_DragMove: Longint = $F012;
type
TPSButton = class(TButton)
private
procedure WMNcHitTest (var Msg: TWmNcHitTest);
message WM_NcHitTest;
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
published
{ Published declarations }
end;
TPSBtnSizerControl = class (TCustomControl)
private
FControl: TControl;
FRectList: array [1..8] of TRect;
FPosList: array [1..8] of Integer;
public
constructor Create (AOwner: TComponent;
AControl: TControl);
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;procedure Register;implementation// TPSButton methodsprocedure TPSButton.WmNcHitTest(var Msg: TWmNcHitTest);
var
Pt: TPoint;
begin
Pt := Point (Msg.XPos, Msg.YPos);
Pt := ScreenToClient (Pt);
if (Pt.x < 5) and (pt.y < 5) then
Msg.Result := htTopLeft
else if (Pt.x > Width - 5) and (pt.y < 5) then
Msg.Result := htTopRight
else if (Pt.x > Width - 5) and (pt.y > Height - 5) then
Msg.Result := htBottomRight
else if (Pt.x < 5) and (pt.y > Height - 5) then
Msg.Result := htBottomLeft
else if (Pt.x < 5) then
Msg.Result := htLeft
else if (pt.y < 5) then
Msg.Result := htTop
else if (Pt.x > Width - 5) then
Msg.Result := htRight
else if (pt.y > Height - 5) then
Msg.Result := htBottom
else
inherited;
end;// TPSBtnSizerControl methodsconstructor TPSBtnSizerControl.Create(AOwner: TComponent; AControl: TControl);
var
R: TRect;
begin
inherited Create (AOwner);
FControl := AControl;
// install the new handler
OnExit := SizerControlExit;
// set the size and position
R := FControl.BoundsRect;
InflateRect (R, 2, 2);
BoundsRect := R;
// set the parent
Parent := FControl.Parent;
// create the list of positions
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 TPSBtnSizerControl.CreateHandle;
begin
inherited CreateHandle;
SetFocus;
end;procedure TPSBtnSizerControl.CreateParams (var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.ExStyle := Params.ExStyle +
ws_ex_Transparent;
end;procedure TPSBtnSizerControl.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 TPSBtnSizerControl.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 the return value was not set
if Msg.Result = 0 then
inherited;
end;procedure TPSBtnSizerControl.WmSize (var Msg: TWmSize);
var
R: TRect;
begin
R := BoundsRect;
InflateRect (R, -2, -2);
FControl.BoundsRect := R;
// setup data structures
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 [8] := Rect (0, Height div 2 - 3,
5, Height div 2 + 2);
end;procedure TPSBtnSizerControl.SizerControlExit (Sender: TObject);
begin
Free;
end;procedure TPSBtnSizerControl.WmLButtonDown (var Msg: TWmLButtonDown);
begin
Perform (wm_SysCommand, sc_DragMove, 0);
end;procedure TPSBtnSizerControl.WmMove (var Msg: TWmMove);
var
R: TRect;
begin
R := BoundsRect;
InflateRect (R, -2, -2);
FControl.Invalidate; // repaint entire surface
FControl.BoundsRect := R;
end;procedure Register;
begin
RegisterComponents('PS', [TPSButton]);
RegisterNoIcon ([TPSBtnSizerControl]);
end;end.
to:chechy(chechy) 能不能不用控件???
其实我在设计这个控件时,开始也是WM_NcHitTest,这个消息比较简单。但是我发现用这个消息,控件最多只能拉伸到屏幕的大小,再大就不行了,所以我才放弃这个消息。