【问题标题】:Show & hiding the Windows 8 on screen keyboard from WPF在 WPF 中显示和隐藏屏幕键盘上的 Windows 8
【发布时间】:2013-06-10 00:44:25
【问题描述】:

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

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

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

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

有人知道怎么做吗?

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

非常感谢

【问题讨论】:

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


    【解决方案1】:

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

    希望对你有所帮助。

    【讨论】:

      【解决方案2】:

      有点晚了,我将改进 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();
          }
      

      【讨论】:

        【解决方案3】:

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

        您可以在nuget 上获取它,然后您只需要在应用启动逻辑中进行简单配置即可:

        TabTipAutomation.BindTo<TextBox>();
        

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

        欲了解更多信息,请参阅project site

        【讨论】:

        【解决方案4】:

        我会尝试这样的事情

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

        【讨论】:

        • 感谢您的回复关于出现键盘时向上移动屏幕的任何想法
        • @user1131657 好吧,这太苛刻了……您不想这样做吗?应该有一些......例如看看WPF Touch Screen Keyboard......会有更多......而且它看起来比yopu正在尝试做的更好的解决方案。
        • Viktor,我一直在玩这个,我更喜欢使用内置的触摸屏键盘。为什么要重新发明轮子呢!我试过你的代码,但它不起作用。当 CloseMainWindow 行运行时,我收到以下错误:进程已退出,因此请求的信息不可用
        • 好吧...那我就帮不了你了。对不起。我发现的最后一件事是这个question 它被标记为win7,但它可以帮助你。 GL ;)
        • 这不起作用。 Tabtip 具有特殊行为,Windows 会将主实例回收到它自己启动的 TabTip。因此,您启动的实例是瞬态的,并且会立即消失。 Windows 将改为显示任何现有实例或根据需要启动新实例。 @tasasaki 的回答完美。
        【解决方案5】:

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

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

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

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

        【讨论】:

          【解决方案6】:

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

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

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

          【讨论】:

            【解决方案7】:

            试试这个

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

            希望对你有帮助。

            【讨论】:

              【解决方案8】:

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

              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 中,让您高枕无忧。

              【讨论】:

              • 正如另一条评论中指出的,tabtip 很特殊,所以这不起作用。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-11-22
              • 1970-01-01
              • 1970-01-01
              • 2014-01-23
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多