2017-03-02 10 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

, 우리는 서비스로 실행 입력 방법 편집기 (IME)와 통신 할 Input Method Manager를 사용합니다. UWP에서는 텍스트 서비스 프레임 워크를 사용할 수 있어야합니다. Alternatives to Windows APIs in Universal Windows Platform (UWP) apps에 대한 문서가 있습니다.

우리는 Windows​.UI​.Text​.Core 네임 스페이스를 사용할 수 있어야하므로 Windows 핵심 텍스트 API 및 텍스트 입력 서버에 액세스하기위한 유형을 제공합니다. Windows 핵심 텍스트는 키보드 입력 처리를 단일 서버로 중앙 집중화하는 클라이언트 - 서버 시스템입니다.

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 내 대답은 문제를 해결 했습니까? 그렇지 않다면 세부 사항을 말해주십시오. –