Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to move components at run-time? :)

Status
Not open for further replies.

Guest_imported

New member
Jan 1, 1970
0
How to move a label, a editbox, a combobox, a listbox, or other components at run-time?
Give-me an example:)

Thanks:)
 
SolveProblems,

Not sure what you mean by move, but you can move controls by simply changing the Left and Top properties at runtime.

Alternatively, and perhaps more relevant if you're trying to implement a form that responds to resizing and/or resolution changes and you're using Delphi 5 or later, you may want to take a look at the Anchor properties. These "pin" controls to relative positions on forms. When you resize forms with specifically set Anchor properties, the controls automatically resize with the form.

Finally, there's also a lot you can do with Panels and the Align property, though some prefer not to use this for it consumes additional window handles. The technique is largely unneeded now that we have the Anchor properties, but it's very useful when youre working with older versions of Delphi.

Examples can be found in the online Help.

Hope this helps...

-- Lance
 
Move Window-controls (TLabel isn't one, you can use TPanel instead) at runtime with the mouse by pressing the CTRL-Button:

{i.e. a TEdit (on the OnMouseDown Event)}

procedure TForm1.Edit1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if ssCtrl in Shift then
begin
ReleaseCapture;
Edit1.Perform(WM_SYSCOMMAND,$F012,0);
end;
end;
 
Here's another example. You need to right click on a contorl to drag it. Doesn't drags labels though...:
Code:
procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := AWndProc;
end;

procedure TForm1.AWndProc(var AMsg: TMsg; var Handled: Boolean);
var
  APoint : TPoint;
  ARect  : TRect;
begin
  case AMsg.message of
   WM_MOUSEMOVE :
   begin
     if (GetParent(AMsg.hwnd) = 0) then Exit;
     if ((AMsg.wParam and MK_RBUTTON) > 0) then
     begin
       GetWindowRect(AMsg.hwnd, ARect);
       APoint.x := LOWORD(AMsg.lParam);
       APoint.y := HIWORD(AMsg.lParam);
       Windows.ClientToScreen(AMsg.hwnd, APoint);
       Windows.ScreenToClient(GetParent(AMsg.hwnd), APoint);
       APoint.x := APoint.x + Round((ARect.Left - ARect.Right) / 2);
       APoint.y := APoint.y + Round((ARect.Top - ARect.Bottom) / 2);
       SetWindowPos(AMsg.hwnd, 0, APoint.x, APoint.y, 0, 0, SWP_NOZORDER or SWP_NOSIZE);
     end;
   end;
  end;
end;

--- markus
 
Why can't I move a label at run-time?
Can I move all other standard components in run-time?

Thanks in advance:)
 
Er, you can. Just change the Left and Top properties of the label.
 
Hello,

Give-me an example how to move a label component using mouse in a form at run-time...

Thanks:)
 
SolveProblems,

I think we're a bit confused about your confusion. You can move components at runtime by assigning new values to the appropriate positional properties. In this case, for example, you would add code to mouse movement events designed to adjust your Label's Top and Left properties in response to mouse actions taken by the user.

Here's a *very* crude example of one way to do this. (There are many others):

Code:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure Label1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Label1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Label1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  fOffsetX,
  fOffsetY : Integer;

implementation

{$R *.dfm}

procedure TForm1.Label1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
   Label1.Tag := 1;
end;

procedure TForm1.Label1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
   if Label1.Tag = 1 then
   begin
     fOffsetX := X;
     fOffsetY := Y;
   end;
end;

procedure TForm1.Label1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
   Label1.Tag  := 0;
   Label1.Left := Label1.Left + fOffsetX;
   Label1.Top  := Label1.Top + fOffsetY;
   fOffsetX    := 0;
   fOffsetY    := 0;
end;

end.

To move the component, drag it during runtime (just like you would at Design time).

Hope this helps...

-- Lance
 
Solution (Version 2) drag everything on a form when right mouse button is pressed :)
Code:
procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := AWndProc;
end;

procedure TForm1.AWndProc(var AMsg: TMsg; var Handled: Boolean);
var
  APoint, PT : TPoint;
  ARect      : TRect;
  AForm      : TForm;
  i          : Integer;
begin
  // AControl variable is declaered in public section of a form :
  // AControl : TControl;
  case AMsg.message of
   WM_RBUTTONDOWN :
   begin
     AForm := Screen.ActiveForm;
     for i := 0 to AForm.ControlCount - 1 do
     begin
       PT.x := LOWORD(AMsg.lParam);
       PT.y := HIWORD(AMsg.lParam);
       APoint.x := AForm.Controls[i].Left;
       APoint.y := AForm.Controls[i].Top;
       if (AForm.Controls[i] is TWinControl)then
       begin
         MapWindowPoints(GetParent(AMsg.hwnd), 0, APoint, 1);
         MapWindowPoints(AMsg.hwnd, 0, PT, 1);
       end
       else
       begin
         MapWindowPoints(AForm.Controls[i].Parent.Handle, 0, APoint, 1);
         MapWindowPoints(AForm.Controls[i].Parent.Handle, 0, PT, 1);
       end;
       ARect.Left  := APoint.x;
       ARect.Right := ARect.Left + AForm.Controls[i].Width;
       ARect.Top   := APoint.y;
       ARect.Bottom:= ARect.Top + AForm.Controls[i].Height;
       if PtInRect(ARect, PT) then
       begin
         AControl := AForm.Controls[i];
         Break;
       end;
     end;
   end;
   WM_RBUTTONUP :
   begin
     AControl := nil;
   end;
   WM_MOUSEMOVE :
   begin
     if Assigned(AControl)and((AMsg.wParam and MK_RBUTTON) > 0)then
     begin
       APoint.x := LOWORD(AMsg.lParam);
       APoint.y := HIWORD(AMsg.lParam);
       MapWindowPoints(AMsg.hwnd, 0, APoint, 1);
       if (AControl is TWinControl)then
        Windows.ScreenToClient(GetParent(TWinControl(AControl).Handle), APoint)
       else
        APoint := AControl.Parent.ScreenToClient(APoint);
       AControl.Left := APoint.x - Round(AControl.Width / 2);
       AControl.Top  := APoint.y - Round(AControl.Height / 2);
     end;
   end;
  end;
end;
Have fun.

--- markus
 
> Why can't I move a label at run-time?
> Can I move all other standard components in run-time?

The examples people gave above this question used window handles. Delphi controls break down into two groups: those that have a window handle, and those that don't. It's easy to tell the difference: look 'em up in the help, click on Hierarchy. If it's descended from TWinControl, then it's a windowed control, and has a window handle. Many things (TEdit, TPanel, TStaticText) are descended from TWinControl; some (TLabel, TImage) are not.

Get rid of your TLabels and replace 'em with TStaticText, and the above window handle based solutions will work. Or you can use a solution like footpad's, which doesn't depend on the window handle. -- Doug Burbidge mailto:dougburbidge@yahoo.com
 
Doug, to move a label you don't always need it's handle. It was needed in my first example, but in the second example it's not needed.

--- markus
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top