Visão geral dos ganchos
Um gancho é um mecanismo através do qual um aplicativo pode intercetar eventos, como mensagens, ações do rato e toques de tecla. Uma função que intercepta um tipo específico de evento é conhecida como procedimento de gancho . Um procedimento de gancho pode agir sobre cada evento que recebe e, em seguida, modificar ou descartar o evento.
A seguir são alguns exemplos de usos para ganchos.
- Monitorizar mensagens para fins de depuração
- Fornecer suporte para gravação e reprodução de macros
- Fornecer suporte para a tecla de ajuda (F1)
- Simule a entrada por mouse e teclado
- Implementar um aplicativo de treinamento baseado em computador (CBT)
Observação
Os ganchos tendem a tornar o sistema mais lento porque aumentam a quantidade de processamento que o sistema deve executar para cada mensagem. Você deve instalar um gancho apenas quando necessário e removê-lo o mais rápido possível.
Esta seção discute o seguinte:
Correntes de gancho
O sistema suporta muitos tipos diferentes de ganchos; Cada tipo fornece acesso a um aspeto diferente de seu mecanismo de tratamento de mensagens. Por exemplo, uma aplicação pode utilizar o gancho identificado como WH_MOUSE para monitorar o tráfego de mensagens relacionadas ao mouse.
O sistema mantém uma cadeia separada de ganchos para cada tipo de gancho. Uma cadeia de gancho é 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; Outros podem modificar mensagens ou interromper seu progresso através da cadeia, impedindo-os de chegar ao próximo procedimento de gancho ou à janela de destino.
Procedimentos de Hook
Para tirar proveito de um tipo específico de gancho, o desenvolvedor fornece um procedimento de gancho e usa a função SetWindowsHookEx para instalar o gancho na cadeia associada. 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 pela aplicação.
O parâmetro nCode é um código de gancho utilizado pelo procedimento para determinar a ação a executar. O valor do código do gancho depende do tipo do gancho; Cada tipo tem seu próprio conjunto característico de códigos de gancho. Os valores dos parâmetros wParam e lParam dependem do código de gancho, mas geralmente 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 gancho. Quando ocorre um evento 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 monitoriza mensagens para todos os threads na mesma área de trabalho que o thread que faz a chamada. Um gancho específico de tópico monitora mensagens apenas para um tópico individual. Um procedimento de gancho global pode ser chamado no contexto de qualquer aplicação na mesma área de trabalho que o thread de chamada, portanto, o procedimento deve estar num módulo DLL separado. Um procedimento de gancho específico de thread é chamado somente no contexto do thread associado. Se uma aplicação instalar um procedimento de gancho para um dos seus próprios threads, o procedimento de gancho pode estar no mesmo módulo que o restante do código da aplicação ou em uma DLL. Se o aplicativo instala um procedimento de gancho para um thread de um aplicativo diferente, o procedimento deve 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 aspeto diferente do mecanismo de manipulação de mensagens do sistema. As seções a seguir descrevem os ganchos disponíveis.
- WH_CALLWNDPROC e WH_CALLWNDPROCRET
- WH_CBT
- WH_DEBUG
- WH_FOREGROUNDIDLE
- WH_GETMESSAGE
- WH_JOURNALPLAYBACK
- WH_JOURNALRECORD
- WH_KEYBOARD_LL
- WH_KEYBOARD
- WH_MOUSE_LL
- WH_MOUSE
- WH_MSGFILTER e WH_SYSMSGFILTER
- WH_SHELL
WH_CALLWNDPROC e WH_CALLWNDPROCRET
Os ganchos WH_CALLWNDPROC e WH_CALLWNDPROCRET permitem-lhe monitorizar mensagens enviadas para procedimentos de janela. O sistema chama o procedimento de gancho WH_CALLWNDPROC antes de passar a mensagem para o procedimento da janela de receção e chama o procedimento de gancho WH_CALLWNDPROCRET depois que o procedimento de janela processou a mensagem.
O gancho WH_CALLWNDPROCRET passa um ponteiro para uma estrutura CWPRETSTRUCT para o procedimento de gancho. A estrutura contém o valor de retorno do procedimento de janela que processou a mensagem, bem como os parâmetros de mensagem associados à mensagem. A subclassificação 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 completar 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 que o procedimento de gancho retorna determina se o sistema permite ou impede uma dessas operações. O gancho WH_CBT destina-se principalmente a aplicações de treinamento baseado em computador (CBT).
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 este gancho para decidir se deve permitir ao sistema executar procedimentos 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 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 WH_GETMESSAGE permite que uma aplicação monitorize mensagens que estão prestes a ser retornadas pelas funções GetMessage ou PeekMessage. Você pode usar o gancho de WH_GETMESSAGE para monitorar a entrada de mouse e teclado e outras mensagens postadas na fila de mensagens.
Para mais informações, consulte a função de retorno de chamada GetMsgProc .
WH_JOURNALPLAYBACK
Advertência
As APIs de ganchos de registro no diário não são suportadas a partir do Windows 11 e serão removidas em uma versão futura. Por isso, é altamente recomendável chamar a SendInput TextInput API.
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 normal de rato e teclado é desativada enquanto um gancho de WH_JOURNALPLAYBACK esteja instalado. Um gancho de WH_JOURNALPLAYBACK é um gancho global — não pode ser usado como um gancho específico de 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 que reproduz.
Para mais informações, consulte a função de retorno de chamada JournalPlaybackProc.
WH_JOURNALRECORD
Advertência
As APIs de journaling hooks não são suportadas a partir do Windows 11 e serão removidas numa versão futura. Por isso, é altamente recomendável chamar o SendInput TextInput API.
O gancho WH_JOURNALRECORD permite monitorizar e registar 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 é um gancho 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 monitorizar eventos de entrada do teclado que estão prestes a ser colocados numa fila de entrada de thread.
Para obter mais informações, consulte o LowLevelKeyboardProc função de retorno de chamada.
WH_KEYBOARD
O gancho WH_KEYBOARD permite que um aplicativo monitore o tráfego de mensagens para as mensagens WM_KEYDOWN e WM_KEYUP que estão prestes a ser retornadas pela função GetMessage ou pela função PeekMessage. Você pode usar o gancho de 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 monitorizar eventos de entrada do rato prestes a serem postados numa fila de entrada de thread.
Para obter mais informações, consulte a função de retorno de chamada LowLevelMouseProc.
WH_MOUSE
O gancho WH_MOUSE permite monitorizar mensagens do rato prestes a serem retornadas pelas funções GetMessage ou PeekMessage. Você pode usar o gancho de WH_MOUSE para monitorar a entrada do mouse postada em uma fila de mensagens.
Para 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 detetar 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 de WH_MSGFILTER só pode monitorizar mensagens passadas para um menu, barra de deslocamento, caixa de mensagem ou caixa de diálogo criada pela aplicação 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 executar filtro de mensagens durante loops modais, sendo equivalente ao filtro feito no ciclo de mensagens principal. Por exemplo, um aplicativo geralmente examina uma nova mensagem no loop principal entre o momento em que recupera a mensagem da fila e o momento em que envia a mensagem, executando processamento especial conforme apropriado. No entanto, durante um loop modal, o sistema recupera e despacha mensagens sem permitir que um aplicativo tenha a chance de filtrar as mensagens em seu loop de mensagens principal. Se um aplicativo instala um WH_MSGFILTER ou WH_SYSMSGFILTER procedimento de gancho, o sistema chama o procedimento durante o loop modal.
Um aplicativo pode chamar diretamente o gancho WH_MSGFILTER ao chamar a função CallMsgFilter. Usando essa função, o aplicativo pode usar o mesmo código para filtrar mensagens durante loops modais como usa no loop de mensagem principal. Para fazer isso, encapsular as operações de filtragem num procedimento de gancho WH_MSGFILTER e chamar 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 hook; pode introduzir 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
Uma aplicação de shell pode usar o gancho 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 ele (ou qualquer outro aplicativo) possa receber mensagens WH_SHELL. Esta função deve ser chamada com SPI_SETMINIMIZEDMETRICS e uma estrutura MINIMIZEDMETRICS. Defina o iArrange membro desta estrutura como ARW_HIDE.
Para obter mais informações, consulte a função de retorno de chamada ShellProc.