簡體   English   中英

使用C#在通用Windows應用程序中未檢測到鍵盤布局更改

[英]Keyboard layout change not detected in universal windows apps with C#

我想檢測C#的每個鍵盤布局更改。 不論是通過win +空格鍵還是alt + shift鍵或鼠標鍵來切換……我寫的代碼都非常適合台式機應用程序(見下文)。 但這不適用於UWP應用。 如果我在UWP應用程序內切換布局,則不會檢測到該布局,如果我切換到桌面應用程序,則立即檢測到該更改...如何檢測布局中的任何更改? 還有什么其他方法可以找出在任何給定的時刻處於活動狀態的布局,無論哪個窗口處於活動狀態? 我的代碼:

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");
    }
}

}

在Desktop中,我們使用輸入法管理器與作為服務運行的輸入法編輯器(IME)進行通信。 在UWP中,我們應該能夠使用文本服務框架。 有一個有關通用Windows平台(UWP)應用程序中Windows API替代方法的文檔。

因此我們應該能夠使用Windows​.UI​.Text​.Core命名空間,它提供了用於訪問Windows核心文本API和文本輸入服務器的類型。 Windows核心文本是一個客戶端-服務器系統,可將鍵盤輸入的處理集中到單個服務器中。

我們可以在CoreTextServicesManager類中找到InputLanguageChanged事件。 當前輸入語言已更改時,會發生這種情況。 當我們通過win +空格或alt + shift或使用鼠標切換輸入法InputLanguageChanged將觸發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!");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM