Solved

Moving Controls at Runtime: Example Please

Posted on 1998-03-26
12
182 Views
Last Modified: 2010-04-06
I'm writting an app that will allow the user to drag/drop controls onto a container and then hook them up via a line.  The user can move the items a runtime.  Are there any examples out there?
1.  Moving controls at runtime
2.  creating this type of container object.
3.  linking controls with a line (that moves when the object is moved by user).

0
Comment
Question by:blitz051697
  • 4
  • 3
  • 3
  • +1
12 Comments
 
LVL 4

Expert Comment

by:BoRiS
ID: 1360952
blitz

I can give you code as to how to move the controls at run time but dropping them on to a container i guess would have to be done by allowing the container to accept these objects and then link them...

if you want to code let me know.... by comment

remember it's only the code to move object at run time...

Later

BoRiS
0
 
LVL 5

Expert Comment

by:inter
ID: 1360953
Hi,

Here is doing it in one way. Do the following:

1 - Create and empty form
2 - Place a Panel and Button on the form. Those should be named as Panel1 and Button1
3 - Cut and paste the following code for your unit as follows:

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ComCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    procedure Panel1DragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure Panel1DragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure FormDragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure FormDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Button1.DragMode := dmAutomatic;
  Panel1.DragMode := dmAutomatic;
end;

procedure TForm1.Panel1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Accept := (Source is TControl) and (Source <> Sender);
end;

procedure TForm1.Panel1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
  with (Source as TControl) do
  begin
    Parent := TWinControl(Sender);
    Left := X;
    Top := Y;
  end;
end;

procedure TForm1.FormDragDrop(Sender, Source: TObject; X, Y: Integer);
begin
  with (Source as TControl) do
  begin
    Left := X;
    Top := Y;
  end;
end;

procedure TForm1.FormDragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Accept := (Source is TControl);
end;

end.


Link events from object inspector to the above events. For example click on Panel and press F11 to show the object ispector. Switch to events tab and from the drop down list of OnDragOver event select Panel1DragOver etc...

Then run the project. Drag the button over Panel and drop. Then drag the panel over the form and drop. Is that what you want?

Regards,
Igor
0
 
LVL 5

Expert Comment

by:inter
ID: 1360954
Hi BoRis,

Sorry, I do not see you commenting while I prepare the answer.

Igor
0
 
LVL 4

Expert Comment

by:BoRiS
ID: 1360955
hi inter

not to worry, lets see what blitz has to say

Later

BoRiS
0
 
LVL 5

Expert Comment

by:inter
ID: 1360956
Hi there,

excuse me, when you drag button back to the form it does not work so modify the following please:

procedure TForm1.FormDragDrop(Sender, Source: TObject; X, Y: Integer);
begin
  with (Source as TControl) do
  begin
    Parent := TWinControl(Sender);
    Left := X;
    Top := Y;
  end;
end;

Regards,
Igor
0
 

Author Comment

by:blitz051697
ID: 1360957
boris, you say that you can move controls at runtime.  But does your code also allow drawing a graphical line to link them?  Will the line move as the control moves?  
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 4

Expert Comment

by:BoRiS
ID: 1360958
blitz

let me see what i can do...

I'll let you know by comment

later

BoRiS
0
 
LVL 5

Expert Comment

by:inter
ID: 1360959
Hi there,

would you please explain 'drawing a graphical line to link them' more. In addition you may reject my answer so that BoRiS can be able to supply one.

Regards,
Igor
0
 

Author Comment

by:blitz051697
ID: 1360960
Two controls that are linked would have a line that is drawn between them.   This would be similar to a program like Visio or flowcharting tools. As I move the control (or box or whatever) the line continues to stay linked to any other attached controls.


0
 
LVL 4

Expert Comment

by:d003303
ID: 1360961
Yo blitz,
I could offer you a bunch of code again. Some time ago I designed some basic flowcharting like classes with connector classes to graphically display a network environment. The classes are extendable, the base connector class supports 1<->1 connections, but any element supports an unlimited number of connections (and, yes, you can drag them around however you want).
Classes with sample app for 500 pts ? Your turn.

Slash/d003303
0
 

Author Comment

by:blitz051697
ID: 1360962
Ok Slash, What do ya got?

Blitz
0
 
LVL 4

Accepted Solution

by:
d003303 earned 500 total points
ID: 1360963
Yo blitz,

here we go. The first unit is the foundation class. It contains the basic container class(wich holds all objects), the basic connector class (that connects the objects) and, of course, the basic class of the flowchart elements.
The second unit is an example how to extend the basic classes with customized controls.
The third is a sample app using the basic and example classes. All action is on the right mouse key.

////////////////////////////////
//
// base classes
//
// to be FloatCtrls.pas

unit FloatCtrls;

interface

uses Classes, Controls, StdCtrls, ExtCtrls;

type

  TCustomDragObject = class;
  TDragObjectClass = class of TCustomDragObject;

  TBasicConnector = class(TGraphicControl)
  private
    FConnSource,
    FConnTarget  : TCustomDragObject;
    UpsideDown   : Boolean;
  protected
    procedure Paint; override;
    procedure NewBounds;
  public
    constructor CreateConnection(AOwner : TComponent; AParent : TWinControl; ASource, ATarget : TCustomDragObject); virtual;
    procedure DestroyConnection;
    function ConnTarget(AnObject : TCustomDragObject): TCustomDragObject;
  end;

  TConnectorClass = class of TBasicConnector;

  TCustomDragObjectContainer = class(TCustomPanel)
  private
    FCurrentConnectorClass : TConnectorClass;
    FCurrentDragObjectClass : TDragObjectClass;
  public
    constructor Create(AOwner : TComponent); override;
    property CurrentConnectorClass: TConnectorClass read FCurrentConnectorClass write FCurrentConnectorClass;
    property CurrentDragObjectClass: TDragObjectClass read FCurrentDragObjectClass write FCurrentDragObjectClass;
  end;

  TCustomDragObject = class(TCustomPanel)
  private
    FContainer : TCustomDragObjectContainer;
    FIsDragAllowed : Boolean;
    FConnectedObjects : TStringList;
  protected
    procedure DblClick; override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure SetIsDragAllowed(NewValue : Boolean);
    function GetConnectionFromTarget(AnObject : TCustomDragObject): TBasicConnector;
    function GetConnectionFromIndex(AnIndex : Integer): TBasicConnector;
    function GetIndexFromConnection(AnObject : TBasicConnector): Integer;
    procedure Connect(AnObject : TBasicConnector);
    procedure Disconnect(AnObject : TBasicConnector);
  public
    constructor CreateContainered(AOwner : TComponent; AContainer : TCustomDragObjectContainer); virtual;
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
    procedure ConnectTo(AnObject : TCustomDragObject);
    procedure DisconnectFrom(AnObject : TCustomDragObject);
    procedure DisconnectFromIndex(AnIndex : Integer);
    property IsDragAllowed: Boolean read FIsDragAllowed write SetIsDragAllowed;
    property ConnectedObjects: TStringList read FConnectedObjects;
    property Caption;
  end;

implementation

uses Windows, Messages, SysUtils;

////////////////////////////////////////////////////////////////////////////////

constructor TBasicConnector.CreateConnection(AOwner : TComponent; AParent : TWinControl; ASource, ATarget : TCustomDragObject);
begin
  Create(AOwner);
  FConnSource := ASource;
  FConnTarget := ATarget;
  FConnSource.Connect(Self);
  FConnTarget.Connect(Self);
  Parent := AParent;
  NewBounds;
end;

procedure TBasicConnector.DestroyConnection;
begin
  FConnTarget.Disconnect(Self);
  FConnSource.Disconnect(Self);
  Free;
end;

function TBasicConnector.ConnTarget(AnObject : TCustomDragObject): TCustomDragObject;
begin
  if AnObject = FConnTarget
   then Result := FConnSource
   else Result := FConnTarget;
end;

procedure TBasicConnector.NewBounds;
var ALeft1, ATop1, ALeft2, ATop2, Offset,
    ALeft, ATop, AWidth, AHeight : Integer;
begin
  Offset := Canvas.Pen.Width div 2;
  ALeft1 := FConnSource.Left + FConnSource.Width div 2;
  ATop1 := FConnSource.Top + FConnSource.Height div 2;
  ALeft2 := FConnTarget.Left + FConnTarget.Width div 2;
  ATop2 := FConnTarget.Top + FConnTarget.Height div 2;
  if ALeft1 < ALeft2 then
   begin
    UpsideDown := false;
    ALeft := ALeft1;
    AWidth := ALeft2 - ALeft;
   end
  else
   begin
    UpsideDown := true;
    ALeft := ALeft2;
    AWidth := ALeft1 - ALeft;
   end;
  if ATop1 < ATop2 then
   begin
    ATop := ATop1;
    AHeight := ATop2 - ATop;
   end
  else
   begin
    UpsideDown := not UpsideDown;
    ATop := ATop2;
    AHeight := ATop1 - ATop;
   end;
  SetBounds(ALeft - Offset, ATop - Offset, AWidth + Offset, AHeight + Offset);
end;

procedure TBasicConnector.Paint;
var Offset : Integer;
begin
  inherited Paint;
  Offset := Canvas.Pen.Width div 2;
  if UpsideDown then
   begin
     Canvas.MoveTo(Offset, Height - Offset);
     Canvas.LineTo(Width - Offset, Offset);
   end
  else
   begin
     Canvas.MoveTo(Offset, Offset);
     Canvas.LineTo(Width - Offset, Height - Offset);
   end;
end;

////////////////////////////////////////////////////////////////////////////////

constructor TCustomDragObjectContainer.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);
  FCurrentConnectorClass := TBasicConnector;
  FCurrentDragObjectClass := TCustomDragObject;
  BevelOuter := bvNone;
end;

////////////////////////////////////////////////////////////////////////////////

constructor TCustomDragObject.CreateContainered(AOwner : TComponent; AContainer : TCustomDragObjectContainer);
begin
  Create(AOwner);
  FContainer := AContainer;
end;

constructor TCustomDragObject.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);
  FConnectedObjects := TStringList.Create;
  FIsDragAllowed := false;
  FContainer := nil;
end;

destructor TCustomDragObject.Destroy;
var Index : Integer;
begin
  Index := 0;
  while Index < FConnectedObjects.Count
   do (FConnectedObjects.Objects[Index] as TBasicConnector).DestroyConnection;
  FConnectedObjects.Free;
  inherited Destroy;
end;

function TCustomDragObject.GetConnectionFromTarget(AnObject : TCustomDragObject): TBasicConnector;
var Index : Integer;
begin
  Result := nil;
  Index := 0;
  while Index < FConnectedObjects.Count do
   begin
     if (FConnectedObjects.Objects[Index] as TBasicConnector).ConnTarget(Self) = AnObject then
      begin
        Result := (FConnectedObjects.Objects[Index] as TBasicConnector);
        Break;
      end;
     Inc(Index);
   end;
end;

function TCustomDragObject.GetConnectionFromIndex(AnIndex : Integer): TBasicConnector;
begin
  Result := (FConnectedObjects.Objects[AnIndex] as TBasicConnector)
end;

function TCustomDragObject.GetIndexFromConnection(AnObject : TBasicConnector): Integer;
var Index : Integer;
begin
  Result := -1;
  Index := 0;
  while Index < FConnectedObjects.Count do
   begin
     if (FConnectedObjects.Objects[Index] as TBasicConnector) = AnObject then
      begin
        Result := Index;
        Break;
      end;
     Inc(Index);
   end;
end;

procedure TCustomDragObject.Connect(AnObject : TBasicConnector);
begin
  FConnectedObjects.AddObject(AnObject.ConnTarget(Self).Caption, AnObject);
end;

procedure TCustomDragObject.Disconnect(AnObject : TBasicConnector);
var Index : Integer;
begin
  Index := GetIndexFromConnection(AnObject);
  if Index <> -1
   then FConnectedObjects.Delete(Index)
   else raise Exception.Create('Error while disconnecting from ' + AnObject.ConnTarget(Self).Caption);
end;

procedure TCustomDragObject.ConnectTo(AnObject : TCustomDragObject);
begin
  if GetConnectionFromTarget(AnObject) = nil then
   begin
     if FContainer <> nil
      then FContainer.CurrentConnectorClass.CreateConnection(Self, Parent, Self, AnObject)
      else TBasicConnector.CreateConnection(Self, Parent, Self, AnObject);
   end
  else raise Exception.Create('Already connected to ' + AnObject.Caption);
end;

procedure TCustomDragObject.DisconnectFrom(AnObject : TCustomDragObject);
var AConnector : TBasicConnector;
begin
  AConnector := GetConnectionFromTarget(AnObject);
  if AConnector <> nil
   then AConnector.DestroyConnection
   else raise Exception.Create('Not connected to ' + AnObject.Caption);
end;

procedure TCustomDragObject.DisconnectFromIndex(AnIndex : Integer);
begin
  GetConnectionFromIndex(AnIndex).Free;
end;

procedure TCustomDragObject.SetIsDragAllowed(NewValue : Boolean);
begin
  if FIsDragAllowed <> NewValue then
   begin
     FIsDragAllowed := NewValue;
     if FIsDragAllowed
      then BevelInner := bvLowered
      else BevelInner := bvNone;
   end;
end;

procedure TCustomDragObject.DblClick;
begin
  IsDragAllowed := not IsDragAllowed;
  inherited;
end;

procedure TCustomDragObject.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var Index : Integer;
begin
  if IsDragAllowed then
   begin
     ReleaseCapture;
     SendMessage(Handle, WM_SYSCOMMAND, 61458, 0);
     for Index := 0 to FConnectedObjects.Count - 1
      do (FConnectedObjects.Objects[Index] as TBasicConnector).NewBounds;
   end;
  inherited;
end;

end.

////////////////////////////////
//
// example extension classes
//
// to be ExtFloatCtrls.pas

unit ExtFloatCtrls;

interface

uses Classes, Menus, FloatCtrls;

type

  TMyConnector = class(TBasicConnector)
  public
    constructor Create(AOwner : TComponent); override;
  end;

  TMyDragObjectContainer = class(TCustomDragObjectContainer)
  private
    AContextMenu : TPopUpMenu;
    procedure OnNewItemClick(Sender: TObject);
    procedure OnBasicObjectClick(Sender: TObject);
    procedure OnEnhancedObjectClick(Sender: TObject);
    procedure OnBasicConnectorClick(Sender: TObject);
    procedure OnEnhancedConnectorClick(Sender: TObject);
  public
    constructor Create(AOwner : TComponent); override;
    procedure NewItem(ACaption : string; x, y : LongInt);
  end;

  TMyDragObject = class(TCustomDragObject)
  private
    AContextMenu : TPopUpMenu;
  protected
    procedure DeleteSubMenuItems;
    procedure OnContextMenuPopUp(Sender : TObject);
    procedure ConnectClick(Sender : TObject);
    procedure DisconnectClick(Sender : TObject);
    procedure ToggleMoveClick(Sender : TObject);
    procedure DeleteClick(Sender : TObject);
  public
    constructor Create(AOwner : TComponent); override;
  end;

implementation

uses Windows, SysUtils;

////////////////////////////////////////////////////////////////////////////////

constructor TMyConnector.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);
  Canvas.Pen.Width := 6;
end;

////////////////////////////////////////////////////////////////////////////////

constructor TMyDragObjectContainer.Create(AOwner : TComponent);
var AMenuItem : TMenuItem;
begin
  inherited Create(AOwner);
  CurrentConnectorClass := TMyConnector;
  CurrentDragObjectClass := TMyDragObject;
  AContextMenu := TPopUpMenu.Create(Self);
  PopUpMenu := AContextMenu;

  AMenuItem := TMenuItem.Create(Self);
  AMenuItem.Caption := '&New';
  AMenuItem.OnClick := OnNewItemClick;
  AContextMenu.Items.Add(AMenuItem);

  AMenuItem := TMenuItem.Create(Self);
  AMenuItem.Caption := '-';
  AContextMenu.Items.Add(AMenuItem);

  AMenuItem := TMenuItem.Create(Self);
  AMenuItem.Caption := '&Objects...';
  AContextMenu.Items.Add(AMenuItem);

  AMenuItem := TMenuItem.Create(Self);
  AMenuItem.Caption := '&Basic';
  AMenuItem.RadioItem := true;
  AMenuItem.OnClick := OnBasicObjectClick;
  AContextMenu.Items[2].Add(AMenuItem);

  AMenuItem := TMenuItem.Create(Self);
  AMenuItem.Caption := '&Enhanced';
  AMenuItem.RadioItem := true;
  AMenuItem.Checked := true;
  AMenuItem.OnClick := OnEnhancedObjectClick;
  AContextMenu.Items[2].Add(AMenuItem);

  AMenuItem := TMenuItem.Create(Self);
  AMenuItem.Caption := '&Connectors...';
  AContextMenu.Items.Add(AMenuItem);

  AMenuItem := TMenuItem.Create(Self);
  AMenuItem.Caption := '&Basic';
  AMenuItem.RadioItem := true;
  AMenuItem.OnClick := OnBasicConnectorClick;
  AContextMenu.Items[3].Add(AMenuItem);

  AMenuItem := TMenuItem.Create(Self);
  AMenuItem.Caption := '&Enhanced';
  AMenuItem.RadioItem := true;
  AMenuItem.Checked := true;
  AMenuItem.OnClick := OnEnhancedConnectorClick;
  AContextMenu.Items[3].Add(AMenuItem);
end;

procedure TMyDragObjectContainer.OnNewItemClick(Sender: TObject);
var APoint : TPoint;
begin
  GetCursorPos(APoint);
  APoint := ScreenToClient(APoint);
  NewItem(IntToStr(ControlCount + 1), APoint.x, APoint.y);
end;

procedure TMyDragObjectContainer.OnBasicObjectClick(Sender: TObject);
begin
  (Sender as TMenuItem).Checked := true;
  CurrentDragObjectClass := TCustomDragObject;
end;

procedure TMyDragObjectContainer.OnEnhancedObjectClick(Sender: TObject);
begin
  (Sender as TMenuItem).Checked := true;
  CurrentDragObjectClass := TMyDragObject;
end;

procedure TMyDragObjectContainer.OnBasicConnectorClick(Sender: TObject);
begin
  (Sender as TMenuItem).Checked := true;
  CurrentConnectorClass := TBasicConnector;
end;

procedure TMyDragObjectContainer.OnEnhancedConnectorClick(Sender: TObject);
begin
  (Sender as TMenuItem).Checked := true;
  CurrentConnectorClass := TMyConnector;
end;

procedure TMyDragObjectContainer.NewItem(ACaption : string; x, y : LongInt);
var NewDragObject : TCustomDragObject;
begin
  NewDragObject := CurrentDragObjectClass.CreateContainered(Self, Self);
  with NewDragObject do
   begin
     Top := y;
     Left := x;
     Width := 100;
     Height := 100;
     Parent := Self;
     Caption := ACaption;
   end;
end;

////////////////////////////////////////////////////////////////////////////////

constructor TMyDragObject.Create(AOwner : TComponent);
var AMenuItem : TMenuItem;
begin
  inherited Create(AOwner);
  AContextMenu := TPopUpMenu.Create(Self);
  AContextMenu.OnPopUp := OnContextMenuPopUp;
  PopUpMenu := AContextMenu;

  AMenuItem := TMenuItem.Create(Self);
  AMenuItem.Caption := '&Connect to...';
  AContextMenu.Items.Add(AMenuItem);

  AMenuItem := TMenuItem.Create(Self);
  AMenuItem.Caption := 'D&isconnect from...';
  AContextMenu.Items.Add(AMenuItem);

  AMenuItem := TMenuItem.Create(Self);
  AMenuItem.Caption := '&Moveable';
  AMenuItem.OnClick := ToggleMoveClick;
  AMenuItem.Checked := false;
  AContextMenu.Items.Add(AMenuItem);

  AMenuItem := TMenuItem.Create(Self);
  AMenuItem.Caption := '-';
  AContextMenu.Items.Add(AMenuItem);

  AMenuItem := TMenuItem.Create(Self);
  AMenuItem.Caption := '&Delete';
  AMenuItem.OnClick := DeleteClick;
  AContextMenu.Items.Add(AMenuItem);
end;

procedure TMyDragObject.OnContextMenuPopUp(Sender : TObject);
var Index1, Index2 : Integer;
    AMenuItem : TMenuItem;
begin
  DeleteSubMenuItems;
  Self.AContextMenu.Items[2].Checked := IsDragAllowed;
  Index2 := 0;
  with (Parent as TCustomDragObjectContainer) do
   for Index1 := 0 to ControlCount - 1 do
    if (Controls[Index1] is TCustomDragObject) then
     begin
       // connect to submenu
       AMenuItem := TMenuItem.Create(Self);
       AMenuItem.Caption := IntToStr(Index2 + 1) + ': ' + (Controls[Index1] as TCustomDragObject).Caption;
       AMenuItem.OnClick := ConnectClick;
       AMenuItem.Tag := Index1;
       if Controls[Index1] = Self
        then AMenuItem.Enabled := false;
       Self.AContextMenu.Items[0].Add(AMenuItem);
       Inc(Index2);
     end;
   if ConnectedObjects.Count = 0
    then Self.AContextMenu.Items[1].Enabled := false
    else Self.AContextMenu.Items[1].Enabled := true;
   for Index1 := 0 to ConnectedObjects.Count - 1 do
    begin
      // connect to submenu
      AMenuItem := TMenuItem.Create(Self);
      AMenuItem.Caption := IntToStr(Index1 + 1) + ': ' + (ConnectedObjects.Objects[Index1] as TBasicConnector).ConnTarget(Self).Caption;
      AMenuItem.OnClick := DisconnectClick;
      AMenuItem.Tag := Index1;
      Self.AContextMenu.Items[1].Add(AMenuItem);
    end;
end;

procedure TMyDragObject.DeleteSubMenuItems;
var AMenuItem : TMenuItem;
 procedure DeleteSubs;
 begin
   while AMenuItem.Count <> 0
    do AMenuItem.Delete(0);
 end;
begin
  AMenuItem := AContextMenu.Items[0];
  DeleteSubs;
  AMenuItem := AContextMenu.Items[1];
  DeleteSubs;
end;

procedure TMyDragObject.ConnectClick(Sender : TObject);
begin
  // wildest typecast
  ConnectTo(((Parent as TCustomDragObjectContainer).Controls[(Sender as TMenuItem).Tag]) as TCustomDragObject);
end;

procedure TMyDragObject.DisconnectClick(Sender : TObject);
begin
  // not so wild typecast as above
  DisconnectFrom(((ConnectedObjects.Objects[(Sender as TMenuItem).Tag]) as TBasicConnector).ConnTarget(Self));
end;

procedure TMyDragObject.ToggleMoveClick(Sender : TObject);
begin
  IsDragAllowed := not IsDragAllowed;
  (Sender as TMenuItem).Checked := IsDragAllowed;
end;

procedure TMyDragObject.DeleteClick(Sender : TObject);
begin
  Free;
end;

end.

////////////////////////////////
//
// sample app
//
// to be _mover.pas

unit _mover;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, ExtFloatCtrls, Menus, StdCtrls;

type

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
     Container : TMyDragObjectContainer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Container := TMyDragObjectContainer.Create(Self);
  with Container do
   begin
     Parent := Self;
     Align := alClient;
   end;
end;

end.

////////////////////////////////
//
// to be _mover.dfm

object Form1: TForm1
  Left = 200
  Top = 108
  Width = 783
  Height = 551
  Caption = 'All options are on the right mouse button !'
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
end

////////////////////////////////
//
// to be mover.dpr

program mover;

uses
  Forms,
  _mover in '_mover.pas' {Form1},
  FloatCtrls in 'FloatCtrls.pas',
  ExtFloatCtrls in 'ExtFloatCtrls.pas';

{$R *.RES}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

////////////////////////////////

That's mainly it. Look at the sample source in ExtFloatCtrls.pas for the usage. If you have questions, just post them here.

Have fun,
Slash/d003303
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now