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

我正在调整一个触摸屏界面的应用程序,我们希望使用Windows Vista / 7中包含的平板电脑文本input面板,特别是它的键盘。 我想显示和隐藏它适合我的应用程序。 基本上我需要ShowKeyboard()HideKeyboard()函数。 什么是控制这个最好的方法?

我查看了ITextInputPanel API,但是我无法直接用它控制键盘(也许我错过了什么?)。 我也没有尝试将窗口消息发送到窗口。

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

任何指针都非常赞赏。

Solutions Collecting From Web of "如何在Windows Vista / 7中以编程方式控制文本input面板(TabTip.exe)"

我解决了这个问题。 事实证明,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表示消息是从菜单发送的。

最后,我希望能够显示和隐藏输入面板。 我注意到,我可以打开一个桌面带,只有一个按钮用于切换输入面板的可视性。 间谍++从这个按钮发布的消息透露,它发送一个名为“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输入面板确实运行在高完整性级别,而由有限用户帐户启动的进程是中等完整性级别。

对于Windows 8:

注意:就像Windows 7解决方案一样,这需要一个提升的过程。

输入面板不是HWND_DESKTOP的后代。 (这可能是某种地铁窗口。)为了获得窗口句柄,使用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);