在不受控制的 window 的菜单栏中 block/remove 键盘钩子有什么方法吗?

Any way to block/remove keyboard hook in uncontrolled window's Menubar?

我正在使用 PostMessage 将击键发送到不活动的 Adob​​e Flash 投影仪 window,这部分工作正常。我将它 运行 留在后台,它对我的​​正常计算机使用影响很小,这就是我的意图。当我以编程方式发送 W(或不太频繁的 Q)键时,问题就来了,而我恰好持有 Ctrl 用于不同的 windows 快捷方式。这会触发 Ctrl-QCtrl-W,两者都会立即关闭 Adob​​e Flash Projector。 Ctrl-FCtrl-O 也有一些不良影响。

编辑:我对短暂释放 Ctrl 键的解决方案不感兴趣。

有没有办法从第三方解除快捷键window?它在列出快捷方式的 window 顶部使用标准 OS 菜单栏,所以肯定有办法重新分配、取消分配或阻止它,对吗?

过去我曾尝试使用这些 dll 来破坏菜单。它使它消失但没有打破捷径。

DllCall("SetMenu", uint, this.id, uint, 0)
hMenu := DllCall("GetSystemMenu", "UInt",this.id, "UInt",1)
DllCall("DestroyMenu", "Uint",hMenu)

抱歉出现了奇怪的语法,这是我用 autohotkey 编写的程序的早期版本。

我现在使用的语言是 C#,但我假设解决方案使用的是 .dll,所以这并不重要。欢迎提出建议或更改我的标签。

  1. 您可以尝试使目标应用程序(Window 包含菜单)。

  2. 您可以尝试找到应用程序使用了哪些函数,并使用 VirtualProtect 和注入汇编程序在应用程序的本地副本中重写它们(如果您不了解内存虚拟化是危险的) .使用 GetKeyStateGetAsyncKeyState 检查应用程序(在文本编辑器中打开应用程序后可见)。

  3. 你可以试试: HMENU hMenu=GetMenu(applicationMainWindow); SetMenu(applicationMainWindow,0); // here send your input with SendMessageW instead of PostMessageW SetMenu(applicationMainWindow,hMenu);

每个程序都可以使用各种方法来处理用户键盘输入。在这种情况下,如果您没有发送它并且检测到 Ctrl,则可能使用 GetAsyncKeyState 或 GetKeyState(用于 Ctrl)。

如果它不能帮助您,请在您的问题中添加带有 PostMessage 的代码。

顺便说一句。您可以清除适当的 window 样式,而不是破坏 GetSystemMenu,并在发送输入后恢复它(如果问题是系统菜单 - 概率接近 1%)。

使用程序 Resource Tuner 的免费试用版,我打开 flashplayer_28_sa.exe,转到加速器 Table(显然加速器在菜单上下文中表示快捷方式),并删除了令人讨厌的捷径。然后我保存了,保存失败了,我保存了一遍又一遍,然后又成功了,虽然我当时没有做任何不同的事情。

我认为它可以与具有标准 windows 菜单的程序的其他快捷方式一起使用。

虽然我最终没有使用这种方法,(因为更改菜单对于阻止那些菜单项的快捷方式无效),但我发现了各种有趣的方法来修改第三方 window 的菜单。我会留下一些我在这里找到的东西,因为虽然它与我的问题有关,但它并不能解决我的问题。评论基于我对他们所做事情的错误理解。

各种外部:

[DllImport("user32.dll")]
//get hMenu of the window's menu
static extern IntPtr GetMenu(IntPtr hWnd);
[DllImport("user32.dll")]
//Attach hMenu to a window. if hMenu is 0, attach no menu (remove menu)
static extern bool SetMenu(IntPtr hWnd, IntPtr hMenu);
[DllImport("user32.dll")]
//Destroy hMenu
private static extern bool DestroyMenu(IntPtr hMenu);
[DllImport("user32.dll")]
//Destroy Destroy submenu at position within menu
private static extern bool DeleteMenu(IntPtr hMenu, uint uPosition, uint uFlags);
[DllImport("user32.dll")]
//Like GetMenu, but gets the restore/move/size/minimize/etc menu that you get when clicking on the little icon in the top left of a window (not the window's menu
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll")]
//Adds a menu to a menu
private static extern bool AppendMenu(IntPtr hMenu, int uFlags, int uIDNewItem, string lpNewItem);
[DllImport("user32.dll")]
//Removes a menu from a menu
private static extern bool RemoveMenu(IntPtr hMenu, uint uPosition, int uFlags);
[DllImport("user32.dll")]
//Like AppendMenu, but specifies position
private static extern bool InsertMenu(IntPtr hMenu, int uPosition, int uFlags, int uIDNewItem, string lpNewItem);
[DllImport("user32.dll")]
//Lets you set various properties of a menu (grayed out, checked, etc)
private static extern bool ModifyMenu(IntPtr hMenu, uint uPosition, uint uFlags, IntPtr uIDNewItem, string lpNewItem);
[DllImport("user32.dll")]
//gets the hMenu for a submenu
private static extern IntPtr GetSubMenu(IntPtr hMenu, int pos);

参数说明:

hWnd 是带有标准菜单的 window 的句柄。

hMenu是菜单句柄,可以是根级菜单(如文件、编辑、帮助)或子菜单项(如打开、复制、关于...)的句柄。您可以通过 GetSubMenuGetSystemMenu

获得这些

uPosition为整数位置,0为第一个。

uFlags 可以在每个函数的单独页面上找到,您可以在 https://msdn.microsoft.com/en-us/library/ff468865%28v=vs.85%29.aspx

找到

lpNewItem指的是菜单项上显示的文本字符串。

uIDNewItem 是一个类似于 hMenu 的指针,它将被插入到定义的位置