title: User moving Shape at run time
body: <p>I have a unit called MachineShapes, with a type TShape on it. I am trying to get it so when a user clicks on shape they can move it. I think iam close but got a little confused. Thanks for any help</p>
  
  <p>MachineShapes</p>
  
  <pre><code>    unit MachineShape;
  
  
  interface
  
  uses
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
    Vcl.Controls, extctrls,myDataModule,Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
  
  type
  
  TMachine = class(TShape)
    private
      { Private declarations }
      FOnMouseDown : TNotifyEvent;
      FOnMouseUp: TNotifyEvent;
      FonMouseMove: TNotifyEvent;
      procedure ControlMouseDown(Sender: TObject;
                               Button: TMouseButton;
                               Shift: TShiftState;
                               X, Y: Integer);
      procedure ControlMouseMove(Sender: TObject;
                               Shift: TShiftState;
                               X, Y: Integer);
      procedure ControlMouseUp(Sender: TObject;
                             Button: TMouseButton;
                             Shift: TShiftState;
                             X, Y: Integer);
  
    private
      inReposition : boolean;
      oldPos : TPoint;
    Protected
        procedure DoMouseDown; virtual;
        procedure DoMouseUp; Virtual;
        procedure DoMouseMove; virtual;
    Published
        property OnMouseDown: TNotifyEvent Read FOnMouseDown Write fOnMouseDown;
        property OnMouseMove: TNotifyEvent Read FOnMouseMove write fOnMouseMove;
        Property onMouseUp : TNotifyEvent Read FOnMouseUp write FOnMouseUp;
    public
      { Public declarations }
  
    end;
  implementation
  
  uses
    deptlayout;
  
  
      procedure TMachine.ControlMouseMove(Sender: TObject; Shift: TShiftState; X: Integer; Y: Integer);
      const
          minWidth = 20;
          minHeight = 20;
      var
          newPos: TPoint;
          frmPoint : TPoint;
      begin
        if inReposition then
        begin
          with TWinControl(Sender) do
          begin
            GetCursorPos(newPos);
              Screen.Cursor := crSize;
              Left := Left - oldPos.X + newPos.X;
              Top := Top - oldPos.Y + newPos.Y;
              oldPos := newPos;
          end;
        end;
      end;
  
      procedure TMachine.ControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer);
      begin
        if inReposition then
          begin
            Screen.Cursor := crDefault;
            ReleaseCapture;
            inReposition := False;
          end;
  
      end;
  
  
      procedure TMachine.ControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer);
      begin
          inReposition:=True;
          SetCapture(TWinControl(Sender).Handle);
          GetCursorPos(oldPos);
      end;
  
  
      procedure tmachine.DoMouseDown;
      begin
          if assigned(fonmousedown) then
            fonmousedown(self);
      end;
  
      procedure tmachine.DoMouseUp;
      begin
          if assigned(fonmouseup) then
            fonmouseup(self);
      end;
  
      procedure tmachine.domousemove;
      begin
          if assigned(fonmousemove) then
            fonmousemove(self);
      end;
  
  end.
  </code></pre>
  
  <p>How i call it..</p>
  
  <pre><code>    procedure TFGetZoneDept.CreateShape(Sender: TObject);
  var
    machine : TMachine;
  begin
  
    //creates the shape
          machine := MachineShape.TMachine.Create(fdeptlayout); //form to create shape on
          machine.Parent := fdeptlayout; //form to add shape to
          machine.OnMouseDown := machinemouseDown;
          machine.OnMouseUp := machinemouseUp;
          machine.OnMouseMove:= machinemouseMove;
  end;
  
  
  procedure TFGetZoneDept.MachineMouseDown(Sender: TObject);
  var
    machine: TMachine;
  begin
     machine := Sender as TMachine;
  end;
  
  procedure TFGetZoneDept.MachineMouseUp(Sender: TObject);
  var
    machine: TMachine;
  begin
    machine := Sender as TMachine;
  end;
  
  procedure TFGetZoneDept.machineMouseMove(Sender: TObject);
  var
    machine: TMachine;
  begin
    machine := sender as Tmachine;
  end;
  </code></pre>