Se você estiver desenvolvendo aplicações gráficas ou multimídia, você pode estar se perguntando como mover um formulário sem usar sua barra de título. Na verdade, você só precisa arrastar a área cliente do formulário com o mouse.
Método um
A seguir está a maneira mais comum de realizar a função acima: adicione a seguinte instrução de procedimento na seção de instrução PRivate do formulário:
procedimento WMNCHitTest(var Msg:TWMNCHitTest); mensagem WM_NCHITTEST;
Em seguida, adicione o seguinte código na seção de implementação:
procedimento TForm1{ou o nome do formulário que você definiu}.WMNCHitTest(var Msg:TWMNCHitTest);
começar
DefaultHandler(Mensagem);
se Msg.Result = HTCLIENT então
Msg.Result:= HTCAPTION;
fim;
Este método faz o Windows pensar que a barra de título foi clicada quando o mouse clica na área cliente do formulário.
Método dois
Aqui está outra maneira de mover uma forma normal com o mouse.
procedimento TForm1.FormMouseMove(Remetente: TObject; Shift: TShiftState; X, Y: Inteiro);
começar
if (ssLeft em Shift) então comece
Liberar Captura;
EnviarMensagem(Form1.Handle,WM_SYSCOMMAND,SC_MOVE+1,0);
fim;
fim;
Imperfeições dos métodos acima
Vamos ver o que acontece quando você desmarca a opção “Mostrar conteúdo da janela ao arrastar”. Esta é uma configuração para janelas do Windows. Você pode encontrar esta propriedade em "Menu Iniciar -> Configurações -> Opções de Pasta -> Exibir -> Configurações Avançadas". No Windows95, você precisa modificar o registro. Quando esta propriedade for definida como inválida, o formulário mudará para um contorno quadrado quando arrastado. Talvez você use uma forma irregular, mas ainda mostra contornos.
Quando você deseja que seu formulário fique encaixado na borda da tela (por exemplo: WinAmp, ao arrastar o formulário para uma posição específica no topo da tela, o formulário ficará próximo ao topo da tela), se você usa a segunda etapa acima. Dessa forma, você não será capaz de controlar a posição do formulário até que o botão do mouse seja liberado e não será capaz de lidar com problemas de encaixe.
Abaixo usarei métodos simples para resolver dois problemas:
Primeiro, não importa qual seja a configuração, o contorno não será exibido ao arrastar o formulário;
Segundo, a detecção de posição é realizada quando o formulário é movido e é encaixado em um local específico quando a posição é apropriada.
Muitas pessoas podem ter resolvido esses problemas, mas talvez o código abaixo possa ajudá-lo.
Método três
O código a seguir pode ser copiado diretamente no Delphi, desde que você salve o Form1 como uMain.pas e o Form2 como uDock.pas. Os eventos utilizados são: OnMouseDown, OnMouseMove, OnMouseUp, OnShow (Form1).
Este é um método para mover um formulário baseado no movimento do mouse, incluindo dois formulários, uMain e uDock (Form1 e Form2). O Form2 é aberto através do Form1 e pode ser encaixado na parte inferior do Form1. Uma vez encaixado, o Form2 se moverá com o Form1 até que você mova o Form2 para fora do caminho.
Formulário1
unidade uPrincipal;
interface
usa
Windows, Mensagens, SysUtils, Classes, Gráficos, Controles, Formulários, Diálogos;
tipo
TForm1 = classe(TForm)
procedimento FormMouseDown(Sender:TObject; Button:TMouseButton;Shift:TShiftState;X,Y: Integer);
procedimento FormMouseMove(Remetente: TObject; Shift: TShiftState;X,Y: Inteiro);
procedimento FormMouseUp(Sender:TObject;Button:TMouseButton;Shift:TShiftState;X,Y: Integer);
procedimento FormShow(Remetente: TObject);
privado
{Declarações privadas}
público
DocktoForm: Booleano;
{Declarações públicas}
fim;
var
Formulário1: TForm1;
CanMove, CanMoveX, CanMoveY: Booleano;
AntigoX, AntigoY: Inteiro;
F1X,F1Y,F2X,F2Y: inteiro;
Área de Trabalho: TRect;
implementação
usa o uDock;
{$R *.DFM}
procedimento TForm1.FormMouseDown(Remetente: TObject; Botão: TMouseButton;Shift: TShiftState; X, Y: Inteiro);
começar
CanMoveX := verdadeiro;
CanMoveY := verdadeiro;
CanMove := verdadeiro;
AntigoX := X;
AntigoY := S;
ifDocktoForm então
começar
F1X := Formulário1.Esquerda;
F1Y := Formulário1.Top;
F2X := Form2.Esquerda;
F2Y := Form2.Top;
fim;
fim;
procedimento TForm1.FormMouseMove(Remetente: TObject; Shift: TShiftState; X, Y: Inteiro);
começar
se (CanMove) então
começar
se CanMoveX então
Form1.Left := Form1.Left + (X - OldX);
se CanMoveY então
Form1.Top := Form1.Top + (Y - AntigoY);
//Esta seção trava no topo
se (Form1.Top < WorkArea.Top + 10) e (Form1.Top > WorkArea.Top-10) então
começar
Form1.Top := WorkArea.Top;
se (Y-VelhoY > 10) ou (Y-VelhoY < -10) então
CanMoveY := verdadeiro
outro
CanMoveY := Falso;
fim;
//Esta seção trava no lado esquerdo
se (Form1.Left <WorkArea.Left+10) e (Form1.Left > WoskArea.Left-10) então
começar
Form1.Left := WorkArea.Left;
se (X-OldX > 10) ou (X-OldX < -10) então
CanMoveX := verdadeiro
outro
CanMoveX := Falso;
fim;
//Esta seção trava no lado direito
se (Form1.Left > WorkArea.Right-Form1.Width-10) e (Form1.Left <WorkArea.Right-Form1.Width+10) então
começar
Form1.Left := WorkArea.Right-Form1.Width;
se (X-OldX > 10) ou (X-OldX < -10) então
CanMoveX := verdadeiro
outro
CanMoveX := Falso;
fim;
//Esta seção trava na TaskBar
ifDocktoForm então
começar
se (Form1.Top > WorkArea.Bottom-Form1.Height-Form2.Height-10) e (Form1.Top <WorkArea.Bottom-Form1.Height-Form2.Height+10) então
começar
Form1.Top := WorkArea.Bottom-Form1.Height-Form2.Height;
se (Y-VelhoY > 10) ou (Y-VelhoY < -10) então
CanMoveY := verdadeiro
outro
CanMoveY := Falso;
fim;
fim
senão começar
se (Form1.Top > WorkArea.Bottom-Form1.Height-10) e (Form1.Top <WorkArea.Bottom-Form1.Height+10) então
começar
Form1.Top := WorkArea.Bottom-Form1.Height;
se (Y-VelhoY > 10) ou (Y-VelhoY < -10) então
CanMoveY := verdadeiro
outro
CanMoveY := Falso;
fim;
fim;
ifDocktoForm então
começar
Form2.Left := Form1.Left - (F1X-F2X);// + (X-OldX);
Form2.Top := Form1.Top+Form1.Altura;
saída;
fim;
//Esta seção trava a playlist no centro do Form1
if (Form2.Left > Form1.Left + ((Form1.Width div 2)-(Form2.Width div 2))-10) e (Form2.Left < Form1.Left + ((Form1.Width div 2)-( Form2.Largura div 2))+10) e
(Form2.Top > Form1.Top+Form1.Height-10) e (Form2.Top <Form1.Top+Form1.Height+10) então
começar
Form2.Left := Form1.Left + ((Form1.Largura div 2)-(Form2.Largura div 2));
DocktoForm := Verdadeiro;
F1X := Formulário1.Esquerda;
F1Y := Formulário1.Top;
F2X := Form2.Esquerda;
F2Y := Form2.Top;
fim;
fim;
fim;
procedimento TForm1.FormMouseUp(Remetente: TObject; Botão: TMouseButton; Shift: TShiftState; X, Y: Inteiro);
começar
CanMove := falso;
fim;
procedimento TForm1.FormShow(Remetente: TObject);
começar
//Obter parâmetros da área de trabalho
SystemParametersInfo(SPI_GETWORKAREA, 0, @WorkArea, 0);
Form2.Mostrar;
fim;
fim.
Formulário2
unidade uDock;
interface
usa
Windows, Mensagens, SysUtils, Classes, Gráficos, Controles, Formulários, Diálogos;
tipo
TForm2 = classe(TForm)
procedimento FormMouseDown(Remetente: TObject; Botão: TMouseButton;Shift: TShiftState; X, Y: Inteiro);
procedimento FormMouseMove(Remetente: TObject; Shift: TShiftState; X,Y: Inteiro);
procedimento FormMouseUp(Remetente: TObject; Botão: TMouseButton;Shift: TShiftState; X, Y: Inteiro);
privado
{Declarações privadas}
público
{Declarações públicas}
fim;
var
Formulário2: TForm2;
CanMove, CanMoveX, CanMoveY, DocktoForm: Booleano;
AntigoX, AntigoY: Inteiro;
implementação
usa uMain;
{$R *.DFM}
procedimento TForm2.FormMouseDown(Remetente: TObject; Botão: TMouseButton;Shift: TShiftState; X, Y: Inteiro);
começar
CanMoveX := verdadeiro;
CanMoveY := verdadeiro;
CanMove := verdadeiro;
AntigoX := X;
AntigoY := S;
fim;
procedimento TForm2.FormMouseMove(Remetente: TObject; Shift: TShiftState; X, Y: Inteiro);
começar
se (CanMove) então
começar
se CanMoveX então
Form2.Left := Form2.Left + (X - OldX);
se CanMoveY então
Form2.Top := Form2.Top + (Y - AntigoY);
//Esta seção trava no topo
se (Form2.Top < WorkArea.Top + 10) e (Form2.Top > WorkArea.Top-10) então
começar
Form2.Top := WorkArea.Top;
se (Y-VelhoY > 10) ou (Y-VelhoY < -10) então
CanMoveY := verdadeiro
outro
CanMoveY := Falso;
fim;
//Esta seção trava no lado esquerdo
se (Form2.Left <WorkArea.Left+10) e (Form2.Left > WorkArea.Left-10) então
começar
Form2.Left := WorkArea.Left;
se (X-OldX > 10) ou (X-OldX < -10) então
CanMoveX := verdadeiro
outro
CanMoveX := Falso;
fim;
//Esta seção trava no lado direito
se (Form2.Left > WorkArea.Right-Form2.Width-10) e (Form2.Left <WorkArea.Right-Form2.Width+10) então
começar
Form2.Left := WorkArea.Right-Form2.Width;
se (X-OldX > 10) ou (X-OldX < -10) então
CanMoveX := verdadeiro
outro
CanMoveX := Falso;
fim;
//Esta seção trava na TaskBar
se (Form2.Top > WorkArea.Bottom-Form2.Height-10) e (Form2.Top <WorkArea.Bottom-Form2.Height+10) então
começar
Form2.Top := WorkArea.Bottom-Form2.Height;
se (Y-VelhoY > 10) ou (Y-VelhoY < -10) então
CanMoveY := verdadeiro
outro
CanMoveY := Falso;
saída;
fim;
//Esta seção trava na parte inferior do player
if (Form2.Top > Form1.Top+Form1.Height-10) e (Form2.Top < Form1.Top+Form1.Height+10) e (Form2.Left > Form1.Left-Form2.Width) e (Form2. Esquerda <Form1.Left + Form1.Width) então
começar
Form2.Top := Form1.Top+Form1.Altura;
se (Y-OldY > 10) ou (Y-OldY < -10) então comece
CanMoveY := verdadeiro;
Form1.DockToForm := Falso;
fim
senão começar
CanMoveY := Falso;
Form1.DockToForm := Verdadeiro;
fim;
fim;
//Esta seção trava a playlist no centro do Form1
if (Form2.Left > Form1.Left + ((Form1.Width div 2)-(Form2.Width div 2))-10) e (Form2.Left < Form1.Left + ((Form1.Width div 2)-( Form2.Largura div 2))+10) e
(Form2.Top > Form1.Top+Form1.Height-10) e (Form2.Top <Form1.Top+Form1.Height+10) então
começar
Form2.Left := Form1.Left + ((Form1.Largura div 2)-(Form2.Largura div 2));
se (X-VelhoX > 10) ou (X-VelhoX < -10) ou (Y-VelhoY > 10) ou (Y-VelhoY < -10) então
CanMoveX := verdadeiro
outro
CanMoveX := Falso;
fim;
fim;
fim;
procedimento TForm2.FormMouseUp(Remetente: TObject; Botão: TMouseButton;Shift: TShiftState; X, Y: Inteiro);
começar
CanMove := falso;
fim;
fim.
Espero que o que foi dito acima seja útil para aqueles que estão lutando com conteúdo semelhante.