If you are developing graphics or multimedia applications, you may be wondering how to move a form without using its title bar. In fact, you only need to drag the client area of the form with the mouse.
Method one
The following is the most common way to accomplish the above function: add the following procedure statement in the PRivate statement section of the form:
procedure WMNCHitTest(var Msg:TWMNCHitTest);message WM_NCHITTEST;
Then add the following code in the implementation section:
procedure TForm1{or the Form name you defined}.WMNCHitTest(var Msg:TWMNCHitTest);
begin
DefaultHandler(Msg);
if Msg.Result = HTCLIENT then
Msg.Result:= HTCAPTION;
end;
This method makes Windows think that the title bar was clicked when the mouse clicks on the client area of the form.
Method two
Here is another way to move a normal form with the mouse.
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if (ssLeft in Shift) then begin
ReleaseCapture;
SendMessage(Form1.Handle,WM_SYSCOMMAND,SC_MOVE+1,0);
end;
end;
Imperfections of the above methods
Let's see what happens when you uncheck the "Show contents of window while dragging" option. This is a setting for Windows windows. You can find this property in "Start Menu --> Settings --> Folder Options --> View --> Advanced Settings". In Windows95, you need to modify the registry. When this property is set to invalid, the form will change to a square outline when dragged. Maybe you use an irregular form, but it still shows outlines.
When you want your form to be docked at the edge of the screen (for example: WinAmp, when you drag the form to a specific position at the top of the screen, the form will be close to the top of the screen), if you use the second step above This way, you won't be able to handle the form position until the mouse button is released, and you won't be able to handle docking issues.
Below I will use simple methods to solve two problems:
First, no matter what the setting is, the outline will not be displayed when dragging the form;
Second, position detection is performed when the form is moved, and it is docked at a specific location when the position is appropriate.
Many people may have solved these problems, but maybe the code below will help you.
Method three
The following code can be copied directly into Delphi, provided that you save Form1 as uMain.pas and Form2 as uDock.pas. The events used are: OnMouseDown, OnMouseMove, OnMouseUp, OnShow (Form1).
This is a method to move a form based on mouse movement, including two forms, uMain and uDock (Form1 and Form2). Form2 is opened through Form1 and can be docked to the bottom of Form1. Once docked, Form2 will move with Form1 until you move Form2 out of the way.
Form1
unit uMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormMouseDown(Sender:TObject; Button:TMouseButton;Shift:TShiftState;X,Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState;X,Y: Integer);
procedure FormMouseUp(Sender:TObject;Button:TMouseButton;Shift:TShiftState;X,Y: Integer);
procedure FormShow(Sender: TObject);
private
{Private declarations}
public
DocktoForm: Boolean;
{Public declarations}
end;
var
Form1: TForm1;
CanMove, CanMoveX, CanMoveY: Boolean;
OldX, OldY: Integer;
F1X,F1Y,F2X,F2Y: integer;
WorkArea : TRect;
implementation
uses uDock;
{$R *.DFM}
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
begin
CanMoveX := true;
CanMoveY := true;
CanMove := true;
OldX := X;
OldY := Y;
ifDocktoForm then
begin
F1X := Form1.Left;
F1Y := Form1.Top;
F2X := Form2.Left;
F2Y := Form2.Top;
end;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if (CanMove) then
begin
if CanMoveX then
Form1.Left := Form1.Left + (X - OldX);
if CanMoveY then
Form1.Top := Form1.Top + (Y - OldY);
//This section latches to the top
if (Form1.Top < WorkArea.Top + 10) and (Form1.Top > WorkArea.Top-10) then
begin
Form1.Top := WorkArea.Top;
if (Y-OldY > 10) or (Y-OldY < -10) then
CanMoveY := true
else
CanMoveY := False;
end;
//This section latches to the left side
if (Form1.Left < WorkArea.Left+10) and (Form1.Left > WoskArea.Left-10) then
begin
Form1.Left := WorkArea.Left;
if (X-OldX > 10) or (X-OldX < -10) then
CanMoveX := true
else
CanMoveX := False;
end;
//This section latches to the right side
if (Form1.Left > WorkArea.Right-Form1.Width-10) and (Form1.Left < WorkArea.Right-Form1.Width+10) then
begin
Form1.Left := WorkArea.Right-Form1.Width;
if (X-OldX > 10) or (X-OldX < -10) then
CanMoveX := true
else
CanMoveX := False;
end;
//This section latches to the TaskBar
ifDocktoForm then
begin
if (Form1.Top > WorkArea.Bottom-Form1.Height-Form2.Height-10) and (Form1.Top < WorkArea.Bottom-Form1.Height-Form2.Height+10) then
begin
Form1.Top := WorkArea.Bottom-Form1.Height-Form2.Height;
if (Y-OldY > 10) or (Y-OldY < -10) then
CanMoveY := true
else
CanMoveY := False;
end;
end
else begin
if (Form1.Top > WorkArea.Bottom-Form1.Height-10) and (Form1.Top < WorkArea.Bottom-Form1.Height+10) then
begin
Form1.Top := WorkArea.Bottom-Form1.Height;
if (Y-OldY > 10) or (Y-OldY < -10) then
CanMoveY := true
else
CanMoveY := False;
end;
end;
ifDocktoForm then
begin
Form2.Left := Form1.Left - (F1X-F2X);// + (X-OldX);
Form2.Top := Form1.Top+Form1.Height;
exit;
end;
//This section latches playlist in center of Form1
if (Form2.Left > Form1.Left + ((Form1.Width div 2)-(Form2.Width div 2))-10) and (Form2.Left < Form1.Left + ((Form1.Width div 2)-( Form2.Width div 2))+10) and
(Form2.Top > Form1.Top+Form1.Height-10) and (Form2.Top < Form1.Top+Form1.Height+10) then
begin
Form2.Left := Form1.Left + ((Form1.Width div 2)-(Form2.Width div 2));
DocktoForm := True;
F1X := Form1.Left;
F1Y := Form1.Top;
F2X := Form2.Left;
F2Y := Form2.Top;
end;
end;
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
CanMove := false;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
//Get Work Area Parameters
SystemParametersInfo(SPI_GETWORKAREA, 0, @WorkArea, 0);
Form2.Show;
end;
end.
Form2
unit uDock;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm2 = class(TForm)
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
private
{Private declarations}
public
{Public declarations}
end;
var
Form2: TForm2;
CanMove, CanMoveX, CanMoveY, DocktoForm: Boolean;
OldX, OldY: Integer;
implementation
uses uMain;
{$R *.DFM}
procedure TForm2.FormMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
begin
CanMoveX := true;
CanMoveY := true;
CanMove := true;
OldX := X;
OldY := Y;
end;
procedure TForm2.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if (CanMove) then
begin
if CanMoveX then
Form2.Left := Form2.Left + (X - OldX);
if CanMoveY then
Form2.Top := Form2.Top + (Y - OldY);
//This section latches to the top
if (Form2.Top < WorkArea.Top + 10) and (Form2.Top > WorkArea.Top-10) then
begin
Form2.Top := WorkArea.Top;
if (Y-OldY > 10) or (Y-OldY < -10) then
CanMoveY := true
else
CanMoveY := False;
end;
//This section latches to the left side
if (Form2.Left < WorkArea.Left+10) and (Form2.Left > WorkArea.Left-10) then
begin
Form2.Left := WorkArea.Left;
if (X-OldX > 10) or (X-OldX < -10) then
CanMoveX := true
else
CanMoveX := False;
end;
//This section latches to the right side
if (Form2.Left > WorkArea.Right-Form2.Width-10) and (Form2.Left < WorkArea.Right-Form2.Width+10) then
begin
Form2.Left := WorkArea.Right-Form2.Width;
if (X-OldX > 10) or (X-OldX < -10) then
CanMoveX := true
else
CanMoveX := False;
end;
//This section latches to the TaskBar
if (Form2.Top > WorkArea.Bottom-Form2.Height-10) and (Form2.Top < WorkArea.Bottom-Form2.Height+10) then
begin
Form2.Top := WorkArea.Bottom-Form2.Height;
if (Y-OldY > 10) or (Y-OldY < -10) then
CanMoveY := true
else
CanMoveY := False;
exit;
end;
//This section latches to the Player Bottom
if (Form2.Top > Form1.Top+Form1.Height-10) and (Form2.Top < Form1.Top+Form1.Height+10) and (Form2.Left > Form1.Left-Form2.Width) and (Form2. Left < Form1.Left + Form1.Width) then
begin
Form2.Top := Form1.Top+Form1.Height;
if (Y-OldY > 10) or (Y-OldY < -10) then begin
CanMoveY := true;
Form1.DockToForm := False;
end
else begin
CanMoveY := False;
Form1.DockToForm := True;
end;
end;
//This section latches playlist in center of Form1
if (Form2.Left > Form1.Left + ((Form1.Width div 2)-(Form2.Width div 2))-10) and (Form2.Left < Form1.Left + ((Form1.Width div 2)-( Form2.Width div 2))+10) and
(Form2.Top > Form1.Top+Form1.Height-10) and (Form2.Top < Form1.Top+Form1.Height+10) then
begin
Form2.Left := Form1.Left + ((Form1.Width div 2)-(Form2.Width div 2));
if (X-OldX > 10) or (X-OldX < -10) or (Y-OldY > 10) or (Y-OldY < -10) then
CanMoveX := true
else
CanMoveX := False;
end;
end;
end;
procedure TForm2.FormMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
begin
CanMove := false;
end;
end.
I hope the above is helpful to those who are struggling with similar content.