2017-03-02 33 views
0

我想用C#检测每个键盘布局更改。无论它是由win + space还是alt + shift还是鼠标来切换...... 我为桌面应用程序编写了一个运行良好的代码(见下文)。但它不适用于UWP应用程序。如果我在UWP应用程序内切换布局,则无法检测到,如果切换到桌面应用程序,立即检测到更改...我如何检测布局中的任何更改?有没有其他的方法可以找到在任何给定时刻哪个布局是活动的? 我的代码:使用C#在通用Windows应用程序中未检测到键盘布局更改#

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using Microsoft.Win32; 
using System.Runtime.InteropServices; 
using System.Globalization; 

namespace ConsoleApplication1 
{ 
class Program 
{ 
    static void Main(string[] args) 
    { 
     string lastLang = ""; 
     while (true) 
     { 
      string langSuffix = GetKeyboardLayoutIdAtTime(); 

      if (!langSuffix.Equals(lastLang)) 
      { 
       // do something 
       Console.WriteLine(getCurrentTimeStamp() + ": Changing '" + lastLang + "' to '" + langSuffix + "'."); 
       lastLang = langSuffix; 
      } 
      System.Threading.Thread.Sleep(1000); 

     } 

    } 


    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] 
    private static extern IntPtr GetForegroundWindow(); 

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] 
    private static extern int GetWindowThreadProcessId(IntPtr handleWindow, out int lpdwProcessID); 

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] 
    private static extern IntPtr GetKeyboardLayout(int WindowsThreadProcessID); 

    public static string GetKeyboardLayoutIdAtTime() 
    { 
     IntPtr hWnd = GetForegroundWindow(); 
     int lpdwProcessId; 
     InputLanguageCollection installedInputLanguages = InputLanguage.InstalledInputLanguages; 
     CultureInfo currentInputLanguage = null; 
     int WinThreadProcId = GetWindowThreadProcessId(hWnd, out lpdwProcessId); 

     IntPtr KeybLayout = GetKeyboardLayout(WinThreadProcId); 
     // this remain unchanged when I switch layouts in UWP 
     Console.WriteLine("KL IntPtr: " + KeybLayout); 

     for (int i = 0; i < installedInputLanguages.Count; i++) 
     { 
      if (KeybLayout == installedInputLanguages[i].Handle) currentInputLanguage = installedInputLanguages[i].Culture; 

     } 
     if(currentInputLanguage == null) 
     { 
      Console.WriteLine(getCurrentTimeStamp() + "current input language is null..."); 
     } 
     return currentInputLanguage.TwoLetterISOLanguageName; 
    } 

    private static string getCurrentTimeStamp() 
    { 
     return DateTime.Now.ToString("yyyyMMddHHmmssffff"); 
    } 
} 

}

回答

1

在桌面中,我们使用与Input Method Manager输入法编辑器(IME),其作为服务运行进行通信。在UWP中,我们应该能够使用文本服务框架。有关于Alternatives to Windows APIs in Universal Windows Platform (UWP) apps的文档。

所以,我们应该能够使用Windows​.UI​.Text​.Core命名空间,它为访问Windows内核API的文字和文字输入服务器提供的类型。 Windows核心文本是将键盘输入处理集中到单个服务器中的客户端 - 服务器系统。

我们可以发现在CoreTextServicesManagerInputLanguageChanged事件。它发生在当前输入语言改变时。当我们通过win + space或alt + shift或鼠标切换输入法时,InputLanguageChanged将被触发。

例如:

public MainPage() 
{ 
    this.InitializeComponent(); 
    CoreTextServicesManager textServiceManager = CoreTextServicesManager.GetForCurrentView(); 
    textServiceManager.InputLanguageChanged += TextServiceManager_InputLanguageChanged; 
} 

private void TextServiceManager_InputLanguageChanged(CoreTextServicesManager sender, object args) 
{ 
    Debug.WriteLine("Keyboard layout is changed!"); 
} 
+0

@stove难道我的回答解决了您的问题?如果没有,请告诉我细节。 –

相关问题