了解什么进程注册了全球热键? (Windows API) [英] Find out what process registered a global hotkey? (Windows API)

查看:214
本文介绍了了解什么进程注册了全球热键? (Windows API)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,Windows不提供API函数来告诉应用程序已注册了全局热键(通过RegisterHotkey)。我只能发现一个热键是注册的,如果RegisterHotkey返回false,而不是拥有热键。



在没有直接API的情况下,一个迂回的路? Windows维护与每个注册的热键相关联的句柄 - 这是一个有点令人生ening的,应该没有办法得到这个信息。



可能不会工作的例子:发送(模拟)注册热键,然后拦截Windows将发送到注册过程的热键消息。首先,我不认为拦截消息会显示目的地窗口句柄。第二,即使有可能,这将是一件坏事,因为发送热键会触发各种程序的各种潜在的不必要的活动。



没有什么重要的,但是我经常看到这样的功能的请求,并且自己是注册热键的应用程序的受害者,甚至没有在UI中的任何地方公开它文件。



(在Delphi中工作,只有WinAPI上的学徒,请多加一点。)

解决方案

你的问题引起了我的兴趣,所以我做了一些挖掘,而不幸的是,我没有一个适当的答案,我以为我会分享我所拥有的。 / p>

我发现这个创建1998年写的键盘钩子(在Delphi中)的例子,但是可以在Delphi 2007中进行一些调整。



它是一个调用$ code> SetWindowsHookEx 的DLL,通过一个回调函数,然后可以截取关键笔划:在这种情况下,它正在改进他们的乐趣,将左光标向右更改等。一个简单的应用程序然后调用DLL,并根据TTimer事件报告其结果。如果你有兴趣,我可以发布基于Delphi 2007的代码。



它有很好的记录和评论,你可以使用它作为一个基础,正在进行如果您可以获得发送关键笔划的应用程序的句柄,那么可以这样回溯。使用该句柄,您可以轻松获取所需的信息。



其他应用程序尝试通过快捷方式确定热键,因为它们可以包含快捷键,这只是热键的另一个术语。然而,大多数应用程序不倾向于设置此属性,因此它可能不会返回太多。如果您对该路由感兴趣,则Delphi可以访问 IShellLink COM接口,您可以使用它来加载快捷方式并获取其热键:

 使用ShlObj,ComObj,ShellAPI,ActiveX,CommCtrl; 

程序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));

// IShellLink实现者还必须支持IPersistFile
//接口。获取一个接口指针。
PF:= SL as IPersistFile;

//将文件加载到IPersistFile对象
OleCheck(PF.Load(PWideChar(LinkFile),STGM_READ));

//通过调用Resolve接口函数来解析链接。
OleCheck(SL.Resolve(0,SLR_ANY_MATCH或SLR_NO_UI));

//获取热键信息
OleCheck(SL.GetHotKey(HotKey));

//提取HotKey和Modifier属性。
HotKeyText:='';
HotKeyMod:=嗨(HotKey);

if(HotKeyMod和HOTKEYF_ALT)= HOTKEYF_ALT then
HotKeyText:='ALT +';
如果(HotKeyMod和HOTKEYF_CONTROL)= HOTKEYF_CONTROL然后
HotKeyText:= HotKeyText +'CTRL +';
if(HotKeyMod and HOTKEYF_SHIFT)= HOTKEYF_SHIFT then
HotKeyText:= HotKeyText +'SHIFT +';
if(HotKeyMod和HOTKEYF_EXT)= HOTKEYF_EXT then
HotKeyText:= HotKeyText +'Extended +';

HotKeyText:= HotKeyText + Char(Lo(HotKey));

if(HotKeyText ='')或(HotKeyText =#0)then
HotKeyText:='None';

ShowMessage('快捷键 - '+ HotKeyText);
结束

如果您有权访问 Safari Books Online ,有一个使用快捷方式的好的部分/ Shell链接,由Steve Teixeira和Xavier Pacheco撰写的Borland Delphi 6开发人员指南。我上面的例子是从那里开始的一个非法的版本,这个网站



希望有帮助!


As far as I've been able to find out, Windows doesn't offer an API function to tell what application has registered a global hotkey (via RegisterHotkey). I can only find out that a hotkey is registered if RegisterHotkey returns false, but not who "owns" the hotkey.

In the absence of a direct API, could there be a roundabout way? Windows maintains the handle associated with each registred hotkey - it's a little maddening that there should be no way of getting at this information.

Example of something that likely wouldn't work: send (simulate) a registered hotkey, then intercept the hotkey message Windows will send to the process that registered it. First, I don't think intercepting the message would reveal the destination window handle. Second, even if it were possible, it would be a bad thing to do, since sending hotkeys would trigger all sorts of potentially unwanted activity from various programs.

It's nothing critical, but I've seen frequent requests for such functionality, and have myself been a victim of applications that register hotkeys without even disclosing it anywhere in the UI or docs.

(Working in Delphi, and no more than an apprentice at WinAPI, please be kind.)

解决方案

Your question piqued my interest, so I've done a bit of digging and while, unfortunately I don't have a proper answer for you, I thought I'd share what I have.

I found this example of creating keyboard hook (in Delphi) written in 1998, but is compilable in Delphi 2007 with a couple of tweaks.

It's a DLL with a call to SetWindowsHookEx that passes through a callback function, which can then intercept key strokes: In this case, it's tinkering with them for fun, changing left cursor to right, etc. A simple app then calls the DLL and reports back its results based on a TTimer event. If you're interested I can post the Delphi 2007 based code.

It's well documented and commented and you potentially could use it as a basis of working out where a key press is going. If you could get the handle of the application that sent the key strokes, you could track it back that way. With that handle you'd be able to get the information you need quite easily.

Other apps have tried determining hotkeys by going through their Shortcuts since they can contain a Shortcut key, which is just another term for hotkey. However most applications don't tend to set this property so it might not return much. If you are interested in that route, Delphi has access to IShellLink COM interface which you could use to load a shortcut up from and get its hotkey:

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;

If you've got access to Safari Books Online, there is a good section about working with shortcuts / shell links in the Borland Delphi 6 Developer's Guide by Steve Teixeira and Xavier Pacheco. My example above is a butchered version from there and this site.

Hope that helps!

这篇关于了解什么进程注册了全球热键? (Windows API)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆