有什么方法可以在不受控制的窗口菜单栏中阻止/删除键盘钩子?

时间:2018-01-24 21:25:33

标签: windows ui-automation

我使用PostMessage向无效的Adobe Flash Projector窗口发送击键,该部分完美运行。我让它在后台运行,它干扰我正常的计算机使用,这是意图。当我以编程方式发送W(或不太频繁的Q)密钥而我碰巧持有Ctrl用于其他Windows快捷方式时,问题就出现了。这会触发Ctrl-QCtrl-W,两者都会立即关闭Adobe Flash投影仪。 Ctrl-FCtrl-O也有一些不良影响。

编辑:我对简要发布Ctrl密钥的解决方案不感兴趣。

无论如何我可以从第三方窗口取消快捷键吗?它在窗口顶部使用标准的操作系统菜单栏,这是列出快捷方式的地方,所以肯定有一种方法可以重新分配,取消分配或阻止它,对吗?

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

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

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

我现在使用的语言是C#,但我认为解决方案使用的是.dll,因此不那么重要。随意建议或更改我的标签。

3 个答案:

答案 0 :(得分:1)

  1. 您可以尝试在目标应用程序的主窗口(包含菜单的窗口)中设置非活动状态(WS_DISABLED - 使用GetWindowStyleSetWindowStyle。)

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

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

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

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

    顺便说一句。您可以清除相应的窗口样式而不是销毁GetSystemMenu,并在发送输入后将其恢复(如果问题是系统菜单 - 概率接近1%)。

答案 1 :(得分:1)

使用程序Resource Tuner的免费试用版,我打开flashplayer_28_sa.exe,转到加速器表(显然加速器意味着菜单上下文中的快捷方式),并删除了有问题的快捷方式。然后我保存了它,它没能保存,我又一次又一次地保存了它,然后它又起作用了,虽然那段时间没什么不同的。

我认为它适用于带有标准Windows菜单的程序的其他快捷方式。

答案 2 :(得分:0)

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

各种外部:

[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是带有标准菜单的窗口的句柄。

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

获取这些内容

uPosition是一个整数位,0是第一个。

uFlags可以在每个功能的个人页面上找到,您可以在this similar question找到

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

uIDNewItem是一个像hMenu这样的指针,它将插入到定义的位置