如何在 Windows Vista/7 中以编程方式控制文本输入面板 (TabTip.exe) [英] How do I control the text input panel programmatically (TabTip.exe) in Windows Vista/7

查看:25
本文介绍了如何在 Windows Vista/7 中以编程方式控制文本输入面板 (TabTip.exe)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

非常感谢任何指针.

解决方案

我解决了这个问题.事实证明,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"));无效隐藏键盘(){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 输入面板确实以高完整性级别运行,而由受限用户帐户启动的进程是中等完整性级别.

I'm adapting an application for touch screen interface and we want to use the tablet text input panel included in Windows Vista/7, specifically its keyboard. I want to show and hide it as appropriate for my app. Basically I want ShowKeyboard() and HideKeyboard() functions. What's the best way to control this?

I looked at the ITextInputPanel API but I was unable to control the keyboard directly with it (maybe I missed something?). I have also unsuccessfully tried to send window messages to its window.

The application is written in C++/MFC.

Any pointers at all are greatly appreciated.

解决方案

I solved the problem. It turns out that Spy++ really is a Windows programmers best friend.

First, the window class of the input panel window turns out to be "IPTip_Main_Window". I use this to get the window handle like so:

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

It turns out that I can just post the same WM_COMMAND messages that its own menu is sending. Most of the operations are available from the menu: dock top, dock bottom and float. The code for sending those messages are:

::PostMessage(wKB, WM_COMMAND, MAKEWPARAM(X,0) , 0);

where X is 10021 for dock bottom, 10023 for dock top and 10020 for floating. The 0 in the high word indicates that the message is sent from a menu.

Finally, I wanted to be able to show and hide the input panel. I noticed that I could turn on a desk band which only includes a single button for toggling the visibility of the input panel. Spy++ing on the messages posted from this button revealed that it sends a global registered window message which is named "TabletInputPanelDeskBandClicked". Sending this message to the input panel causes it to toggle its visibility.

The HideKeyboard() function now looks like this:

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);
    }
}

The ShowWindow() function is implemented similarly, but it will also start the keyboard if it is not running.

Update:

It seems that this inter-process messaging is disallowed in Windows Vista/7. When running this command in a non-elevated process it will fail with "access denied". My guess is that this is caused by User Interface Process Isolation (UIPI) protection found in Windows Vista/7. Since the Tablet PC Input Panel is running as a child process of a service it has higher integrity level than user programs, and thus cannot be sent any (or a very limited set of) messages to.

Update:

It turns out that the Tablet PC Input Panel is indeed running in high integrity level, whereas processes started by a limited user account is medium integrity level.

这篇关于如何在 Windows Vista/7 中以编程方式控制文本输入面板 (TabTip.exe)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆