当我在{10}中在Windows 10上运行WinForms(或Delphi,请参见最后的)应用程序时,当输入框被聚焦时,触摸键盘不会自动弹出。
我相信这应该是自动发生的,无需任何额外的代码/设置。
对于测试,我有一个最简单的VS 2015 WinForms桌面应用程序,只有一个tablet mode。
它只是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
与DropDownStyle = DropDown
)RichTextBox
)我通过运行TabTip.exe
看到了有关显式弹出窗口的所有提示。 E.g:
TextBox.PasswordChar
大多数"解决方案"提供这样的代码:
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 键的黑客攻击)。 / p>
实际上,上述黑客攻击在Windows 10周年更新中似乎不再起作用了:
有趣的是,我在Delphi / C ++ Builder / VCL应用程序中看到了相同的行为。键盘不会弹出编辑框(Show touch keyboard (TabTip.exe) in Windows 10 Anniversary edition)。它会弹出组合框(TEdit
)和密码模式下的编辑框(TComboBox
)。有趣的是,不是PasswordChar
,.NET RichTextBox
的显着差异,可能值得研究。
这个(未答复的)问题描述了一个相同的行为:
TRichEdit
答案 0 :(得分:9)
根本原因似乎是Winforms的textBox不是AutomationElement,而其他提到的控件(ComboBoxes等)是。
引用Markus von und zu Heber的accepted answer here:
我们在文章“Automatic Touch Keyboard for TextBoxes in WPF Applications on Windows 8+”中找到了它,但它也非常好(甚至 更容易!)为winforms。谢谢Dmitry Lyalin!
将对UIAutomationClient.dll的引用插入项目
- 醇>
在应用程序主窗口的form-load-handler中,插入以下代码:
var asForm = System.Windows.Automation.AutomationElement.FromHandle(this.Handle);
答案 1 :(得分:8)
我已经走过这条路几次,只能实现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 Desktop App: Open tabtip.exe to secondary keyboard (for numeric textbox)
答案 2 :(得分:5)
据我所知,发起osk.exe
或tabtip.exe
几乎就是"标准"使这项工作的方式。我发现没有"官方"解决方案到目前为止。
但是,如果我这样做,我就不会杀死进程或发送密钥来尝试解除键盘。相反,您可以在启动进程时获取窗口句柄,并使用它来最小化窗口并将其隐藏在任务栏中。
这里的某个人已经拿到了窗口句柄来关闭它,但它给了你一个主意:Show & hiding the Windows 8 on screen keyboard from WPF
如果你需要我,请告诉我,我会看看我是否能抽出时间做一个完整的例子。
答案 3 :(得分:1)
使用RichTextBox而不是TextBox控件。 RichTextBox支持触摸键盘,并在获得焦点时自动弹出键盘。 (类似于其他输入控件,如组合框)
RichTextBox还支持与TextBox相同的属性,因此在大多数情况下它应该是一个变化。 (两个控件都派生自TextBoxBase)
我注意到如果触摸键盘在弹出后被解除,你可能需要在控件上点击两次以使其弹回。
答案 4 :(得分:0)
正如Ofek Shilon's answer暗示的那样,触控键盘似乎可以利用UI automation。
可以使用UIAutomationClient.dll
中的UI自动化实现。
为了将UI自动化神奇地注入应用程序,必须触发程序集内部类UiaCoreApi
的类初始值设定项。
On可以通过调用seeming no-op来实现:
AutomationElement.FromHandle(IntPtr)(-1)
另一种方法是显式实现自动化UI。对于该实现,相应输入控件的ITextProvider
/ IValueProvider
接口。
要将接口的实现绑定到控件,请使用lParam
= RootObjectId
处理WM_GETOBJECT
window message。
有关实施的示例,请参阅
虽然有趣的是,触控键盘开箱即用(例如组合框或密码编辑框,请参阅答案)的控件不会实现WM_GETOBJECT
/ RootObjectId
。它们背后肯定有不同的机制。