2017-03-02 93 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難道我的回答解決了您的問題?如果沒有,請告訴我細節。 –

相關問題