Sua pergunta despertou meu interesse, então fiz algumas pesquisas e, embora, infelizmente, não tenha uma resposta adequada para você, pensei em compartilhar o que tenho.
Encontrei este exemplo de criação de gancho de teclado (em Delphi) escrito em 1998, mas é compilável em Delphi 2007 com alguns ajustes.
É uma DLL com uma chamada para SetWindowsHookEx
que passa por uma função de retorno de chamada, que pode então interceptar os pressionamentos de tecla: Neste caso, está mexendo nelas para se divertir, mudando o cursor da esquerda para a direita etc. Um aplicativo simples chama a DLL e informa de volta seus resultados com base em um evento TTimer. Se você estiver interessado, posso postar o código baseado em Delphi 2007.
Está bem documentado e comentado e você pode usá-lo como base para descobrir para onde um pressionamento de tecla está indo. Se você pudesse obter o identificador do aplicativo que enviou os pressionamentos de tecla, poderia rastreá-lo dessa forma. Com esse identificador, você poderá obter as informações de que precisa com bastante facilidade.
Outros aplicativos tentaram determinar as teclas de atalho percorrendo seus atalhos, pois podem conter uma tecla de atalho, que é apenas outro termo para tecla de atalho. No entanto, a maioria dos aplicativos não tende a definir essa propriedade, portanto, ela pode não retornar muito. Se você estiver interessado nessa rota, a Delphi tem acesso aIShellLink
interface COM que você pode usar para carregar um atalho e obter sua tecla de atalho:
uses ShlObj, ComObj, ShellAPI, ActiveX, CommCtrl;
procedure GetShellLinkHotKey;
var
LinkFile : WideString;
SL: IShellLink;
PF: IPersistFile;
HotKey : Word;
HotKeyMod: Byte;
HotKeyText : string;
begin
LinkFile := 'C:\Temp\Temp.lnk';
OleCheck(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IShellLink, SL));
// The IShellLink implementer must also support the IPersistFile
// interface. Get an interface pointer to it.
PF := SL as IPersistFile;
// Load file into IPersistFile object
OleCheck(PF.Load(PWideChar(LinkFile), STGM_READ));
// Resolve the link by calling the Resolve interface function.
OleCheck(SL.Resolve(0, SLR_ANY_MATCH or SLR_NO_UI));
// Get hotkey info
OleCheck(SL.GetHotKey(HotKey));
// Extract the HotKey and Modifier properties.
HotKeyText := '';
HotKeyMod := Hi(HotKey);
if (HotKeyMod and HOTKEYF_ALT) = HOTKEYF_ALT then
HotKeyText := 'ALT+';
if (HotKeyMod and HOTKEYF_CONTROL) = HOTKEYF_CONTROL then
HotKeyText := HotKeyText + 'CTRL+';
if (HotKeyMod and HOTKEYF_SHIFT) = HOTKEYF_SHIFT then
HotKeyText := HotKeyText + 'SHIFT+';
if (HotKeyMod and HOTKEYF_EXT) = HOTKEYF_EXT then
HotKeyText := HotKeyText + 'Extended+';
HotKeyText := HotKeyText + Char(Lo(HotKey));
if (HotKeyText = '') or (HotKeyText = #0) then
HotKeyText := 'None';
ShowMessage('Shortcut Key - ' + HotKeyText);
end;
Se você tiver acesso ao Safari Books Online , há uma boa seção sobre como trabalhar com atalhos / links de shell no Borland Delphi 6 Developer's Guide de Steve Teixeira e Xavier Pacheco. Meu exemplo acima é uma versão massacrada de lá e deste site .
Espero que ajude!
WM_HOTKEY
mensagem no registro de mensagens após pressionar a tecla de atalho, pode ser necessário executar a versão de 32 bits do Spy ++ .Depois de alguma pesquisa, parece que você precisa obter acesso à estrutura interna que o MS usa para armazenar as teclas de atalho. O ReactOS tem uma implementação de sala limpa que implementa a
GetHotKey
chamada iterando uma lista interna e extraindo a tecla de atalho que corresponde aos parâmetros da chamada.Dependendo da proximidade da implementação do ReactOS com a implementação do MS, você pode vasculhar a memória para encontrar a estrutura, mas isso está além da minha cabeça ...
Presumo que este tópico sobre sysinternals foi perguntado por alguém relacionado a esta questão, mas pensei em criar um link para ele de qualquer maneira para manter os dois juntos. O tópico parece muito intrigante, mas eu suspeito que algum espelhamento profundo precisaria acontecer para descobrir isso sem acesso aos internos do MS.
fonte
No topo da minha cabeça, você pode tentar enumerar todas as janelas com EnumWindows e, no retorno de chamada, enviar WM_GETHOTKEY para cada janela.
Edit: Aparentemente, eu estava errado sobre isso. MSDN tem mais informações:
Nota: Aqui é um programa que supostamente tem a funcionalidade que você está procurando. Você pode tentar descompilá-lo.
fonte
Isso parece dizer muito a você: http://hkcmdr.anymania.com/help.html
fonte
hoo
usaSetWindowHookEx
para definir dois ganchos, umWH_KEYBOARD_LL
e umWH_GETMESSAGE
... o resto deve ser praticamente documentado no MSDN.Outro tópico menciona um gancho de teclado de nível NT global:
Reatribuir / substituir tecla de atalho (Win + L) para bloquear janelas
talvez você possa obter o controle do processo que chamou o gancho dessa maneira, que pode então resolver para o nome do processo
(isenção de responsabilidade: eu tinha em meus favoritos, realmente não tentei / testei)
fonte
Eu sei que você pode interceptar o fluxo de mensagens em qualquer janela de seu próprio processo - o que costumávamos chamar de subclasse no VB6. (Embora eu não me lembre da função, talvez SetWindowLong?) Não tenho certeza se você pode fazer isso para janelas fora do seu próprio processo. Mas, por causa desta postagem, vamos supor que você encontre uma maneira de fazer isso. Em seguida, você pode simplesmente interceptar as mensagens para todas as janelas de nível superior e monitorar a mensagem WM_HOTKEY. Você não seria capaz de saber todas as teclas logo de cara, mas conforme elas eram pressionadas, você poderia facilmente descobrir qual aplicativo as estava usando. Se você persistir seus resultados no disco e recarregar cada vez que o aplicativo do monitor for executado, poderá aumentar o desempenho do aplicativo ao longo do tempo.
fonte
Isso não responde exatamente à parte da pergunta sobre a API do Windows, mas responde à parte da pergunta sobre uma lista de teclas de atalho globais e os aplicativos que as "possuem".
O Hotkey Explorer gratuito em http://hkcmdr.anymania.com/ mostra uma lista de todas as teclas de atalho globais e os aplicativos que as possuem. Isso apenas me ajudou a descobrir por que uma tecla de atalho específica do aplicativo parou de funcionar e como corrigi-lo (reconfigurando a tecla de atalho global registrada no aplicativo que a tinha registrado), em alguns segundos.
fonte