Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在Windows Vista/7中以编程方式控制文本输入面板(TabTip.exe)_C++_Windows_Mfc_Winapi_Accessibility - Fatal编程技术网

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

C++ 如何在Windows Vista/7中以编程方式控制文本输入面板(TabTip.exe),c++,windows,mfc,winapi,accessibility,C++,Windows,Mfc,Winapi,Accessibility,我正在为触摸屏界面调整一个应用程序,我们希望使用WindowsVista/7中包含的平板电脑文本输入面板,特别是它的键盘。我想根据我的应用程序显示和隐藏它。基本上我想要ShowKeyboard()和HideKeyboard()函数。最好的控制方法是什么 我查看了ITextInputPanel API,但无法直接用它控制键盘(可能我错过了什么?)。我还尝试向其窗口发送窗口消息,但未成功 应用程序是用C++/MFC编写的 非常感谢您的指点。我解决了这个问题。事实证明,Spy++确实是Windows程

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

我查看了ITextInputPanel API,但无法直接用它控制键盘(可能我错过了什么?)。我还尝试向其窗口发送窗口消息,但未成功

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


非常感谢您的指点。

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

首先,输入面板窗口的窗口类是“IPTip_Main_window”。我使用这个来获得窗口句柄,如下所示:

HWND wKB = ::FindWindow(_TEXT("IPTip_Main_Window"), NULL); HWND wKB=::FindWindow(_TEXT(“IPTip_主窗口”),NULL); 事实证明,我可以发布与它自己的菜单发送的相同的WM_命令消息。大多数操作可从菜单中获得:船坞顶部、船坞底部和浮动。发送这些消息的代码为:

::PostMessage(wKB, WM_COMMAND, MAKEWPARAM(X,0) , 0); ::PostMessage(wKB,WM_命令,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); } } DWORD WM_DESKBAND_单击= ::RegisterWindowMessage(_TEXT(“TabletInputPanelDeskBandClicked”); void隐藏板() { HWND wKB=::FindWindow(_TEXT(“IPTip_主窗口”),NULL); 如果(wKB!=NULL&::IsWindowVisible(wKB)) { ::PostMessage(wKB,WM_DESKBAND_单击,0,0); } } ShowWindow()函数的实现方式与此类似,但如果键盘未运行,它也会启动键盘

更新: Windows Vista/7中似乎不允许此进程间消息传递。在非提升进程中运行此命令时,它将失败并显示“拒绝访问”。我猜这是由WindowsVista/7中的用户界面进程隔离(UIPI)保护引起的。由于Tablet PC输入面板作为服务的子进程运行,其完整性级别高于用户程序,因此无法向用户发送任何(或非常有限的)消息

更新: 事实证明,Tablet PC输入面板确实以高完整性级别运行,而由有限用户帐户启动的进程是中等完整性级别。

对于Windows 8:

注意:与Windows 7解决方案一样,这需要一个提升的进程

输入面板不是HWND_DESKTOP的后代。(可能是某种Metro窗口。)为了获得窗口句柄,使用WindowFromPoint()在网格状模式测试中进行一系列水平扫描。对于每个测试,检查父窗口的窗口类,查看它是否为“IPTip_主窗口”

要显示输入面板,请启动
“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);

谢谢你的信息!你知道我发布的“解决方案”在windows 8上是否仍然有效吗?我的测试表明它不起作用。看起来微软重新设计了Windows8的输入面板。不再有下拉菜单来设置停靠状态,因此WM_命令将不会执行任何操作。现在只有一个按钮可以在停靠和取消停靠之间切换。此外,由于窗口层次结构中的某些更改,FindWindow()将无法实际获取窗口句柄。我必须用WindowFromPoint()进行测试才能找到它。这也适用于Windows 7。对于那些不太熟悉windows api的人:可以使用GetParent(HWND窗口)获取父级,也可以使用GetClassName()获取其类名。我有一个相关的问题