我的控件。你需要自己写一个注册代码。
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.

解决方案 »

  1.   

    我的控件~~呵呵~~unit PSButton;interfaceuses
      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.
      

  2.   

    呵呵~~
    to:chechy(chechy) 能不能不用控件???
      

  3.   

    我的控件不用应该没问题,而你的由于有WM_NcHitTest消息,不用控件比较难。
    其实我在设计这个控件时,开始也是WM_NcHitTest,这个消息比较简单。但是我发现用这个消息,控件最多只能拉伸到屏幕的大小,再大就不行了,所以我才放弃这个消息。