Mar*_*ski 105 delphi api winapi hotkeys registerhotkey
据我所知,Windows没有提供API函数来告诉应用程序注册了一个全局热键(通过RegisterHotkey).我只能发现如果RegisterHotkey返回false,则注册了热键,但不是"拥有"热键的人.
在没有直接API的情况下,是否会有迂回的方式?Windows维护与每个注册热键相关联的句柄 - 这有点令人抓狂,因此无法获取此信息.
可能不起作用的示例:发送(模拟)已注册的热键,然后拦截Windows将发送给注册它的进程的热键消息.首先,我不认为拦截消息会显示目标窗口句柄.其次,即使有可能,这也是一件坏事,因为发送热键会触发各种程序中各种可能不需要的活动.
这并不重要,但我已经看到了对这种功能的频繁请求,并且我自己也是注册热键的应用程序的受害者,甚至没有在UI或文档中的任何地方公开它.
(在Delphi工作,只不过是WinAPI的学徒,请善待.)
小智 40
一种可能的方法是使用Visual Studio工具Spy ++.
尝试一下:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\spyxx_amd64.exe)WM_HOTKEY在列表框中,或检查键盘的消息组(如果你有更多潜在的噪声OK)WM_HOTKEY在" 消息(所有Windows)"窗口中选择该行,右键单击,然后在上下文菜单中选择" 属性... "EXPLORER)Pau*_*auk 19
你的问题引起了我的兴趣,所以我做了一些挖掘,但不幸的是,我没有给你一个正确的答案,我想我会分享我所拥有的.
我在1998年创建了这个创建键盘钩子(在Delphi中)的例子,但在Delphi 2007中可以通过几个调整进行编译.
它是一个带有调用的DLL,它SetWindowsHookEx通过一个回调函数,然后可以拦截键击:在这种情况下,它为了好玩而修改它们,将左光标向右移动等等.一个简单的应用程序然后调用DLL并报告回来其结果基于TTimer事件.如果您有兴趣,我可以发布基于Delphi 2007的代码.
它有很好的文档和评论,你可能会用它作为按键按键的基础.如果您可以获得发送键击的应用程序的句柄,您可以通过这种方式跟踪它.有了这个句柄,您就可以轻松获得所需的信息.
其他应用程序尝试通过快捷方式确定热键,因为它们可以包含快捷键,这只是热键的另一个术语.但是,大多数应用程序不倾向于设置此属性,因此它可能不会返回太多.如果您对该路线感兴趣,Delphi可以访问IShellLinkCOM接口,您可以使用该接口加载快捷方式并获取其热键:
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;
Run Code Online (Sandbox Code Playgroud)
如果您可以访问Safari Books Online,那么Steve Teixeira和Xavier Pacheco在Borland Delphi 6开发人员指南中有一个关于使用快捷方式/ shell链接的好部分.我上面的例子是来自那里和这个网站的屠宰版本.
希望有所帮助!
经过一些研究,您似乎需要访问MS用于存储热键的内部结构.ReactOS有一个干净的房间实现,GetHotKey通过迭代内部列表并提取与调用参数匹配的热键来实现调用.
根据ReactOS实现与MS实现的接近程度,您可能能够在内存中找到结构,但这是我的头脑......
BOOL FASTCALL
GetHotKey (UINT fsModifiers,
UINT vk,
struct _ETHREAD **Thread,
HWND *hWnd,
int *id)
{
PHOT_KEY_ITEM HotKeyItem;
LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
{
if (HotKeyItem->fsModifiers == fsModifiers &&
HotKeyItem->vk == vk)
{
if (Thread != NULL)
*Thread = HotKeyItem->Thread;
if (hWnd != NULL)
*hWnd = HotKeyItem->hWnd;
if (id != NULL)
*id = HotKeyItem->id;
return TRUE;
}
}
return FALSE;
}
Run Code Online (Sandbox Code Playgroud)
我认为sysinternals上的这个帖子是由与这个问题相关的人问的,但是我想我还是会链接到它以保持两者在一起.该线程看起来非常有趣,但我怀疑在没有访问MS内部的情况下,需要进行一些深潜探测.
| 归档时间: |
|
| 查看次数: |
25042 次 |
| 最近记录: |