Partilhar via


Escrever a função da janela

A função DispatchMessage chama o procedimento da janela que é o destino da mensagem. O procedimento da janela tem a seguinte assinatura.

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

Existem quatro parâmetros:

  • hwnd é uma alça para a janela.
  • uMsg é o código da mensagem; Por exemplo, a mensagem WM_SIZE indica que a janela foi redimensionada.
  • wParam e lParam contêm dados adicionais que pertencem à mensagem. O significado exato depende do código da mensagem.

LRESULT é um valor inteiro que o programa retorna ao Windows. Ele contém a resposta do seu programa a uma mensagem específica. O significado desse valor depende do código da mensagem. CALLBACK é a convenção de chamada para a função.

Um procedimento de janela típico é simplesmente uma instrução de switch grande que ativa o código da mensagem. Adicione casos para cada mensagem que pretende tratar.

switch (uMsg)
{
    case WM_SIZE: // Handle window resizing

    // etc
}

Dados adicionais para a mensagem estão contidos nos parâmetros lParam e wParam. Ambos os parâmetros são valores inteiros do tamanho de uma largura de ponteiro (32 bits ou 64 bits). O significado de cada um depende do código da mensagem (uMsg). Para cada mensagem, você precisará procurar o código da mensagem e converter os parâmetros para o tipo de dados correto. Normalmente, os dados são um valor numérico ou um ponteiro para uma estrutura. Algumas mensagens não têm dados.

Por exemplo, a documentação da mensagem WM_SIZE indica que:

  • wParam é um sinalizador que indica se a janela foi minimizada, maximizada ou redimensionada.
  • lParam contém a nova largura e altura da janela como valores de 16 bits compactados em um número de 32 ou 64 bits. Você precisará realizar algum deslocamento de bits para obter esses valores. Felizmente, o arquivo de cabeçalho WinDef.h inclui macros auxiliares que fazem isso.

Um procedimento de janela típico lida com dezenas de mensagens, por isso pode tornar-se bastante extenso. Uma maneira de tornar seu código mais modular é colocar a lógica para lidar com cada mensagem em uma função separada. No procedimento de janela, converta os parâmetros wParam e lParam para o tipo de dados correto e passe esses valores para a função. Por exemplo, para manipular a mensagem WM_SIZE, o procedimento de janela teria esta aparência:

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_SIZE:
        {
            int width = LOWORD(lParam);  // Macro to get the low-order word.
            int height = HIWORD(lParam); // Macro to get the high-order word.

            // Respond to the message:
            OnSize(hwnd, (UINT)wParam, width, height);
        }
        break;
    }
}

void OnSize(HWND hwnd, UINT flag, int width, int height)
{
    // Handle resizing
}

O macros LOWORD e macros HIWORD obtêm os valores de largura e de altura de 16 bits de lParam. O procedimento de janela extrai a largura e a altura e, em seguida, passa esses valores para a função OnSize.

Tratamento de mensagens padrão

Se você não manipular uma mensagem específica no procedimento da janela, passe os parâmetros da mensagem diretamente para a funçãoDefWindowProc do. Esta função executa a ação padrão para a mensagem, que varia de acordo com o tipo de mensagem.

return DefWindowProc(hwnd, uMsg, wParam, lParam);

Evitar gargalos na rotina de janela

Enquanto o procedimento da janela é executado, ele bloqueia quaisquer outras mensagens para janelas criadas no mesmo thread. Portanto, evite o processamento demorado dentro do procedimento da janela. Por exemplo, suponha que seu programa abra uma conexão TCP e aguarde indefinidamente que o servidor responda. Se você fizer isso dentro do procedimento da janela, sua interface do usuário não responderá até que a solicitação seja concluída. Durante esse tempo, a janela não pode processar a entrada do mouse ou teclado, repintar-se ou até mesmo fechar.

Em vez disso, você deve mover o trabalho para outro thread, usando um dos recursos de multitarefa incorporados ao Windows:

  • Crie um novo thread.
  • Use um grupo de threads.
  • Utilize chamadas de E/S assíncronas.
  • Use chamadas de procedimento assíncronas.

Seguinte

Pintando a janela