ShowKeyboard()
和 HideKeyboard()
函数。 控制它的最佳方法是什么?我查看了 ITextInputPanel API,但无法直接控制键盘(也许我错过了什么?)。 我还尝试向其窗口发送消息,但没有成功。
该应用程序采用 C++/MFC 编写。
非常感谢任何指针。
ShowKeyboard()
和 HideKeyboard()
函数。 控制它的最佳方法是什么?我解决了这个问题。原来Spy ++确实是Windows程序员最好的朋友。
首先,输入面板窗口的窗口类别是"IPTip_Main_Window"。我用这个获取窗口句柄:
HWND wKB = ::FindWindow(_TEXT("IPTip_Main_Window"), NULL);
事实证明,我可以发送与菜单相同的WM_COMMAND消息。大多数操作都可以从菜单中获得:固定顶部、固定底部和浮动。发送这些消息的代码如下:
::PostMessage(wKB, WM_COMMAND, MAKEWPARAM(X,0) , 0);
X为10021表示固定底部,10023表示固定顶部,10020表示浮动。高字中的0表示该消息是从菜单发送的。
最后,我想能够显示和隐藏输入面板。我注意到我可以打开一个桌面带,其中仅包含一个按钮,用于切换输入面板的可见性。通过对从此按钮发送的消息进行Spy ++,发现它发送一个全局注册的窗口消息,名为"TabletInputPanelDeskBandClicked"。 向输入面板发送此消息会使其切换其可见性。
HideKeyboard()函数现在看起来像这样:
DWORD WM_DESKBAND_CLICKED = ::RegisterWindowMessage(_TEXT("TabletInputPanelDeskBandClicked"));
void HideKeyboard() { HWND wKB = ::FindWindow(_TEXT("IPTip_Main_Window"), NULL); if(wKB != NULL && ::IsWindowVisible(wKB)) { ::PostMessage(wKB, WM_DESKBAND_CLICKED, 0, 0); } }
ShowWindow()函数的实现方式类似,但它还会在键盘未运行时启动键盘。
似乎Windows Vista/7中禁止这种进程间通信。在非提升权限的进程中运行此命令将导致“访问被拒绝”的失败。我猜测这是由于Windows Vista/7中发现的用户界面进程隔离(UIPI)保护所造成的。因为平板电脑输入面板正在作为服务的子进程中运行,它具有比用户程序更高的完整性级别,因此无法接收任何(或者非常有限的)消息。
事实证明,平板电脑输入面板确实以高完整性级别运行,而由受限用户帐户启动的进程则是中间完整性级别。
对于Windows 8:
注意:与Windows 7的解决方案一样,这需要一个提升的进程。
输入面板不是HWND_DESKTOP的后代。(它可能是某种Metro窗口。)为了获得窗口句柄,以网格状模式进行一系列水平扫描,并使用WindowFromPoint()进行测试。对于每个测试,检查父窗口的窗口类是否为"IPTip_Main_Window"。
要显示输入面板,请启动"C:\\Program Files\\Common Files\\microsoft shared\\ink\\tabtip.exe"
。要确定它是否已处于停靠模式,请读取注册表键:
HKEY_CURRENT_USER\Software\Microsoft\TabletTip\1.7\EdgeTargetDockedState
当值为0时,表示输入面板处于浮动模式。如果是这种情况,请发布以下消息以切换到停靠状态:
DWORD WM_DOCK_BUTTON_PRESSED = ::RegisterWindowMessage(_TEXT("IPTipDockButtonPressed"));
PostMessage(hwndInputPanel, WM_DOCK_BUTTON_PRESSED, 0, 0);
要隐藏键盘,请发布以下内容:
PostMessage(hwndInputPanel, WM_SYSCOMMAND, SC_CLOSE, 0);