13

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

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

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

这很好用,但是我不知道如何再次隐藏键盘?

有人知道怎么做吗?

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

非常感谢

4

8 回答 8

19

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

我希望这能帮到您。

于 2014-03-14T04:46:29.253 回答
6

有点晚了,我将改进 tasaki 示例,以便在用户单击 Windows 8 平板电脑的 WPF 应用程序中的文本框时启用显示/隐藏 gotFocus/LostFocus 事件。我希望这对人们有所帮助有类似的头痛,因为如果你想用触摸事件滚动,禁用 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();
    }
于 2015-08-07T20:34:12.637 回答
3

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

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

TabTipAutomation.BindTo<TextBox>();

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

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

于 2016-08-24T07:36:04.727 回答
0

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

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

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

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

于 2013-12-13T19:34:54.803 回答
0

试试这个

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

我希望这能帮到您。

于 2015-02-21T14:37:10.343 回答
0

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

Process myProcess = Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");
myProcess.CloseMainWindow();
myProcess.Close();
于 2013-06-13T15:13:00.700 回答
0

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

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

  • 显示和隐藏键盘
  • 使用移动焦点FrameworkElement.BringIntoView ()
  • FrameworkElement.InputScope用于选择要显示的键盘布局的属性(数字、电子邮件、url 等)
于 2015-06-30T06:06:53.147 回答
-1

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

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

杀死进程将关闭它。

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

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

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

确认它可以工作,然后将其proc.Kill()放入带有错误日志记录的 try-catch 中,让您安心。

于 2013-12-03T18:36:58.903 回答