[英]Automatically pop up tablet touch keyboard on WinForms input focus
当我以平板电脑模式在 Windows 10 上运行 WinForms(或 Delphi,见文末)应用程序时,当输入框聚焦时,触摸键盘不会自动弹出。
我相信这应该自动发生,没有任何额外的代码/设置。
为了测试,我有一个最简单的 VS 2015 WinForms 桌面应用程序,带有一个TextBox
控件。
它只是 Visual Studio 创建的默认 Windows 窗体应用程序 C# 项目。 未添加代码,未更改任何属性。 通过从工具箱中删除(同样没有更改属性),只添加了TextBox
:
this.textBox1 = new System.Windows.Forms.TextBox();
this.textBox1.Location = new System.Drawing.Point(64, 27);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(100, 20);
this.textBox1.TabIndex = 0;
为了验证我的假设,弹出窗口应该是自动的:
我尝试在 Windows 10 上运行 Windows XP 版本的notepad.exe
。它会自动弹出触摸键盘。 我怀疑 Windows XP 是否明确支持触摸键盘。
我还尝试了一些古老的 MFC 应用程序(例如 2005 年的 FileZilla 2.2.15)。 它还会在其所有输入框上弹出触摸键盘。 同样,我很确定,MFC 也没有明确支持触摸键盘。
构建在 wxWidgets 上的应用程序(例如 FileZilla 3.x)也是如此。
看起来 WinForms 中的某些东西阻止了自动弹出窗口。 有趣的是,自动弹出的工作原理是:
ComboBox
with DropDownStyle = DropDown
)TextBox.PasswordChar
)RichTextBox
) 我已经通过运行TabTip.exe
看到了有关显式弹出窗口的所有提示。 例如:
大多数“解决方案”都提供这样的代码:
var progFiles = @"C:\Program Files\Common Files\Microsoft Shared\ink";
var keyboardPath = Path.Combine(progFiles, "TabTip.exe");
this.keyboardProc = Process.Start(keyboardPath);
但我无法相信这可能是“官方”方式。 如果没有别的,那么因为没有干净的方法来隐藏通过运行TabTip.exe
打开的键盘(解决方案包括诸如终止进程或发送Esc键之类的黑客攻击)。
实际上,上述 hack 在 Windows 10 周年更新中似乎不再起作用:
有趣的是,我在 Delphi/C++ Builder/VCL 应用程序中看到了相同的行为。 键盘不会弹出编辑框( TEdit
)。 它确实会弹出组合框 ( TComboBox
) 和密码模式下的编辑框 ( PasswordChar
)。 有趣的是,对于TRichEdit
,与 .NET RichTextBox
什么显着区别,这可能值得研究。
这个(未回答的)问题描述了一个相同的行为:
在编辑框键盘中编写的应用程序 Delphi XE8 touch 不会出现在 Windows 10 中。
我已经在这条路上走了几次,但只能实现taptip.exe
选项。 然后通过终止进程关闭窗口。 我还发现,如果您愿意,可以通过一些注册表技巧使键盘默认为手写面板。 但那只能在 Win8 中有效,在 Win10 中失败。 这是我所做的,以防其他人发现这很有用:
RegistryKey registryKey = Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\TabletTip\\1.7");
registryKey?.SetValue("KeyboardLayoutPreference", 0, RegistryValueKind.DWord);
registryKey?.SetValue("LastUsedModalityWasHandwriting", 1, RegistryValueKind.DWord);
Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");
我需要感谢这篇文章的注册表想法: Windows 8 桌面应用程序:打开 tabtip.exe 到辅助键盘(用于数字文本框)
根本原因似乎是 Winforms 的 textBox 不是 AutomationElement,而其余提到的控件(ComboBoxes 等)是。
在这里引用 Markus von und zu Heber 接受的答案:
我们在“ Windows 8+ 上的 WPF 应用程序中的文本框的自动触摸键盘”一文中找到了它,但它对于 winforms 也非常有效(甚至更容易!)。 谢谢你,德米特里莱林!
将 UIAutomationClient.dll 的引用插入到您的项目中
在应用程序主窗口的表单加载处理程序中,插入以下代码:
var asForm = System.Windows.Automation.AutomationElement.FromHandle(this.Handle);
据我所知,启动osk.exe
或tabtip.exe
几乎是完成这项工作的“标准”方式。 到目前为止,我还没有找到“官方”解决方案。
但是,如果是我这样做,我不会终止进程或发送键来尝试关闭键盘。 相反,您可以在启动进程时获取窗口句柄,并使用它来最小化窗口并将其从任务栏中隐藏。
这里有人得到了窗口句柄只是为了关闭它,但它给了你一个想法: 从 WPF 在屏幕键盘上显示和隐藏 Windows 8
如果你需要我,让我知道,我会看看我是否能找到时间做一个完整的例子。
正如Ofek Shilon 的回答所暗示的那样,触摸键盘似乎可以利用UI 自动化。
可以使用UIAutomationClient.dll
的 UI 自动化实现。
为了将 UI 自动化神奇地注入应用程序,必须触发程序集内部类UiaCoreApi
类初始化程序。
例如,可以通过调用看似无操作来实现这一点:
AutomationElement.FromHandle(IntPtr)(-1)
另一种方法是显式实现自动化 UI。 为此,为相应的输入控件实现ITextProvider
/ IValueProvider
接口。
要将接口的实现绑定到控件,请使用lParam
= RootObjectId
处理WM_GETOBJECT
窗口消息。
有关实现的示例,请参阅
尽管有趣的是,触摸键盘开箱即用的控件(如组合框或密码编辑框,请参阅答案)并未实现WM_GETOBJECT
/ RootObjectId
。 他们背后一定有不同的机器。
使用 RichTextBox 而不是 TextBox 控件。 RichTextBox 支持触摸键盘,获得焦点时会自动弹出键盘。 (类似于组合框等其他输入控件)
RichTextBox 还支持与 TextBox 相同的属性,因此在大多数情况下它应该是一个变化。 (两个控件都源自 TextBoxBase)
我注意到如果触摸键盘在弹出后被关闭,您可能需要在控件上点击两次才能让它重新弹出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.