2006. december 4., hétfő

Moving Controls over the form


Problem/Question/Abstract:

How is it possiple to move an control over the form ?

Answer:

It's very simple - so don't try to write hundreds of lines to solve this problem

Just take a look at this small source-snip

All what we need to do is to override the dynamic MouseDown method of the TControl-BaseClass and fire an WM_SysCommand event with the magicKey $F012.

I hope this article is helpful for you

{-----------------------------------------------------------------------------

hEaDRoOm Development
29.10.2002

Unit Name: HREdit
Author:    Benjamin Benjamin Wittfoth
Purpose:
History:
-----------------------------------------------------------------------------}
unit HREdit;

interface

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

type
  THREdit = class(TEdit)
  private
    fDragable: Boolean;
  protected
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
      override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Dragable: Boolean read fDragable write fDragable;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('HEADROOM DEVELOPMENT', [THREdit]);
end;

{ THREdit }

constructor THREdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
end;

destructor THREdit.Destroy;
begin
  inherited;
end;

procedure THREdit.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
const
  SC_DragMove = $F012; // important key  !!
begin
  inherited;
  if assigned(onMouseDown) then
    OnMouseDown(self, Button, Shift, x, y);
  if fDragable then
  begin
    ReleaseCapture;
    (self as TControl).perform(WM_SysCommand, SC_DragMove, 0); // this is the key !
  end;
end;

end.

If you put then next line after ReleaseCapture; the object will even come to the front before moving it and not just after.

(self as TControl).BringToFront;

Cordinates of control. Simply use an Timer on your form - i know this is not elegant, but it works.

procedure TForm1.TimerTimer(Sender: TObject);
begin
  Edit1.text := inttostr(Edit1.Left) + '/' + inttostr(Edit1.top);
end;

Nincsenek megjegyzések:

Megjegyzés küldése