找出哪个进程注册了全局热键?(Windows API) [英] Find out what process registered a global hotkey? (Windows API)

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

问题描述

据我所知,Windows 没有提供 API 函数来告诉哪个应用程序注册了全局热键(通过 RegisterHotkey).如果 RegisterHotkey 返回 false,我只能发现热键已注册,但不能确定谁拥有"热键.

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.

在没有直接API的情况下,是否有迂回的方式?Windows 维护与每个注册热键相关联的句柄 - 没有办法获取这些信息,这有点令人抓狂.

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.

一些可能不起作用的例子:发送(模拟)一个注册的热键,然后拦截 Windows 将发送给注册它的进程的热键消息.首先,我认为拦截消息不会显示目标窗口句柄.其次,即使有可能,这也是一件坏事,因为发送热键会触发各种程序的各种潜在有害活动.

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.

这并不重要,但我经常看到对此类功能的请求,并且我自己也曾成为注册热键而没有在 UI 或文档中的任何地方公开的应用程序的受害者.

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.

(在 Delphi 工作,不过是 WinAPI 的学徒,请善待.)

(Working in Delp 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.

我发现了这个 创建键盘钩子的例子(在 Delphi 中) 写于 1998 年,但经过一些调整后可在 Delphi 2007 中编译.

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

这是一个调用 SetWindowsHookEx 的 DLL,它通过一个回调函数,然后可以拦截击键:在这种情况下,它正在修补它们以获得乐趣,将左光标更改为右等. 然后,一个简单的应用程序调用 DLL 并根据 TTimer 事件报告其结果.如果您有兴趣,我可以发布基于 Delphi 2007 的代码.

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.

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

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;

如果您可以访问 Safari 在线图书,则有一个 Borland Delphi 6 Developer's Guide 中关于使用快捷方式/shell 链接的好部分 Steve Teixeira 和 Xavier Pacheco.我上面的例子是从那里和这个网站中删除的版本.

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.

希望有帮助!

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

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