Visão geral da entrada do mouse

O mouse é um dispositivo de entrada de usuário importante, mas opcional, para aplicativos. Um aplicativo bem escrito deve incluir uma interface do mouse, mas não deve depender apenas do mouse para adquirir a entrada do usuário. O aplicativo também deve fornecer suporte completo ao teclado.

Um aplicativo recebe a entrada do mouse na forma de mensagens enviadas ou postadas nas janelas.

Esta seção contém os seguintes tópicos:

Cursor do Mouse

Quando o usuário move o mouse, o sistema move um bitmap na tela chamado cursor do mouse. O cursor do mouse contém um ponto de pixel único chamado ponto de acesso, um ponto que o sistema rastreia e reconhece como a posição do cursor. Quando ocorre um evento do mouse, a janela que contém o ponto de acesso normalmente recebe a mensagem do mouse resultante do evento. A janela não precisa estar ativa ou ter o foco do teclado para receber uma mensagem do mouse.

O sistema mantém uma variável que controla a velocidade do mouse, ou seja, a distância que o cursor move quando o usuário move o mouse. Use a função SystemParametersInfo com o sinalizador SPI_GETMOUSE ou SPI_SETMOUSE para recuperar ou definir a velocidade do mouse. Para obter mais informações sobre cursores de mouse, confira Cursores.

Captura do mouse

O sistema normalmente posta uma mensagem do mouse na janela que contém o ponto de acesso do cursor quando ocorre um evento do mouse. Um aplicativo pode alterar esse comportamento usando a função SetCapture para rotear as mensagens do mouse para uma janela específica. A janela recebe todas as mensagens do mouse até que o aplicativo chame a função ReleaseCapture ou especifique outra janela de captura ou até que o usuário clique em uma janela criada por outro thread.

Quando a captura do mouse é alterada, o sistema envia uma mensagem WM_CAPTURECHANGED para a janela que está perdendo a captura do mouse. O parâmetro lParam da mensagem especifica um identificador para a janela que está ganhando a captura do mouse.

Somente a janela em primeiro plano pode capturar a entrada do mouse. Quando uma janela de tela de fundo tenta capturar a entrada do mouse, a janela só recebe mensagens de eventos do mouse que ocorrem quando o ponto de acesso do cursor está dentro da parte visível da janela.

A captura da entrada do mouse será útil se uma janela precisar receber toda a entrada do mouse, mesmo quando o cursor se mover para fora da janela. Por exemplo, um aplicativo normalmente rastreia a posição do cursor após um evento de botão do mouse pressionado, seguindo o cursor até que ocorra um evento de botão do mouse liberado. Se um aplicativo não tiver capturado a entrada do mouse e o usuário liberar o botão do mouse fora da janela, a janela não receberá a mensagem de botão liberado.

Um thread pode usar a função GetCapture para determinar se uma das janelas capturou o mouse. Se uma das janelas do thread tiver capturado o mouse, GetCapture vai recuperar um identificador para a janela.

Mouse ClickLock

O recurso de acessibilidade ClickLock do Mouse permite que um usuário bloqueie o botão principal do mouse após um só clique. Para um aplicativo, o botão ainda parece estar pressionado. Para desbloquear o botão, um aplicativo pode enviar qualquer mensagem do mouse ou o usuário pode clicar em qualquer botão do mouse. Esse recurso permite que um usuário faça combinações complexas de mouse de maneira mais simples. Por exemplo, pessoas com determinadas limitações físicas podem realçar um texto, arrastar objetos ou abrir menus com mais facilidade. Para obter mais informações, confira os seguintes sinalizadores e os Comentários em SystemParametersInfo:

  • SPI_GETMOUSECLICKLOCK
  • SPI_SETMOUSECLICKLOCK
  • SPI_GETMOUSECLICKLOCKTIME
  • SPI_SETMOUSECLICKLOCKTIME

Configuração do mouse

Embora o mouse seja um dispositivo de entrada importante para aplicativos, nem todos os usuários necessariamente têm um mouse. Um aplicativo pode determinar se o sistema inclui um mouse transmitindo o valor de SM_MOUSEPRESENT para a função GetSystemMetrics.

O Windows dá suporte a um mouse com até três botões. Em um mouse de três botões, os botões são designados como os botões esquerdo, do meio e direito. As mensagens e as constantes nomeadas relacionadas aos botões do mouse usam as letras L, M e R para identificar os botões. O botão em um mouse de botão único é considerado o botão esquerdo. Embora o Windows dê suporte a um mouse com vários botões, a maioria dos aplicativos usa o botão esquerdo principalmente e os outros minimamente, se for o caso.

Os aplicativos também podem dar suporte a um botão de rolagem do mouse. O botão de rolagem do mouse pode ser pressionado ou girado. Quando o botão de rolagem do mouse é pressionado, ele funciona como o botão do meio (terceiro), enviando mensagens normais do botão do meio para seu aplicativo. Quando ele é girado, uma mensagem do botão de rolagem é enviada ao aplicativo. Para obter mais informações, confira a seção O botão de rolagem do mouse.

Os aplicativos podem dar suporte a botões de comando de aplicativo. Esses botões, chamados de botões X, foram projetados para permitir o acesso mais fácil a um navegador da Internet, ao email eletrônico e aos serviços de mídia. Quando um botão X é pressionado, uma mensagem WM_APPCOMMAND é enviada ao aplicativo. Para obter mais informações, confira a descrição na mensagem WM_APPCOMMAND.

Um aplicativo pode determinar o número de botões no mouse transmitindo o valor de SM_CMOUSEBUTTONS para a função GetSystemMetrics. Para configurar o mouse para um usuário canhoto, o aplicativo pode usar a função SwapMouseButton para inverter o significado dos botões esquerdo e direito do mouse. A transmissão do valor SPI_SETMOUSEBUTTONSWAP para a função SystemParametersInfo é outra maneira de reverter o significado dos botões. Observe, no entanto, que o mouse é um recurso compartilhado, ou seja, reverter o significado dos botões afeta todos os aplicativos.

XBUTTONs

O Windows dá suporte a um mouse com cinco botões. Além dos botões esquerdo, do meio e direito, há o XBUTTON1 e o XBUTTON2, que fornecem a navegação regressiva e progressiva durante o uso do navegador.

O gerenciador de janelas dá suporte ao XBUTTON1 e ao XBUTTON2 por meio das mensagens WM_XBUTTON* e WM_NCXBUTTON*. A HIWORD do WPARAM nessas mensagens contém um sinalizador indicando o botão X que foi pressionado. Como essas mensagens do mouse se ajustam entre as constantes WM_MOUSEFIRST e WM_MOUSELAST, um aplicativo pode filtrar todas as mensagens do mouse com GetMessage ou PeekMessage.

As seguintes mensagens dão suporte ao XBUTTON1 e ao XBUTTON2:

As seguintes APIs foram modificadas para dar suporte a esses botões:

É improvável que uma janela filho em um aplicativo de componente consiga implementar comandos diretamente para o XBUTTON1 e o XBUTTON2. Portanto, DefWindowProc envia uma mensagem WM_APPCOMMAND para uma janela quando um botão X recebe um clique. DefWindowProc também envia a mensagem WM_APPCOMMAND para a janela pai. Isso é semelhante à maneira como os menus de contexto são invocados com um clique com o botão direito do mouse: DefWindowProc envia uma mensagem WM_CONTEXTMENU para o menu e a envia para o pai. Além disso, se DefWindowProc receber uma mensagem WM_APPCOMMAND para uma janela de nível superior, ele chamará um gancho de shell com o código HSHELL_APPCOMMAND.

Há suporte para os teclados que têm teclas extras para funções de navegador, funções de mídia, inicialização de aplicativos e gerenciamento de energia. Para obter mais informações, confira Teclas de teclado para navegação e outras funções.

Mensagens do mouse

O mouse gera um evento de entrada quando o usuário move o mouse ou pressiona ou libera um botão do mouse. O sistema converte eventos de entrada do mouse em mensagens e os posta na fila de mensagens do thread apropriado. Quando as mensagens do mouse são postadas mais rapidamente do que um thread pode processá-las, o sistema descarta todas, exceto a mensagem mais recente do mouse.

Uma janela recebe uma mensagem do mouse quando um evento do mouse ocorre enquanto o cursor está dentro das bordas da janela ou quando a janela captura o mouse. As mensagens do mouse são divididas em dois grupos: mensagens da área do cliente e mensagens da área que não é do cliente. Normalmente, um aplicativo processa as mensagens da área do cliente e ignora as mensagens da área que não é do cliente.

Esta seção contém os seguintes tópicos:

Mensagens do mouse da área do cliente

Uma janela recebe uma mensagem do mouse da área do cliente quando um evento do mouse ocorre dentro da área do cliente da janela. O sistema posta a mensagem WM_MOUSEMOVE na janela quando o usuário move o cursor dentro da área do cliente. Ele posta uma das mensagens a seguir quando o usuário pressiona ou libera um botão do mouse enquanto o cursor está dentro da área do cliente.

Mensagem Significado
WM_LBUTTONDBLCLK O botão esquerdo do mouse recebeu dois cliques.
WM_LBUTTONDOWN O botão esquerdo do mouse foi pressionado.
WM_LBUTTONUP O botão esquerdo do mouse foi liberado.
WM_MBUTTONDBLCLK O botão do meio do mouse recebeu dois cliques.
WM_MBUTTONDOWN O botão do meio do mouse foi pressionado.
WM_MBUTTONUP O botão do meio do mouse foi liberado.
WM_RBUTTONDBLCLK O botão direito do mouse recebeu dois cliques.
WM_RBUTTONDOWN O botão direito do mouse foi pressionado.
WM_RBUTTONUP O botão direito do mouse foi liberado.
WM_XBUTTONDBLCLK Um botão X do mouse recebeu dois cliques.
WM_XBUTTONDOWN Um botão X do mouse foi pressionado.
WM_XBUTTONUP Um botão X do mouse foi liberado.

 

Além disso, um aplicativo pode chamar a função TrackMouseEvent para que o sistema envie duas outras mensagens. Ele posta a mensagem WM_MOUSEHOVER quando o cursor é posicionado sobre a área do cliente por determinado tempo. Ele posta a mensagem WM_MOUSELEAVE quando o cursor sai da área do cliente.

Parâmetros de mensagem

O parâmetro lParam de uma mensagem do mouse da área do cliente indica a posição do ponto de acesso do cursor. A palavra de ordem inferior indica a coordenada x do ponto de acesso, e a palavra de ordem superior indica a coordenada y. As coordenadas são especificadas nas coordenadas do cliente. No sistema de coordenadas do cliente, todos os pontos na tela são especificados em relação às coordenadas (0,0) do canto superior esquerdo da área do cliente.

O parâmetro wParam contém sinalizadores que indicam o status dos outros botões do mouse e das teclas CTRL e SHIFT no momento do evento do mouse. Verifique a presença desses sinalizadores quando o processamento de mensagens do mouse depende do estado de outro botão do mouse ou da tecla CTRL ou SHIFT. O parâmetro wParam pode ser uma combinação dos valores a seguir.

Valor Descrição
MK_CONTROL A tecla CTRL está pressionada.
MK_LBUTTON O botão esquerdo do mouse está pressionado.
MK_MBUTTON O botão do meio do mouse está pressionado.
MK_RBUTTON O botão direito do mouse está pressionado.
MK_SHIFT A tecla SHIFT está pressionada.
MK_XBUTTON1 O primeiro botão X está pressionado.
MK_XBUTTON2 O segundo botão X está pressionado.

 

Mensagens de clique duplo

O sistema gera uma mensagem de clique duplo quando o usuário clica em um botão do mouse duas vezes em sequência rápida. Quando o usuário clica em um botão, o sistema estabelece um retângulo centralizado em torno do ponto de acesso do cursor. Ele marca a hora em que o clique ocorreu. Quando o usuário clica no mesmo botão uma segunda vez, o sistema determina se o ponto de acesso ainda está no retângulo e calcula o tempo decorrido desde o primeiro clique. Se o ponto de acesso ainda estiver no retângulo e o tempo decorrido não exceder o valor de tempo limite de clique duplo, o sistema vai gerar uma mensagem de clique duplo.

Um aplicativo pode obter e definir valores de tempo limite de clique duplo usando as funções GetDoubleClickTime e SetDoubleClickTime, respectivamente. Como alternativa, o aplicativo pode definir o valor de tempo limite de clique duplo usando o sinalizador SPI_SETDOUBLECLICKTIME com a função SystemParametersInfo. Ele pode definir o tamanho do retângulo que o sistema usa para detectar cliques duplos transmitindo os sinalizadores SPI_SETDOUBLECLKWIDTH e SPI_SETDOUBLECLKHEIGHT para SystemParametersInfo. No entanto, observe que a configuração do retângulo e do valor de clique duplo afeta todos os aplicativos.

Uma janela definida pelo aplicativo não recebe, por padrão, as mensagens de clique duplo. Devido à sobrecarga do sistema envolvida na geração de mensagens de clique duplo, essas mensagens são geradas apenas para janelas pertencentes às classes que têm o estilo de classe CS_DBLCLKS. Seu aplicativo precisa definir esse estilo ao registrar a classe de janela. Para obter mais informações, confira Classes de janela.

Uma mensagem de clique duplo é sempre a terceira mensagem em uma série de quatro mensagens. As duas primeiras mensagens são as mensagens de botão pressionado e de botão liberado geradas pelo primeiro clique. O segundo clique gera a mensagem de clique duplo seguida de outra mensagem de botão liberado. Por exemplo, se você clicar duas vezes no botão esquerdo do mouse, a seguinte sequência de mensagens será gerada:

  1. WM_LBUTTONDOWN
  2. WM_LBUTTONUP
  3. WM_LBUTTONDBLCLK
  4. WM_LBUTTONUP

Como uma janela sempre recebe uma mensagem de botão pressionado antes de receber uma mensagem de clique duplo, um aplicativo normalmente usa uma mensagem de clique duplo para estender uma tarefa iniciada durante uma mensagem de botão pressionado. Por exemplo, quando o usuário clica em uma cor na paleta de cores do Microsoft Paint, o Paint exibe a cor selecionada ao lado da paleta. Quando o usuário clica duas vezes em uma cor, o Paint exibe a cor e abre a caixa de diálogo Editar Cores.

Mensagens do mouse da área que não é do cliente

Uma janela recebe uma mensagem do mouse da área que não é do cliente quando um evento do mouse ocorre em qualquer parte de uma janela, exceto na área do cliente. A área que não é do cliente de uma janela consiste na borda, na barra de menus, na barra de título, na barra de rolagem, no menu de janela, no botão Minimizar e no botão Maximizar.

O sistema gera mensagens da área que não é do cliente principalmente para uso próprio. Por exemplo, o sistema usa mensagens da área que não é do cliente para alterar o cursor para uma seta de duas pontas quando o ponto de acesso do cursor se move para a borda de uma janela. Uma janela precisa transmitir mensagens do mouse da área que não é do cliente para a função DefWindowProc a fim de aproveitar a interface interna do mouse.

Há uma mensagem do mouse da área que não é do cliente correspondente para cada mensagem do mouse da área do cliente. Os nomes dessas mensagens são semelhantes, com a exceção de que as constantes nomeadas para as mensagens da área que não é do cliente incluem as letras NC. Por exemplo, mover o cursor na área que não é do cliente gera uma mensagem WM_NCMOUSEMOVE e pressionar o botão esquerdo do mouse enquanto o cursor está na área que não é do cliente gera uma mensagem WM_NCLBUTTONDOWN.

O parâmetro lParam de uma mensagem do mouse da área que não é do cliente é uma estrutura que contém as coordenadas x e y do ponto de acesso do cursor. Ao contrário das coordenadas das mensagens do mouse da área do cliente, as coordenadas são especificadas em coordenadas de tela em vez de coordenadas do cliente. No sistema de coordenadas de tela, todos os pontos na tela são relativos às coordenadas (0,0) do canto superior esquerdo da tela.

O parâmetro wParam contém um valor do teste de clique, um valor que indica em que ponto da área que não é do cliente o evento do mouse ocorreu. A seção a seguir explica a finalidade dos valores do teste de clique.

A mensagem WM_NCHITTEST

Sempre que ocorre um evento do mouse, o sistema envia uma mensagem WM_NCHITTEST para a janela que contém o ponto de acesso do cursor ou a janela que capturou o mouse. O sistema usa essa mensagem para determinar se deseja enviar uma mensagem do mouse da área do cliente ou da área que não é do cliente. Um aplicativo que precisa receber mensagens de botão e de movimento do mouse precisa transmitir a mensagem WM_NCHITTEST para a função DefWindowProc.

O parâmetro lParam da mensagem WM_NCHITTEST contém as coordenadas de tela do ponto de acesso do cursor. A função DefWindowProc examina as coordenadas e retorna um valor do teste de clique que indica o local do ponto de acesso. O valor do teste de clique pode ser um dos valores a seguir.

Valor Local do ponto de acesso
HTBORDER Na borda de uma janela que não tem uma borda de dimensionamento.
HTBOTTOM Na borda horizontal inferior de uma janela.
HTBOTTOMLEFT No canto inferior esquerdo de uma borda da janela.
HTBOTTOMRIGHT No canto inferior direito de uma borda da janela.
HTCAPTION Em uma barra de título.
HTCLIENT Em uma área do cliente.
HTCLOSE Em um botão Fechar.
HTERROR Na tela de fundo ou em uma linha divisória entre janelas (o mesmo que HTNOWHERE, com a exceção de que a função DefWindowProc produz um som do sistema para indicar um erro).
HTGROWBOX Em uma caixa de tamanho (o mesmo que HTSIZE).
HTHELP Em um botão Ajuda.
HTHSCROLL Em uma barra de rolagem horizontal.
HTLEFT Na borda esquerda de uma janela.
HTMENU Em um menu.
HTMAXBUTTON Em um botão Maximizar.
HTMINBUTTON Em um botão Minimizar.
HTNOWHERE Na tela de fundo ou em uma linha divisória entre as janelas.
HTREDUCE Em um botão Minimizar.
HTRIGHT Na borda direita de uma janela.
HTSIZE Em uma caixa de tamanho (o mesmo que HTGROWBOX).
HTSYSMENU Em um menu Sistema ou em um botão Fechar de uma janela filho.
HTTOP Na borda horizontal superior de uma janela.
HTTOPLEFT No canto superior esquerdo de uma borda da janela.
HTTOPRIGHT No canto superior direito de uma borda da janela.
HTTRANSPARENT Em uma janela atualmente coberta por outra janela no mesmo thread.
HTVSCROLL Na barra de rolagem vertical.
HTZOOM Em um botão Maximizar.

 

Se o cursor estiver na área do cliente de uma janela, DefWindowProc retornará o valor do teste de clique HTCLIENT para o procedimento de janela. Quando o procedimento de janela retorna esse código para o sistema, o sistema converte as coordenadas de tela do ponto de acesso do cursor em coordenadas do cliente e, em seguida, posta a mensagem apropriada do mouse da área do cliente.

A função DefWindowProc retorna um dos outros valores do teste de clique quando o ponto de acesso do cursor está na área que não é do cliente de uma janela. Quando o procedimento de janela retorna um desses valores do teste de clique, o sistema posta uma mensagem do mouse da área que não é do cliente, colocando o valor do teste de clique no parâmetro wParam da mensagem e as coordenadas do cursor no parâmetro lParam.

Sonar do Mouse

O recurso de acessibilidade Sonar do Mouse mostra brevemente vários círculos concêntricos ao redor do ponteiro quando o usuário pressiona e libera a tecla CTRL. Esse recurso ajuda um usuário a localizar o ponteiro do mouse em uma tela que está desordenada ou com resolução definida como alta, em um monitor de baixa qualidade ou para usuários com deficiência visual. Para obter mais informações, confira os seguintes sinalizadores em SystemParametersInfo:

SPI_GETMOUSESONAR

SPI_SETMOUSESONAR

Desaparecimento do Mouse

O recurso de acessibilidade Desaparecimento do Mouse oculta o ponteiro quando o usuário está digitando um texto. O ponteiro do mouse reaparece quando o usuário move o mouse. Esse recurso impede que o ponteiro obscureça o texto que está sendo digitado, por exemplo, em um email ou outro documento. Para obter mais informações, confira os seguintes sinalizadores em SystemParametersInfo:

SPI_GETMOUSEVANISH

SPI_SETMOUSEVANISH

O botão de rolagem do mouse

O botão de rolagem do mouse combina os recursos de um botão de rolagem e de um botão do mouse. O botão de rolagem tem entalhes discretos e uniformemente espaçados. Quando você gira o botão de rolagem, uma mensagem do botão de rolagem é enviada ao aplicativo conforme cada entalhe é encontrado. O botão de rolagem também pode funcionar como um botão do meio normal (terceiro) do Windows. Se você pressionar e liberar o botão de rolagem do mouse, as mensagens padrão WM_MBUTTONUP e WM_MBUTTONDOWN serão enviadas. Se você clicar duas vezes no terceiro botão, a mensagem padrão WM_MBUTTONDBLCLK será enviada.

Há suporte para o botão de rolagem do mouse por meio da mensagem WM_MOUSEWHEEL.

Se você girar o mouse, a mensagem WM_MOUSEWHEEL será enviada para a janela de foco. A função DefWindowProc propaga a mensagem para o pai da janela. Não deve haver nenhum encaminhamento interno da mensagem, pois DefWindowProc a propaga até uma janela que a processe ser encontrada.

Como determinar o número de linhas de rolagem

Os aplicativos devem usar a função SystemParametersInfo para recuperar o número de linhas que um documento rola para cada operação de rolagem (entalhe do botão de rolagem). Para recuperar o número de linhas, um aplicativo faz a seguinte chamada:

SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, pulScrollLines, 0)

A variável "pulScrollLines" aponta para um valor inteiro sem sinal que recebe o número sugerido de linhas para rolagem quando o botão de rolagem do mouse é girado sem teclas modificadoras:

  • Se esse número for 0, nenhuma rolagem deverá ocorrer.
  • Se esse número for WHEEL_PAGESCROLL, uma rolagem do botão de rolagem deverá ser interpretada como um clique duplo nas regiões de página para baixo ou página para cima da barra de rolagem.
  • Se o número de linhas a serem roladas for maior que o número de linhas que podem ser visualizadas, a operação de rolagem também deverá ser interpretada como uma operação de página para baixo ou página para cima.

O valor padrão para o número de linhas de rolagem será 3. Se um usuário alterar o número de linhas de rolagem usando a folha Propriedades do Mouse no Painel de Controle, o sistema operacional transmitirá uma mensagem WM_SETTINGCHANGE para todas as janelas de nível superior com SPI_SETWHEELSCROLLLINES especificado. Quando um aplicativo recebe a mensagem WM_SETTINGCHANGE, ele pode obter o novo número de linhas de rolagem chamando:

SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, pulScrollLines, 0)

Controles com rolagem

A tabela abaixo lista os controles com a funcionalidade de rolagem (incluindo as linhas de rolagem definidas pelo usuário).

Control Rolagem
Controle de edição Vertical e horizontal.
Controle de caixa de listagem Vertical e horizontal.
Caixa de combinação Quando não é descartada, cada rolagem recupera o item seguinte ou anterior. Quando é solta, cada rolagem encaminha a mensagem para a caixa de listagem, que rola a caixa de acordo.
CMD (linha de comando) Vertical.
Modo de exibição de árvore Vertical e horizontal.
Exibição de Lista Vertical e horizontal.
Rolagem para cima/para baixo Um item de cada vez.
Rolagem da barra de controle Um item de cada vez.
Microsoft Rich Edit 1.0 Vertical. Observe que o cliente Exchange tem versões próprias dos controles de exibição de lista e modo de exibição de árvore que não têm suporte para o botão de rolagem.
Microsoft Rich Edit 2.0 Vertical.

 

Como detectar um mouse com um botão de rolagem

Para determinar se um mouse com um botão de rolagem está conectado, chame GetSystemMetrics com SM_MOUSEWHEELPRESENT. Um valor retornado igual a TRUE indica que o mouse está conectado.

O seguinte exemplo é do procedimento de janela para um controle de edição de várias linhas:

BOOL ScrollLines(
     PWNDDATA pwndData,   //scrolls the window indicated
     int cLinesToScroll); //number of times

short gcWheelDelta; //wheel delta from roll
PWNDDATA pWndData; //pointer to structure containing info about the window
UINT gucWheelScrollLines=0;//number of lines to scroll on a wheel rotation

gucWheelScrollLines = SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 
                             0, 
                             pulScrollLines, 
                             0);

case WM_MOUSEWHEEL:
    /*
     * Do not handle zoom and datazoom.
     */
    if (wParam & (MK_SHIFT | MK_CONTROL)) {
        goto PassToDefaultWindowProc;
    }

    gcWheelDelta -= (short) HIWORD(wParam);
    if (abs(gcWheelDelta) >= WHEEL_DELTA && gucWheelScrollLines > 0) 
    {
        int cLineScroll;

        /*
         * Limit a roll of one (1) WHEEL_DELTA to
         * scroll one (1) page.
         */
        cLineScroll = (int) min(
                (UINT) pWndData->ichLinesOnScreen - 1,
                gucWheelScrollLines);

        if (cLineScroll == 0) {
            cLineScroll++;
        }

        cLineScroll *= (gcWheelDelta / WHEEL_DELTA);
        assert(cLineScroll != 0);

        gcWheelDelta = gcWheelDelta % WHEEL_DELTA;
        return ScrollLines(pWndData, cLineScroll);
    }

    break;

Ativação de janela

Quando o usuário clica em uma janela de nível superior inativa ou na janela filho de uma janela de nível superior inativa, o sistema envia a mensagem WM_MOUSEACTIVATE (entre outras) para a janela filho ou de nível superior. O sistema envia essa mensagem depois de postar a mensagem WM_NCHITTEST na janela, mas antes de postar a mensagem de botão pressionado. Quando WM_MOUSEACTIVATE é transmitido para a função DefWindowProc, o sistema ativa a janela de nível superior e, em seguida, posta a mensagem de botão pressionado na janela filho ou de nível superior.

Ao processar WM_MOUSEACTIVATE, uma janela pode controlar se a janela de nível superior se torna a janela ativa como resultado de um clique do mouse e se a janela clicada recebe a mensagem de botão pressionado posterior. Ela faz isso retornando um dos valores a seguir após o processamento de WM_MOUSEACTIVATE.

Valor Significado
MA_ACTIVATE Ativa a janela e não descarta a mensagem do mouse.
MA_NOACTIVATE Não ativa a janela e não descarta a mensagem do mouse.
MA_ACTIVATEANDEAT Ativa a janela e descarta a mensagem do mouse.
MA_NOACTIVATEANDEAT Não ativa a janela, mas descarta a mensagem do mouse.

Confira também

Como aproveitar o movimento do mouse de alta definição