在 WPF 的屏幕键盘上显示和隐藏 Windows 8

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17090325/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:00:02  来源:igfitidea点击:

Show & hiding the Windows 8 on screen keyboard from WPF

wpfwindows-8touchscreenon-screen-keyboard

提问by Sun

I'm writing a WPF application for a Windows 8 tablet. It's full windows 8 and not ARM/RT.

我正在为 Windows 8 平板电脑编写 WPF 应用程序。它是完整的 Windows 8 而不是 ARM/RT。

When the user enters a textbox I show the on screen keyboard using the following code:

当用户输入文本框时,我使用以下代码显示屏幕键盘:

System.Diagnostics.Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");

This works fine however I don't know how to hide the keyboard again?

这工作正常但是我不知道如何再次隐藏键盘?

Anybody know how to do this?

有人知道怎么做吗?

Also, is there any way I can resize my application so that focused control is moved up when the keyboard appears? A bit like it does for a windows RT application.

另外,有什么方法可以调整我的应用程序的大小,以便在键盘出现时将焦点控制向上移动?有点像 Windows RT 应用程序。

Many Thanks

非常感谢

回答by tasasaki

I could successfully close onscreen keyboard with the following C# code.

我可以使用以下 C# 代码成功关闭屏幕键盘。

[DllImport("user32.dll")]
public static extern int FindWindow(string lpClassName,string lpWindowName);

[DllImport("user32.dll")]
public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);

public const int WM_SYSCOMMAND = 0x0112;
public const int SC_CLOSE = 0xF060;

private void closeOnscreenKeyboard()
{
    // retrieve the handler of the window  
    int iHandle = FindWindow("IPTIP_Main_Window", "");
    if (iHandle > 0)
    {
        // close the window using API        
        SendMessage(iHandle, WM_SYSCOMMAND, SC_CLOSE, 0);
    }  
}

private void Some_Event_Happened(object sender, EventArgs e)
{
    // It's time to close the onscreen keyboard.
    closeOnscreenKeyboard();
}

I hope this will help you.

我希望这能帮到您。

回答by Guillaume

A little bit late, I'll just improve tasaki example for a complete one of what I did to enable show/hide on gotFocus/LostFocus event when user click on a textBox in my WPF application for windows 8 tablet.I hope this help people with similar headache, because disabling InkHelper, doesn't really work well if u want to scroll with touch event...

有点晚了,我将改进 tasaki 示例以获得完整的一个示例,当用户单击 Windows 8 平板电脑的 WPF 应用程序中的文本框时,我为在 gotFocus/LostFocus 事件上启用显示/隐藏所做的一个完整示例。我希望这对人们有所帮助与类似的头痛,因为禁用 InkHelper,如果你想滚动触摸事件并不能很好地工作......

First of all u must add these reference to your App.Xaml.cs File.

首先,您必须将这些引用添加到您的 App.Xaml.cs 文件中。

using System.Management;
using System.Runtime.InteropServices;

The code:

编码:

    protected override void OnStartup(StartupEventArgs eventArgs)
    {
        EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotFocusEvent,
                                new RoutedEventHandler(GotFocus_Event), true);
        EventManager.RegisterClassHandler(typeof(TextBox), UIElement.LostFocusEvent,
                                new RoutedEventHandler(LostFocus_Event), true);

       MainApplication.Show();
    }

    private static void GotFocus_Event(object sender, RoutedEventArgs e)
    {
       // TestKeyboard();
        OpenWindows8TouchKeyboard(sender, e);
    }
    //http://www.c-sharpcorner.com/UploadFile/29d7e0/get-the-key-board-details-of-your-system-in-windows-form/
    private static bool IsSurfaceKeyboardAttached()
    {
        SelectQuery Sq = new SelectQuery("Win32_Keyboard");
        ManagementObjectSearcher objOSDetails = new ManagementObjectSearcher(Sq);
        ManagementObjectCollection osDetailsCollection = objOSDetails.Get();
        //Windows 8 tablet are returnign 2 device when keyboard is connecto
        //My application won't be used for Desktop so this condition is fine
        //But u might want to see if keyboard is usb and == 1 so you are 
        //returning true or not on tablet.  
        return osDetailsCollection.Count <= 1 ? true : false;
    }

    private static void OpenWindows8TouchKeyboard(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;        
        if (textBox != null && IsSurfaceKeyboardAttached())
        {
            var path = @"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe";
            if (!File.Exists(path))
            {
                // older windows versions
                path = Environment.GetFolderPath(Environment.SpecialFolder.System) + @"\osk.exe";
            }
            Process.Start(path);
            textBox.BringIntoView();//SetFocus so u dont lose focused area
        }
    }
    [DllImport("user32.dll")]
    public static extern int FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll")]
    public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);

    public const int WM_SYSCOMMAND = 0x0112;
    public const int SC_CLOSE = 0xF060;
    public const int SC_MINIMIZE = 0xF020;

    private void CloseOnscreenKeyboard()
    {
        // retrieve the handler of the window  
        int iHandle = FindWindow("IPTIP_Main_Window", "");
        if (iHandle > 0)
        {
            // close the window using API        
            SendMessage(iHandle, WM_SYSCOMMAND, SC_CLOSE, 0);
        }
    }

    private void LostFocus_Event(object sender, EventArgs e)
    {
        // It's time to close the onscreen keyboard.
        CloseOnscreenKeyboard();
    }

回答by Макс Федотов

I open-sourced my project to automate everything concerning TabTip integration in WPF app.

我开源了我的项目,以自动化 WPF 应用程序中与 TabTip 集成相关的所有内容。

You can get it on nuget, and after that all you need is a simple config in your apps startup logic:

您可以在nuget上获取它,之后您只需要在应用程序启动逻辑中进行一个简单的配置:

TabTipAutomation.BindTo<TextBox>();

You can bind TabTip automation logic to any UIElement. Virtual Keyboard will open when any such element will get focus, and it will close when element will lose focus. Not only that, but TabTipAutomation will move UIElement (or Window) into view, so that TabTip will not block focused element.

您可以将 TabTip 自动化逻辑绑定到任何 UIElement。当任何此类元素获得焦点时,虚拟键盘将打开,当元素失去焦点时它将关闭。不仅如此,TabTipAutomation 还会将 UIElement(或 Window)移动到视图中,以便 TabTip 不会阻塞焦点元素。

For more info refer to the project site.

有关更多信息,请参阅项目站点

回答by Dmitry Lyalin

I am not sure how to hidethe keyboard programmatically, but just as you know I just recently published a sample on how to trigger (as-in, show) the touch keyboard in WPF applications when a user clicks into a Textbox, its here:

我不确定如何以编程方式隐藏键盘,但正如您所知,我最近发布了一个示例,内容涉及当用户单击文本框时如何在 WPF 应用程序中触发(原样显示)触摸键盘,它在这里:

http://code.msdn.microsoft.com/Enabling-Windows-8-Touch-7fb4e6de

http://code.msdn.microsoft.com/Enabling-Windows-8-Touch-7fb4e6de

The cool thing about this sample, as it doesn't require the use of Process and instead uses supported Windows 8 API to trigger the touch keyboard for TextBox controls using automation.

这个示例很酷,因为它不需要使用 Process,而是使用受支持的 Windows 8 API 来使用自动化触发 TextBox 控件的触摸键盘。

It has been something I've been working on for many months, i'm glad to finally contribute this example to our community. Please let me know if there are any questions, suggestions, problems, etc in the sample Q&A pane

这是我几个月以来一直在努力的事情,我很高兴最终将这个例子贡献给我们的社区。如果示例问答窗格中有任何问题、建议、问题等,请告诉我

回答by Kapitán Mlíko

Well I would try something like this

好吧,我会尝试这样的事情

Process myProcess = Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");
myProcess.CloseMainWindow();
myProcess.Close();

回答by Amirhossein Yari

try this one

试试这个

System.Diagnostics.Process.Start("TabTip.exe");

I hope this will help you.

我希望这能帮到您。

回答by pogosama

Maybe you can try the solution published on this blog: http://mheironimus.blogspot.nl/2015/05/adding-touch-keyboard-support-to-wpf.html

也许您可以尝试在此博客上发布的解决方案:http: //mheironimus.blogspot.nl/2015/05/adding-touch-keyboard-support-to-wpf.html

It contains some of the things you asked for (and more):

它包含您要求的一些内容(以及更多内容):

  • Show and hide keyboard
  • Move focus using FrameworkElement.BringIntoView ()
  • FrameworkElement.InputScopeproperty to choose which keyboard layout to show (numeric, email, url, etc)
  • 显示和隐藏键盘
  • 使用移动焦点 FrameworkElement.BringIntoView ()
  • FrameworkElement.InputScope选择要显示的键盘布局的属性(数字、电子邮件、网址等)

回答by jporcenaluk

This should work to open, then kill the process.

这应该可以打开,然后终止进程。

Process proc = Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");
proc.Kill();

Killing the process will close it.

杀死进程将关闭它。

If you debug and step through these two lines, however, the same error you mentioned above occurs - "Process has exited, so the request information is not available."

但是,如果您调试并单步执行这两行,则会出现您上面提到的相同错误 - “进程已退出,因此请求信息不可用。”

If you aren'tstepping through these two lines while debugging, no exception is thrown and the on-screen keyboard will be killed.

如果你通过调试时这两条线步进,则不会抛出异常和屏幕键盘会被杀死。

If you use CloseMainWindow()the keyboard will not close. CloseMainWindow()is for processes with a UI, so you would think it would be effective on this, but perhaps because the keyboard is part of the OS it doesn't count.

如果使用CloseMainWindow()键盘不会关闭。CloseMainWindow()用于具有 UI 的进程,因此您会认为它对此有效,但也许因为键盘是操作系统的一部分,所以它不算数。

Confirm that it works, then throw the proc.Kill()in a try-catch with error logging for peace of mind.

确认它有效,然后将其proc.Kill()放入带有错误日志的 try-catch 中,让您高枕无忧。