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 tecla. Uma função que intercepta um tipo específico de evento é conhecida como um procedimento de gancho. Um procedimento de gancho pode agir em cada evento recebido e, em seguida, modificar ou descartar o evento.

O exemplo a seguir usa para ganchos:

  • Monitorar mensagens para fins de depuração
  • Fornecer suporte para gravação e reprodução de macros
  • Fornecer suporte para uma chave de ajuda (F1)
  • Simular entrada de mouse e teclado
  • Implementar um aplicativo cbt (treinamento baseado em computador)

Observação

Os ganchos tendem a retardar o 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 ganchos

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 para mensagens do mouse.

O sistema mantém uma cadeia de gancho separada para cada tipo de gancho. Uma 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 tomar depende do tipo de gancho envolvido. Os procedimentos de gancho para alguns tipos de ganchos só podem monitorar mensagens; outras pessoas podem modificar mensagens ou interromper seu progresso pela cadeia, impedindo-as de alcançar o próximo procedimento de gancho ou a janela de destino.

Procedimentos de gancho

Para aproveitar um determinado tipo 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 executada. 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 que é monitorado por um tipo específico de gancho, o sistema chama o procedimento no início da cadeia de gancho associada ao gancho. Cada procedimento de gancho na cadeia determina se o evento deve ser passado 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 alguns tipos de ganchos só podem monitorar mensagens. o sistema passa mensagens para cada procedimento de gancho, independentemente de um procedimento específico 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 de 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 do thread é chamado somente 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 Bibliotecas de Vínculo Dinâmico.

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 para procedimentos de janela. O sistema chama um procedimento de gancho WH_CALLWNDPROC antes de passar a mensagem para o procedimento de janela de recebimento e chama o procedimento de gancho WH_CALLWNDPROCRET depois que o procedimento de janela processa a mensagem.

O gancho WH_CALLWNDPROCRET passa um ponteiro para 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 gancho de WH_CBT destina-se principalmente a aplicativos cbt (treinamento baseado em computador).

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 o sistema deve permitir que o sistema chame procedimentos de gancho associados a outros tipos de ganchos.

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 em primeiro plano está ocioso. O sistema chama um procedimento de gancho WH_FOREGROUNDIDLE quando o thread em 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 WH_GETMESSAGE permite que um aplicativo monitore mensagens prestes a serem retornadas pela função GetMessage ou PeekMessage . Você pode usar o gancho 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 de retorno de chamada GetMsgProc .

WH_JOURNALPLAYBACK

Aviso

As APIs de Ganchos de Registro no Diário não têm suporte a partir de 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 é desabilitada desde que um gancho de WH_JOURNALPLAYBACK esteja instalado. Um gancho de WH_JOURNALPLAYBACK é um gancho global. Ele não pode ser usado como um gancho específico do thread.

O gancho WH_JOURNALPLAYBACK retorna 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 tempo dos eventos reproduzidos.

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

WH_JOURNALRECORD

Aviso

As APIs de Ganchos de Registro no Diário não têm suporte a partir de 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 monitorar e registrar 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 de WH_JOURNALRECORD é um gancho global. Ele não pode ser usado como um gancho específico do thread.

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

WH_KEYBOARD_LL

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

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

WH_KEYBOARD

O gancho de WH_KEYBOARD permite que um aplicativo monitore o tráfego de mensagens para WM_KEYDOWN e WM_KEYUP mensagens prestes a serem retornadas pela função GetMessage ou PeekMessage . Você pode usar o gancho WH_KEYBOARD para monitorar a entrada do teclado postada em uma fila de mensagens.

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

WH_MOUSE_LL

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

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

WH_MOUSE

O gancho de WH_MOUSE permite monitorar mensagens do mouse prestes a serem retornadas pela função GetMessage ou PeekMessage . Você pode usar o gancho WH_MOUSE para monitorar a entrada do mouse postada em uma fila de mensagens.

Para obter mais informações, consulte a função de retorno de chamada 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 do usuário pressionar a combinação de teclas ALT+TAB ou ALT+ESC. O gancho de WH_MSGFILTER só pode monitorar mensagens passadas para um menu, barra de rolagem, caixa de mensagem ou caixa de diálogo criada pelo aplicativo que instalou o procedimento de gancho. O gancho WH_SYSMSGFILTER monitora essas mensagens para 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 main. Por exemplo, um aplicativo geralmente examina uma nova mensagem no loop main entre a hora em que recupera a mensagem da fila e a hora em que envia a mensagem, executando o processamento especial conforme apropriado. No entanto, durante um loop modal, o sistema recupera e envia mensagens sem permitir que um aplicativo filtre as mensagens em seu loop de mensagem main. Se um aplicativo instalar um WH_MSGFILTER ou WH_SYSMSGFILTER procedimento de gancho, o sistema chamará o procedimento durante o loop modal.

Um aplicativo pode chamar o gancho de 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 main. 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 passado para o 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 retorno de chamada 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 MINIMIZEDMETRICS . Defina o membro iArrange dessa estrutura como ARW_HIDE.

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