如何在 C# WinForms 中使用 Windows 屏幕键盘
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15554786/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use Windows On-Screen Keyboard in C# WinForms
提问by Tara
- VS 2010
- Developing 32-bit app that runs on 64-bit OS (Windows 7, Windows 8 - desktop app)
- C#
- .NET 4.0
- WinForms
- VS 2010
- 开发在 64 位操作系统(Windows 7、Windows 8 - 桌面应用程序)上运行的 32 位应用程序
- C#
- .NET 4.0
- 窗体
I have found many threads on launching the Windows on-screen keyboard (osk.exe
) from an application, but I am running into some problems. It appears to be because I am running a 32-bit app on a 64-bit OS. I've tried the code posted by WooCaSh here:
Keyboard on the screen in WinForms
我发现有很多关于osk.exe
从应用程序启动 Windows 屏幕键盘 ( ) 的线程,但我遇到了一些问题。似乎是因为我在 64 位操作系统上运行 32 位应用程序。我在这里尝试了 WooCaSh 发布的代码:
WinForms 屏幕上的键盘
But none of the three different paths work for me. For the sysnative
path, Process.Start
fails with "Cannot find the path specified."For the system32
and osk.exe
paths, I get the "Could not start the on-screen keyboard"error dialog.
但是这三种不同的路径都不适合我。对于sysnative
路径,Process.Start
失败并显示 “找不到指定的路径”。对于system32
和osk.exe
路径,我收到“无法启动屏幕键盘”错误对话框。
I found a possible workaround here, which is a little more complicated than what I was looking for (post by eryang): http://social.msdn.microsoft.com/Forums/en-US/netfx64bit/thread/10ebc62f-e6d7-4072-9fd1-ea3784a0966f/
我在这里找到了一个可能的解决方法,它比我想要的要复杂一些(由 eryang 发布):http://social.msdn.microsoft.com/Forums/en-US/netfx64bit/thread/10ebc62f-e6d7 -4072-9fd1-ea3784a0966f/
- Is there an easier or correct way to do this?
- I was hoping that running my app on a tablet would automatically launch the on-screen keyboard when the user selects a textbox, but no luck. Is this normal or am I missing something? I've found that the keyboard is not automatically launched in Windows 8 when in Desktop mode (which my app is): http://www.bleepingcomputer.com/forums/t/480250/keyboard-does-not-pop-up-automatically/Apparently it works on Windows 7 tablets, but I can't test because I only have Windows 8 tablets here.
- 有没有更简单或更正确的方法来做到这一点?
- 我希望当用户选择一个文本框时,在平板电脑上运行我的应用程序会自动启动屏幕键盘,但没有运气。这是正常的还是我错过了什么?我发现在桌面模式下(我的应用程序是)键盘不会在 Windows 8 中自动启动:http: //www.bleepingcomputer.com/forums/t/480250/keyboard-does-not-pop-up -自动/显然它适用于 Windows 7 平板电脑,但我无法测试,因为我这里只有 Windows 8 平板电脑。
采纳答案by Tara
I am now launching the "Touch Keyboard" as opposed to the "On-Screen Keyboard" (which is the keyboard I wanted on Windows 8 anyway) with:
我现在启动“触摸键盘”而不是“屏幕键盘”(无论如何这是我在 Windows 8 上想要的键盘):
string progFiles = @"C:\Program Files\Common Files\Microsoft Shared\ink";
string keyboardPath = Path.Combine(progFiles, "TabTip.exe");
this.keyboardProc = Process.Start(keyboardPath);
This works on my Win7 and Win8, regardless of my 32-bit app on 64-bit OS. However, I still have the problem of programmatically closing the keyboard when I'm done. The process, this.keyboardProc
, does not seem to get the handle, and immediately has property HasExited = true
. This means my attempts to close or kill it fail.
这适用于我的 Win7 和 Win8,无论我在 64 位操作系统上的 32 位应用程序如何。但是,我仍然遇到在完成后以编程方式关闭键盘的问题。进程,this.keyboardProc
,似乎没有得到句柄,立即拥有属性HasExited = true
。这意味着我试图关闭或杀死它失败。
According to this thread, if the user manually opens the keyboard (or I programmatically launch it), the keyboard will not automatically close/hide when the text field loses focus: Windows 8 - How to Dismiss Touch Keyboard?I tried the workaround of setting the focus to a hidden button, but since I launched the keyboard myself, it doesn't close automatically.
根据此线程,如果用户手动打开键盘(或我以编程方式启动它),当文本字段失去焦点时,键盘不会自动关闭/隐藏:Windows 8 - 如何关闭触摸键盘?我尝试了将焦点设置为隐藏按钮的解决方法,但由于我自己启动了键盘,因此它不会自动关闭。
回答by Panu Horsmalahti
I had trouble closing the on screen keyboard. You can start the Touch Keyboard with
我无法关闭屏幕键盘。您可以使用以下命令启动触摸键盘
string progFiles = @"C:\Program Files\Common Files\Microsoft Shared\ink";
string onScreenKeyboardPath = System.IO.Path.Combine(progFiles, "TabTip.exe");
onScreenKeyboardProc = System.Diagnostics.Process.Start(onScreenKeyboardPath);
and close all keyboards with
并关闭所有键盘
//Kill all on screen keyboards
Process[] oskProcessArray = Process.GetProcessesByName("TabTip");
foreach (Process onscreenProcess in oskProcessArray)
{
onscreenProcess.Kill();
}
For some reason onScreenKeyboardProc.Kill() or .Close() doesn't work.
由于某种原因 onScreenKeyboardProc.Kill() 或 .Close() 不起作用。
回答by torvin
Starting TabTip.exe no longer works in Widnows 10 Anniversary Edition. I discovered an undocumented COM interface for controlling the touch keyboard. Check the code here https://stackoverflow.com/a/40921638/332528
在 Widnows 10 周年纪念版中启动 TabTip.exe 不再有效。我发现了一个用于控制触摸键盘的未公开的 COM 接口。检查这里的代码https://stackoverflow.com/a/40921638/332528
回答by tombam
For the keyboard to open up automatically, the controls have to implement some UI Automation control patterns, specifically ITextProvider/IValueProvider. It is a nuisance, but it works (and it is a cleaner way than launching some *.exe)
为了让键盘自动打开,控件必须实现一些 UI 自动化控件模式,特别是 ITextProvider/IValueProvider。这是一个麻烦,但它的工作原理(它比启动一些 *.exe 更干净)
I wrote a sample app and a short article here: http://blog.tombam.net/implementing-textbox-with-on-screen-touch-keyboard-part-1/
我在这里写了一个示例应用程序和一篇短文:http: //blog.tombam.net/implementing-textbox-with-on-screen-touch-keyboard-part-1/
回答by Martin Prikryl
The touch keyboard leverages the UI automation. For some reasons that are a mystery to me, the standard Windows edit box does not implement UI automation, while other controls, like combo box, do.
触摸键盘利用 UI 自动化。由于某些我觉得很神秘的原因,标准的 Windows 编辑框没有实现 UI 自动化,而其他控件,如组合框,则可以。
One can use implementation of UI automation from UIAutomationClient.dll
.
可以使用UIAutomationClient.dll
.
For the UI automation to be magically injected into an application, class initializer of the assembly internal class UiaCoreApi
have to be triggered.
为了将 UI 自动化神奇地注入应用程序,UiaCoreApi
必须触发程序集内部类的类初始化程序。
On can achieve that for example by calling seeming no-op:
例如,可以通过调用看似无操作来实现这一点:
AutomationElement.FromHandle(IntPtr)(-1)
Another way is to implement automation UI explicitly. For that implement the ITextProvider
/IValueProvider
interfaces for the respective input control.
另一种方法是显式实现自动化 UI。为此,为相应的输入控件实现ITextProvider
/IValueProvider
接口。
To bind the implementation of the interfaces to the control, handle WM_GETOBJECT
window messagewith lParam
= RootObjectId
.
要将接口的实现绑定到控件,请使用=处理WM_GETOBJECT
窗口消息。lParam
RootObjectId
For an example of implementation, see
有关实现的示例,请参阅
- tombam's answerto this question;
- or directly poster's article Implementing TextBox with on-screen touch keyboard.
- tombam对这个问题的回答;
- 或直接海报的文章用屏幕触摸键盘实现文本框。
Though interestingly, controls, for which touch keyboard works out-of-the-box (like combo box or password edit box, see the answer), do not implement the WM_GETOBJECT
/RootObjectId
. There must be a different machinery behind them.
尽管有趣的是,触摸键盘开箱即用的控件(如组合框或密码编辑框,请参阅答案)并未实现WM_GETOBJECT
/ RootObjectId
。他们背后一定有不同的机器。
The most common "solution" to this problem, to explicitly popup the keyboard by running the TabTip.exe
or osk.exe
, is hardly acceptable.
这个问题最常见的“解决方案”是通过运行TabTip.exe
or显式弹出键盘osk.exe
,这几乎是不可接受的。
If for nothing else, then because there's no clean way to hide the keyboard opened by running the TabTip.exe
(solutions include hacks like killing the process or sending Esckey).
如果没有别的,那么因为没有干净的方法来隐藏通过运行打开的键盘TabTip.exe
(解决方案包括诸如终止进程或发送Esc密钥之类的黑客攻击)。
And actually the above hack does not seem to work anymore in Windows 10 Anniversary Update: Show touch keyboard (TabTip.exe) in Windows 10 Anniversary edition.
实际上,上述 hack 在 Windows 10 Anniversary Update: Show touch keyboard (TabTip.exe) in Windows 10 Anniversary edition 中似乎不再起作用。