我正在C++WinAPI中开发一个虚拟键盘。它显然需要知道Edit控件何时具有焦点,以便显示虚拟键盘(VK)窗口。当用户按下VK中的一个键时,程序需要将该字符插入另一个进程Edit控件中。这些都存在安全问题,甚至在Windows操作系统中都不可能。因此,我的问题。。。
-
是否可以知道另一个流程中的Edit控件何时具有焦点?我认为钩子可能是解决方案。使用全局钩子确实会带来安全问题,有没有一种方法可以让我专门对操作系统说"只告诉我什么时候"编辑"类型的控件有焦点"?还有其他我不知道的方法吗?
-
是否可以在另一个进程中插入字符编辑控件?这再次引发了安全/礼仪方面的担忧。
是否可以知道另一个流程中的Edit控件何时具有焦点?
是的,但不是直接。您确实需要一个钩子,可以通过SetWindowsHookEx()
或SetWinEventHook()
。
使用SetWindowsHookEx()
,为了挂接其他进程,必须在DLL中实现您的挂接(32位和64位系统的单独DLL)。您可以使用WH_CBT
挂钩查找HCBT_SETFOCUS
通知,或者使用WH_CALLWNDPROC
挂钩查找WM_SETFOCUS
/WM_KILLFOCUS
窗口消息。
使用SetWinEventHook()
,您不需要DLL来挂接其他进程。您可以注册接收EVENT_OBJECT_FOCUS
事件(不过,我没有看到用于检测失焦的挂钩事件)。
有没有一种方法可以让我专门对操作系统说"只告诉我什么时候‘编辑’类型的控件有焦点"?
没有。要专门筛选出Edit控件,您的钩子需要在提供的HWND
上调用GetClassName()
来查找已知的Edit类(并非所有Edit控件都命名为"EDIT"
)。
是否可以在另一个进程中插入字符编辑控件?
是的。您可以使用SendInput()
或keybd_event()
将键击发布到键盘驱动程序本身发布到的相同输入队列。只要Edit控件保持聚焦,它就会接收键击,就像用户正常键入一样。这是首选的方法。
然而,钩子确实为您提供了Edit控件的HWND
,因此您可以直接向Edit控件发送WM_KEYDOWN
/WM_CHAR
/WM_KEYUP
消息(但是,请注意这些问题:您不能用PostMessage模拟键盘输入,通过WM_CHAR消息模拟输入可能会伪造收件人,但不会伪造输入系统)。或者,您可以向Edit控件发送WM_GETTEXT
/WM_SETTEXT
消息,或通过AccessibleObjectFromWindow()
检索其IAccessible
接口,以根据需要操作Edit控件的文本内容。