Ir para o conteúdo

Movimentação de Controlos em Run-Time

Quando é necessário movimentar controlos com o rato, existem diferentes códigos que necessitam de cálculos, variáveis, etc, de modo a arrastar o controlo de um lugar para o outro, enquanto o botão do rato estiver pressionado.

Se é verdade que não é muito utilizado é verdade que quando é preciso não é um processo muito simples de fazer (pelo menos dá algum trabalho).

A forma mais simples de o fazer (que eu tenha conhecimento) é utilizando o método DefWndProc() que permite enviar mensagens para o sistema. É uma utilização de subclasses que irá fazer o mesmo que o Windows faz quando o utilizador pressiona o rato na barra de título e arrasta-o.

Ora isto permite simplificar uma série de coisas como arrastar um controlo (como por exemplo, uma Label ou TextBox) ou mesmo o próprio Form. No caso do Form, e quando este não tem barra de título, dá imenso jeito.

Dois exemplos para uma TextBox e o Form.

Exemplo

    ' Constantes com a indicação de que o utilizador pressiona 
    ' o botão esquerdo do rato e da barra de titulo do Form
    Const WM_NCLBUTTONDOWN As Integer = &HA1
    Const HTCAPTION As Integer = 2


    ' Movimentação da TextBox no Form
    Private Sub TextBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles TextBox1.MouseDown

        ' Caso esteja a ser pressionado o botão esquerdo
        If e.Button = Windows.Forms.MouseButtons.Left Then

            ' Liberta a captura do rato. Esta captura vai a True
            ' quando o rato é pressionado, e impede a movimentação
            TextBox1.Capture = False

            ' Envia uma mensagem que irá movimentar o controlo
            Dim msg As Message = Message.Create(TextBox1.Handle, WM_NCLBUTTONDOWN, _
                    New IntPtr(HTCAPTION), IntPtr.Zero)
            Me.DefWndProc(msg)

        End If

    End Sub



    ' Movimentação do Form (sem comentários uma vez que é igual ao anterior)
    Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown

        If e.Button = Windows.Forms.MouseButtons.Left Then
            Me.Capture = False

            Dim msg As Message = Message.Create(Me.Handle, WM_NCLBUTTONDOWN, _
                    New IntPtr(HTCAPTION), IntPtr.Zero)
            Me.DefWndProc(msg)

        End If
    End Sub

É possível ainda utilizar outras constantes para fazer outras acções, como por exemplo, utilizando a HTBOTTOMRIGHT (Const HTBOTTOMRIGHT As Integer = 17) em vez da HTCAPTION, que irá efectuar o resize do Form. A constante HTBOTTOMRIGHT é a indicação de que o utilizador está a fazer o redimencionamento do Form no canto inferior direito.