13

how do I move a borderless form? I tried looking on the internet, but nothing. Thanks a lot.

Giacomo King Patermo
  • 829
  • 3
  • 13
  • 25
  • may be here : http://delphi.about.com/od/windowsshellapi/a/dragnocaption.htm – philnext Jun 06 '12 at 19:54
  • Duplicate of [C++Builder: Create a TForm with BorderStyle bsNone that is nevertheless movable and resizable](http://stackoverflow.com/questions/7178030/cbuilder-create-a-tform-with-borderstyle-bsnone-that-is-nevertheless-movable) - that code is for C++Builder, but it's still the same VCL! It should be trivial to change to Delphi. – David Jun 06 '12 at 20:16

2 Answers2

29

You can drag a form using any contained control, including itself.

Using the following example, you can move a form by clicking on its canvas and dragging. You could do the same with a panel on the form by putting the same code in the panel's MouseDown event, which would let you create your own pseudo caption bar.

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
const
  SC_DRAGMOVE = $F012;
begin
  if Button = mbLeft then
  begin
    ReleaseCapture;
    Perform(WM_SYSCOMMAND, SC_DRAGMOVE, 0);
  end;
end;
Bruce McGee
  • 15,076
  • 6
  • 55
  • 70
13

If you mean dragging the window by the mouse, you can override WM_NCHITTEST message handling and return HTCAPTION for the drag region. The below will drag the window within the upper 30 pixels for insance:

type
  TForm1 = class(TForm)
  private
  protected
    procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
  end;

..

procedure TForm1.WMNCHitTest(var Message: TWMNCHitTest);
var
  Pt: TPoint;
begin
  Pt := ScreenToClient(SmallPointToPoint(Message.Pos));
  if Pt.Y < 30 then
    Message.Result := HTCAPTION
  else
    inherited;
end;
Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
  • @David: Lately, I have been a bit sceptic to this approach, because, basically, you are telling the OS that *the entire form is the window's caption*, which might not actually be semantically true. (Well, in Sertac's code, perhaps the first 30 pixels *are* in fact the caption, but generally, this might not be true.) – Andreas Rejbrand Jun 06 '12 at 20:26
  • @andreas Do you have any concrete reason to reject this? What are the downsides? This is the standard approach. – David Heffernan Jun 06 '12 at 20:36
  • @David: No, no concrete downside that I can think of. – Andreas Rejbrand Jun 06 '12 at 20:39
  • 1
    An alternative is to implement an OnMouseDown handler, where you set a move state and store the mouse down position, a OnMouseMove handler where you move the form, and an OnMouseUp handler, where you clear the move state. It's not that much work. It for instance has the benefit of letting you decide for yourself how many pixels the mouse should move before you initiate the move. This sometimes can be desirable. – bjaastad_e Jun 06 '12 at 20:41
  • I'm trying to use this method and I've found that I can't close the form by the "X" button. So, there's one downside. I suppose I could just drop a tiny button and write the code, of course. – Craig Stevensson Oct 16 '14 at 19:08
  • 1
    @Craig - Call the `inherited` first, modify the result only if it's 'HTCLIENT'. Alternatively modify your intervention region to exclude the buttons. – Sertac Akyuz Oct 16 '14 at 21:04