如何在Windows Vista/7中以编程方式(TabTip.exe)控制文本输入面板

Yng*_*and 16 c++ windows winapi mfc accessibility

我正在调整触摸屏界面的应用程序,我们想要使用Windows Vista/7中包含的平板电脑文本输入面板,特别是其键盘.我想根据我的应用显示和隐藏它.基本上我想要ShowKeyboard()HideKeyboard()功能.控制它的最佳方法是什么?

我查看了ITextInputPanel API但我无法直接用它控制键盘(也许我错过了什么?).我也试图向其窗口发送窗口消息失败.

该应用程序是用C++/MFC编写的.

任何指针都非常感谢.

Yng*_*and 14

我解决了这个问题.事实证明,Spy ++确实是Windows程序员最好的朋友.

首先,输入面板窗口的窗口类是"IPTip_Main_Window".我使用它来获取窗口句柄,如下所示:

HWND wKB = ::FindWindow(_TEXT("IPTip_Main_Window"), NULL);

事实证明,我可以发布自己的菜单发送的相同WM_COMMAND消息.大多数操作都可以从菜单中获得:dock top,dock bottom和float.发送这些消息的代码是:

::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)保护引起的.由于Tablet PC输入面板作为服务的子进程运行,因此它具有比用户程序更高的完整性级别,因此无法向其发送任何(或非常有限的一组)消息.

更新:

事实证明,Tablet PC输入面板确实在高完整性级别运行,而由有限用户帐户启动的流程是中等完整性级别.


小智 11

对于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
Run Code Online (Sandbox Code Playgroud)

值为0表示输入面板处于浮动模式.如果是这种情况,请发布以下消息以切换停靠状态:

DWORD WM_DOCK_BUTTON_PRESSED = ::RegisterWindowMessage(_TEXT("IPTipDockButtonPressed"));
PostMessage(hwndInputPanel, WM_DOCK_BUTTON_PRESSED, 0, 0);
Run Code Online (Sandbox Code Playgroud)

要隐藏键盘,请发布以下内容:

PostMessage(hwndInputPanel, WM_SYSCOMMAND, SC_CLOSE, 0);
Run Code Online (Sandbox Code Playgroud)