在不受控制的 window 的菜单栏中 block/remove 键盘钩子有什么方法吗?
Any way to block/remove keyboard hook in uncontrolled window's Menubar?
我正在使用 PostMessage 将击键发送到不活动的 Adobe Flash 投影仪 window,这部分工作正常。我将它 运行 留在后台,它对我的正常计算机使用影响很小,这就是我的意图。当我以编程方式发送 W
(或不太频繁的 Q
)键时,问题就来了,而我恰好持有 Ctrl
用于不同的 windows 快捷方式。这会触发 Ctrl-Q
或 Ctrl-W
,两者都会立即关闭 Adobe Flash Projector。 Ctrl-F
和 Ctrl-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,所以这并不重要。欢迎提出建议或更改我的标签。
您可以尝试使目标应用程序(Window 包含菜单)。
您可以尝试找到应用程序使用了哪些函数,并使用 VirtualProtect
和注入汇编程序在应用程序的本地副本中重写它们(如果您不了解内存虚拟化是危险的) .使用 GetKeyState
或 GetAsyncKeyState
检查应用程序(在文本编辑器中打开应用程序后可见)。
你可以试试:
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
是菜单句柄,可以是根级菜单(如文件、编辑、帮助)或子菜单项(如打开、复制、关于...)的句柄。您可以通过 GetSubMenu
或 GetSystemMenu
或
获得这些
uPosition
为整数位置,0为第一个。
uFlags
可以在每个函数的单独页面上找到,您可以在 https://msdn.microsoft.com/en-us/library/ff468865%28v=vs.85%29.aspx
找到
lpNewItem
指的是菜单项上显示的文本字符串。
uIDNewItem
是一个类似于 hMenu
的指针,它将被插入到定义的位置
我正在使用 PostMessage 将击键发送到不活动的 Adobe Flash 投影仪 window,这部分工作正常。我将它 运行 留在后台,它对我的正常计算机使用影响很小,这就是我的意图。当我以编程方式发送 W
(或不太频繁的 Q
)键时,问题就来了,而我恰好持有 Ctrl
用于不同的 windows 快捷方式。这会触发 Ctrl-Q
或 Ctrl-W
,两者都会立即关闭 Adobe Flash Projector。 Ctrl-F
和 Ctrl-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,所以这并不重要。欢迎提出建议或更改我的标签。
您可以尝试使目标应用程序(Window 包含菜单)。
您可以尝试找到应用程序使用了哪些函数,并使用
VirtualProtect
和注入汇编程序在应用程序的本地副本中重写它们(如果您不了解内存虚拟化是危险的) .使用GetKeyState
或GetAsyncKeyState
检查应用程序(在文本编辑器中打开应用程序后可见)。你可以试试:
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
是菜单句柄,可以是根级菜单(如文件、编辑、帮助)或子菜单项(如打开、复制、关于...)的句柄。您可以通过 GetSubMenu
或 GetSystemMenu
或
uPosition
为整数位置,0为第一个。
uFlags
可以在每个函数的单独页面上找到,您可以在 https://msdn.microsoft.com/en-us/library/ff468865%28v=vs.85%29.aspx
lpNewItem
指的是菜单项上显示的文本字符串。
uIDNewItem
是一个类似于 hMenu
的指针,它将被插入到定义的位置