2017-03-02 15 views
0

C#ですべてのキーボードレイアウトの変更を検出する必要があります。 win + spaceかalt + shiftかマウスで切り替えるかどうかは関係ありません... 私はデスクトップアプリケーションのためにかなりうまくいく(下記参照)コードを書いています。しかし、UWPアプリでは機能しません。 UWPアプリケーション内でレイアウトを切り替えると、検出されません。デスクトップアプリケーションに切り替えると、すぐに変更が検出されます...レイアウトの変更を検出するにはどうすればよいですか?どのウィンドウがアクティブであっても、どの瞬間にどのレイアウトがアクティブであるかを調べる方法はありますか? マイコード:ユニバーサルウィンドウでC#でキーボードレイアウトの変更が検出されない

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

、我々はサービスとして実行インプットメソッドエディタ(IME)と通信するInput Method Managerを使用します。 UWPでは、テキストサービスフレームワークを使用できるはずです。 Alternatives to Windows APIs in Universal Windows Platform (UWP) appsに関する文書があります。

Windows​.UI​.Text​.Core名前空間を使用できるように、WindowsコアテキストAPIとテキスト入力サーバーにアクセスするための型が用意されています。 Windowsコアテキストは、キーボード入力の処理を1つのサーバーに集約するクライアント/サーバーシステムです。

InputLanguageChangedイベントはCoreTextServicesManagerクラスにあります。現在の入力言語が変更されたときに発生します。入力メソッドを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は、私の答えはあなたの問題を解決しましたか?そうでない場合は、詳細を教えてください。 –

関連する問題