Compartilhar via


Visão geral dos ganchos

Um gancho é um mecanismo pelo qual um aplicativo pode interceptar eventos, como mensagens, ações do mouse e pressionamentos de teclas. Uma função que intercepta um tipo específico de evento é conhecida como um procedimento de gancho. Um procedimento de gancho pode atuar sobre cada evento que ele recebe e, em seguida, modificá-lo ou descartá-lo.

Alguns usos para ganchos incluem:

  • Monitorando mensagens para fins de depuração
  • Fornecendo suporte para gravação e reprodução de macros
  • Fornecendo suporte para a tecla de ajuda (F1)
  • Simulando a entrada do mouse e do teclado
  • Implementando um aplicativo CBT (treinamento baseado em computador)

Observação

Os ganchos tendem a diminuir a velocidade do sistema porque aumentam a quantidade de processamento que o sistema deve executar para cada mensagem. Você deve instalar um gancho somente quando necessário e removê-lo assim que possível.

Esta seção discute o seguinte:

Cadeias de gancho

O sistema dá suporte a muitos tipos diferentes de ganchos; cada tipo fornece acesso a um aspecto diferente de seu mecanismo de tratamento de mensagens. Por exemplo, um aplicativo pode usar o gancho WH_MOUSE para monitorar o tráfego de mensagens do mouse.

O sistema mantém uma cadeia de gancho separada para cada tipo de gancho. Cadeia de ganchos é uma lista de ponteiros para funções especiais de retorno de chamada definidas pelo aplicativo chamadas procedimentos de gancho. Quando ocorre uma mensagem associada a um tipo específico de gancho, o sistema passa a mensagem para cada procedimento de gancho referenciado na cadeia de gancho, um após o outro. A ação que um procedimento de gancho pode realizar depende do tipo de gancho envolvido. Os procedimentos de gancho para alguns tipos de gancho podem apenas monitorar mensagens; outros tipos podem modificar mensagens ou interromper seu andamento ao longo da cadeia, impedindo que alcancem o próximo procedimento de gancho ou a janela de destino.

Procedimentos de gancho

Para aproveitar um tipo específico de gancho, o desenvolvedor fornece um procedimento de gancho e usa a função SetWindowsHookEx para instalá-lo na cadeia associada ao gancho. Um procedimento de gancho deve ter a seguinte sintaxe:

LRESULT CALLBACK HookProc(
  int nCode, 
  WPARAM wParam, 
  LPARAM lParam
)
{
   // process event
   ...

   return CallNextHookEx(NULL, nCode, wParam, lParam);
}

HookProc é um espaço reservado para um nome definido pelo aplicativo.

O parâmetro nCode é um código de gancho que o procedimento de gancho usa para determinar a ação a ser realizada. O valor do código de gancho depende do tipo do gancho; cada tipo tem seu próprio conjunto de características de códigos de gancho. Os valores dos parâmetros wParam e lParam dependem do código de gancho, mas normalmente contêm informações sobre uma mensagem que foi enviada ou postada.

A função SetWindowsHookEx sempre instala um procedimento de gancho no início de uma cadeia de ganchos. Quando ocorre um evento monitorado por um tipo específico de gancho, o sistema chama o procedimento no início da cadeia de ganchos associada ao gancho. Cada procedimento de gancho na cadeia determina se o evento deve ser transmitido para o próximo procedimento. Um procedimento de gancho passa um evento para o próximo procedimento chamando a função CallNextHookEx.

Observe que os procedimentos de gancho para determinados tipos de gancho só podem monitorar mensagens. O sistema transmite mensagens para cada procedimento de gancho, independentemente se um determinado procedimento chamar CallNextHookEx.

Um gancho global monitora mensagens para todos os threads na mesma área de trabalho que o thread de chamada. Um gancho específico do thread monitora mensagens para apenas um thread individual. Um procedimento de gancho global pode ser chamado no contexto de qualquer aplicativo na mesma área de trabalho que o thread de chamada, portanto, o procedimento deve estar em um módulo DLL separado. Um procedimento de gancho específico de thread é chamado apenas no contexto do thread associado. Se um aplicativo instalar um procedimento de gancho para um de seus próprios threads, o procedimento de gancho poderá estar no mesmo módulo que o restante do código do aplicativo ou em uma DLL. Se o aplicativo instalar um procedimento de gancho para um thread de um aplicativo diferente, o procedimento deverá estar em uma DLL. Para obter informações, consulte Dynamic-Link Bibliotecas.

Observação

Você deve usar ganchos globais apenas para fins de depuração; caso contrário, você deve evitá-los. Os ganchos globais prejudicam o desempenho do sistema e causam conflitos com outros aplicativos que implementam o mesmo tipo de gancho global.

Tipos de gancho

Cada tipo de gancho permite que um aplicativo monitore um aspecto diferente do mecanismo de tratamento de mensagens do sistema. As seções a seguir descrevem os ganchos disponíveis.

WH_CALLWNDPROC e WH_CALLWNDPROCRET

Os ganchos WH_CALLWNDPROC e WH_CALLWNDPROCRET permitem monitorar mensagens enviadas aos procedimentos de janela. O sistema chama um procedimento de gancho WH_CALLWNDPROC antes de transmitir a mensagem ao procedimento da janela de recebimento e chama o procedimento de gancho de WH_CALLWNDPROCRET depois que o procedimento de janela processa a mensagem.

O gancho WH_CALLWNDPROCRET transmite um ponteiro a uma estrutura CWPRETSTRUCT para o procedimento de gancho. A estrutura contém o valor retornado do procedimento de janela que processou a mensagem, bem como os parâmetros de mensagem associados à mensagem. A subclasse da janela não funciona para mensagens definidas entre processos.

Para obter mais informações, consulte as funções de retorno de chamada CallWndProc e CallWndRetProc .

WH_CBT

O sistema chama um procedimento de gancho WH_CBT antes de ativar, criar, destruir, minimizar, maximizar, mover ou dimensionar uma janela; antes de concluir um comando do sistema; antes de remover um evento de mouse ou teclado da fila de mensagens do sistema; antes de definir o foco de entrada ou antes de sincronizar com a fila de mensagens do sistema. O valor retornado pelo procedimento de gancho determina se o sistema permite ou impede uma dessas operações. O hook WH_CBT é destinado principalmente para aplicativos de treinamento baseado em computador (TBC).

Para obter mais informações, consulte a função de retorno de chamada CBTProc.

Para obter informações, consulte WinEvents.

WH_DEBUG

O sistema chama um procedimento de gancho WH_DEBUG antes de chamar procedimentos de gancho associados a qualquer outro gancho no sistema. Você pode usar esse gancho para determinar se deve permitir que o sistema chame procedimentos de gancho associados a outros tipos de gancho.

Para obter mais informações, consulte a função de retorno de chamada DebugProc.

WH_FOREGROUNDIDLE

O gancho de WH_FOREGROUNDIDLE permite que você execute tarefas de baixa prioridade durante os momentos em que seu thread de primeiro plano está ocioso. O sistema chama um procedimento de gancho WH_FOREGROUNDIDLE quando o thread de primeiro plano do aplicativo está prestes a ficar ocioso.

Para obter mais informações, consulte a função de retorno de chamada ForegroundIdleProc.

WH_GETMESSAGE

O gancho de WH_GETMESSAGE permite que um aplicativo monitore mensagens prestes a serem retornadas pela função GetMessage ou PeekMessage . Você pode usar o hook WH_GETMESSAGE para monitorar a entrada do mouse e do teclado e outras mensagens postadas na fila de mensagens.

Para obter mais informações, consulte a função callback GetMsgProc.

WH_JOURNALPLAYBACK

Aviso

As APIs do Journaling Hooks não têm suporte a partir do Windows 11 e serão removidas em uma versão futura. Por isso, é altamente recomendável chamar a API SendInput TextInput.

O gancho de WH_JOURNALPLAYBACK permite que um aplicativo insira mensagens na fila de mensagens do sistema. Você pode usar esse gancho para reproduzir uma série de eventos de mouse e teclado gravados anteriormente usando WH_JOURNALRECORD. A entrada regular do mouse e do teclado permanece desabilitada enquanto um gancho WH_JOURNALPLAYBACK está instalado. Um gancho WH_JOURNALPLAYBACK é global; não pode ser usado como um gancho específico de thread.

O gancho WH_JOURNALPLAYBACK exibe um valor de tempo limite. Esse valor informa ao sistema quantos milissegundos esperar antes de processar a mensagem atual do gancho de reprodução. Isso permite que o gancho controle o momento dos eventos que ele reproduz.

Para obter mais informações, consulte a função de retorno de chamada JournalPlaybackProc.

WH_JOURNALRECORD

Aviso

As APIs do Journaling Hooks não têm suporte a partir do Windows 11 e serão removidas em uma versão futura. Por isso, é altamente recomendável chamar a API SendInput TextInput.

O gancho de WH_JOURNALRECORD permite que você monitore e registre eventos de entrada. Normalmente, você usa esse gancho para gravar uma sequência de eventos de mouse e teclado para reproduzir mais tarde usando WH_JOURNALPLAYBACK. O gancho WH_JOURNALRECORD é global; não pode ser usado como um gancho específico de thread.

Para obter mais informações, consulte a função de retorno de chamada JournalRecordProc.

WH_KEYBOARD_LL

O gancho WH_KEYBOARD_LL permite monitorar eventos de entrada de teclado prestes a serem publicados em uma fila de entrada de um thread.

Para obter mais informações, consulte a função de retorno de chamada LowLevelKeyboardProc.

WH_KEYBOARD

O WH_KEYBOARD hook permite que um aplicativo monitore o tráfego de mensagens para mensagens WM_KEYDOWN e WM_KEYUP que estão prestes a ser retornadas pela função GetMessage ou PeekMessage. É possível usar o gancho WH_KEYBOARD para monitorar a entrada do teclado publicada em uma fila de mensagens.

Para obter mais informações, consulte a função de retorno de chamada KeyboardProc.

WH_MOUSE_LL

O gancho WH_MOUSE_LL permite monitorar eventos de entrada de mouse prestes a serem publicados em uma fila de entrada de um thread.

Para obter mais informações, consulte a função callback LowLevelMouseProc.

WH_MOUSE

O gancho de WH_MOUSE permite monitorar mensagens do mouse prestes a serem retornadas pela função GetMessage ou PeekMessage . É possível usar o gancho WH_MOUSE para monitorar a entrada do mouse publicada em uma fila de mensagens.

Para obter mais informações, consulte a função de callback MouseProc.

WH_MSGFILTER e WH_SYSMSGFILTER

Os ganchos WH_MSGFILTER e WH_SYSMSGFILTER permitem monitorar mensagens prestes a serem processadas por um menu, barra de rolagem, caixa de mensagem ou caixa de diálogo e detectar quando uma janela diferente está prestes a ser ativada como resultado de o usuário pressionar a combinação de teclas ALT+TAB ou ALT+ESC. O gancho WH_MSGFILTER só pode monitorar mensagens passadas para um menu, uma barra de rolagem, uma caixa de mensagem ou uma caixa de diálogo criada pelo aplicativo que instalou o gancho. O gancho WH_SYSMSGFILTER monitora essas mensagens em todos os aplicativos.

Os ganchos WH_MSGFILTER e WH_SYSMSGFILTER permitem que você execute a filtragem de mensagens durante loops modais equivalentes à filtragem feita no loop de mensagem principal. Por exemplo, um aplicativo geralmente examina uma nova mensagem no loop principal entre a hora em que recupera a mensagem da fila e a hora em que ela expedi a mensagem, executando o processamento especial conforme apropriado. No entanto, durante um loop modal, o sistema recupera e expedi mensagens sem permitir a um aplicativo a chance de filtrar as mensagens em seu loop de mensagem principal. Se um aplicativo instalar um procedimento de gancho WH_MSGFILTER ou WH_SYSMSGFILTER, o sistema chamará o procedimento durante o loop modal.

Um aplicativo pode chamar o hook WH_MSGFILTER diretamente chamando a função CallMsgFilter. Usando essa função, o aplicativo pode usar o mesmo código para filtrar mensagens durante loops modais que usa no loop de mensagem principal. Para fazer isso, encapsule as operações de filtragem em um procedimento de gancho WH_MSGFILTER e chame CallMsgFilter entre as chamadas para as funções GetMessage e DispatchMessage.

while (GetMessage(&msg, (HWND) NULL, 0, 0)) 
{ 
    if (!CallMsgFilter(&qmsg, 0)) 
        DispatchMessage(&qmsg); 
} 

O último argumento de CallMsgFilter é simplesmente transmitido ao procedimento de gancho; você pode inserir qualquer valor. O procedimento de gancho, definindo uma constante como MSGF_MAINLOOP, pode usar esse valor para determinar de onde o procedimento foi chamado.

Para obter mais informações, consulte as funções de callback MessageProc e SysMsgProc.

WH_SHELL

Um aplicativo shell pode usar o gancho de WH_SHELL para receber notificações importantes. O sistema chama um procedimento de gancho WH_SHELL quando o aplicativo shell está prestes a ser ativado e quando uma janela de nível superior é criada ou destruída.

Observe que os aplicativos de shell personalizados não recebem mensagens WH_SHELL . Portanto, qualquer aplicativo que se registre como o shell padrão deve chamar a função SystemParametersInfo antes que ela (ou qualquer outro aplicativo) possa receber mensagens WH_SHELL . Essa função deve ser chamada com SPI_SETMINIMIZEDMETRICS e uma estrutura MINIMIZEEDMETRICS . Defina o membro iArrange dessa estrutura como ARW_HIDE.

Para obter mais informações, consulte a função de retorno de chamada ShellProc.