如何在C#WinForms中使用Windows屏幕键盘

时间:2013-03-21 17:58:10

标签: c# windows winforms 32bit-64bit on-screen-keyboard

  • VS 2010
  • 开发在64位操作系统(Windows 7,Windows 8 - 桌面应用程序)上运行的32位应用程序
  • C#
  • .NET 4.0
  • 的WinForms

我从应用程序启动Windows屏幕键盘(osk.exe)时发现了许多线程,但我遇到了一些问题。这似乎是因为我在64位操作系统上运行32位应用程序。我在这里尝试过WooCaSh发布的代码: Keyboard on the screen in WinForms

但这三种不同的路径都不适合我。对于sysnative路径,Process.Start失败,"无法找到指定的路径。" 对于system32osk.exe路径,我得到"无法启动屏幕键盘" 错误对话框。

我在这里找到了一个可能的解决方法,这比我想要的更复杂一点(由eryang发布):http://social.msdn.microsoft.com/Forums/en-US/netfx64bit/thread/10ebc62f-e6d7-4072-9fd1-ea3784a0966f/

  1. 有更简单或更正确的方法吗?
  2. 我希望在平板电脑上运行我的应用程序会在用户选择文本框时自动启动屏幕键盘,但没有运气。这是正常的还是我错过了什么?我发现在桌面模式(我的应用程序是)时,键盘不会在Windows 8中自动启动:http://www.bleepingcomputer.com/forums/t/480250/keyboard-does-not-pop-up-automatically/显然它适用于Windows 7平板电脑,但我无法测试,因为我这里只有Windows 8平板电脑。

6 个答案:

答案 0 :(得分:20)

我正在推出“触摸键盘”,而不是“屏幕键盘”(这是我在Windows 8上想要的键盘):

string progFiles = @"C:\Program Files\Common Files\Microsoft Shared\ink";
string keyboardPath = Path.Combine(progFiles, "TabTip.exe");

this.keyboardProc = Process.Start(keyboardPath);

这适用于我的Win7和Win8,无论我在64位操作系统上的32位应用程序如何。但是,当我完成时,我仍然有以编程方式关闭键盘的问题。过程this.keyboardProc似乎没有得到句柄,并且立即拥有属性HasExited = true。这意味着我关闭或杀死它的尝试失败了。

根据这个帖子,如果用户手动打开键盘(或者我以编程方式启动它),当文本字段失去焦点时,键盘将不会自动关闭/隐藏:Windows 8 - How to Dismiss Touch Keyboard?我尝试了设置的方法专注于隐藏按钮,但由于我自己启动键盘,它不会自动关闭。

答案 1 :(得分:10)

我无法关闭屏幕键盘。您可以使用

启动触摸键盘
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);

并使用

关闭所有键盘
//Kill all on screen keyboards
Process[] oskProcessArray = Process.GetProcessesByName("TabTip");
foreach (Process onscreenProcess in oskProcessArray)
{
    onscreenProcess.Kill();
}

出于某种原因,onScreenKeyboardProc.Kill()或.Close()不起作用。

答案 2 :(得分:6)

要使键盘自动打开,控件必须实现一些UI自动化控件模式,特别是ITextProvider / IValueProvider。这是一个麻烦,但它的工作原理(它比启动一些* .exe更简洁)

我在这里写了一个示例应用程序和一篇简短的文章:http://blog.tombam.net/implementing-textbox-with-on-screen-touch-keyboard-part-1/

答案 3 :(得分:2)

触控键盘利用UI自动化。由于某些原因对我来说是个谜,标准的Windows编辑框不会自动实现UI,而其他控件(如组合框)也可以实现。

可以使用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。它们背后肯定有不同的机制。

最常见的"解决方案"对于这个问题,通过运行TabTip.exeosk.exe来明确弹出键盘是不可接受的。

如果没有别的,那么因为没有干净的方法来隐藏通过运行TabTip.exe而打开的键盘(解决方案包括杀死进程或发送 Esc 键等黑客攻击)。

实际上,上述黑客攻击似乎不再适用于Windows 10周年更新:Show touch keyboard (TabTip.exe) in Windows 10 Anniversary edition

答案 4 :(得分:0)

启动TabTip.exe不再适用于Widnows 10周年纪念版。我发现了一个用于控制触摸键盘的未记录的COM接口。检查此处的代码https://stackoverflow.com/a/40921638/332528

答案 5 :(得分:0)

我在这里和其他地方冲浪,然后我实现了这一点:

using System.Diagnostics; // remember use this

public partial class Window1 : Window
{

    public Process _p = null;
   
    public Window1()
    {
        InitializeComponent();          
    }

    public void Button_Click(object sender, RoutedEventArgs e)
    {
        if (_p != null)
        {
            _p.Kill();
            _p.Dispose();
            _p = null;
        }
        _p = Process.Start(@"C:\Program Files\Common Files\microsoft shared\ink\TabTip.exe");    
    }

    private void Acceso_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        if (_p != null)
        {
            _p.Kill();
            _p.Dispose();
            _p = null;
        }
    }
}

它正常工作,所以我在这里分享它,以防您的信息对我有帮助。