展示&从WPF隐藏Windows 8在屏幕键盘上

时间:2013-06-13 14:56:52

标签: wpf windows-8 touchscreen on-screen-keyboard

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

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

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

这样可以正常但我不知道如何再次隐藏键盘?

有人知道怎么做吗?

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

非常感谢

8 个答案:

答案 0 :(得分:16)

我可以使用以下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();
}

我希望这会对你有所帮助。

答案 1 :(得分:6)

有点晚了,当用户点击我的Windows 8平板电脑的WPF应用程序中的textBox时,我只是改进了tasaki示例,以完成我在setFocus / LostFocus事件中启用show / hide的完整功能。我希望这可以帮助那些有类似头痛的人,因为禁用InkHelper,如果你想用触摸事件滚动,它并不能很好地工作......

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

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

代码:

    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();
    }

答案 2 :(得分:1)

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

你可以在nuget上获得它,然后你需要的只是你的应用启动逻辑中的简单配置:

TabTipAutomation.BindTo<TextBox>();

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

有关详细信息,请参阅project site

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

我不确定如何以编程方式隐藏键盘,但正如您所知,我刚刚发布了一个关于如何在WPF应用程序中触发(as-in,show)触摸键盘的示例用户点击文本框,其位于:

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

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

这是我多年来一直在努力的事情,我很高兴最终为我们的社区贡献这个榜样。如果示例Q&amp; A窗格中有任何问题,建议,问题等,请告诉我们

答案 5 :(得分:0)

尝试这个

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

我希望这会对你有所帮助。

答案 6 :(得分:0)

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

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

  • 显示和隐藏键盘
  • 使用FrameworkElement.BringIntoView ()
  • 移动焦点
  • FrameworkElement.InputScope属性选择要显示的键盘布局(数字,电子邮件,网址等)

答案 7 :(得分:-1)

这应该可以打开,然后杀死进程。

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

杀死该过程将关闭它。

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

如果在调试时没有单步执行这两行,则不会抛出任何异常,并且屏幕键盘将被终止。

如果您使用CloseMainWindow(),键盘将无法关闭。 CloseMainWindow() is for processes with a UI,所以你会认为它会对此有效,但也许是因为键盘是操作系统的一部分,它不算数。

确认它有效,然后将proc.Kill()放入带有错误记录的try-catch中,以免安心。