即使在应用程序不集中的情况下,也会钩住/检测窗口语言的变化

本文关键字:检测 变化 语言 窗口 应用程序 集中 情况下 | 更新日期: 2023-09-27 18:28:14

即使我的应用程序不在焦点上,是否有方法检测windows/os语言是否发生了更改?
到目前为止,只有当应用程序专注于使用时,我才能实现我想要的目标

string language = "";
System.Windows.Input.InputLanguageManager.Current.InputLanguageChanged +=
new System.Windows.Input.InputLanguageEventHandler((sender, e) =>
{
    language = e.NewLanguage.DisplayName;
    MessageBox.Show(language);
});

但正如你所理解的,这并不是我想要的。。

我在考虑其他解决方案,比如挂接更改语言的键(例如alt+shift),但我无法知道当前使用的是什么语言,用户可以更改默认热键。。。

非常感谢你的帮助。

即使在应用程序不集中的情况下,也会钩住/检测窗口语言的变化

您面临的问题与WM_INPUTLANGCHANGE消息的工作方式有关。此消息由操作系统发送到程序,以便通知程序语言更改。但是,根据文档,此消息仅发送到"受影响的最顶层窗口"。这意味着您甚至可以调用本机方法GetKeyboardLayout(顺便说一句,它由InputLanguageManager使用),但如果应用程序未处于活动状态,GetKeyboard Layout将始终返回最后一种已知的、过时的语言。

考虑到这一点,使用@VDohnal指出的解决方案可能是一个好主意,即找到当前最顶层的窗口并读取其键盘布局。以下是如何在WPF应用程序中快速验证概念的方法。我使用了一个额外的线程,它会定期为它找到最顶层的窗口和现成的键盘布局。代码远非完美,但它很有效,可能会帮助你实现自己的解决方案。

public partial class MainWindow : Window
{
    [DllImport("user32.dll")]
    static extern IntPtr GetKeyboardLayout(uint idThread);
    [DllImport("user32.dll")]
    private static extern IntPtr GetForegroundWindow();
    [DllImport("user32.dll")]
    static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr processId);
    private CultureInfo _currentLanaguge;
    public MainWindow()
    {
        InitializeComponent();
        Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    HandleCurrentLanguage();
                    Thread.Sleep(500);
                }
            });
    }
    private static CultureInfo GetCurrentCulture()
    {
        var l = GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero));
        return new CultureInfo((short)l.ToInt64());
    }
    private void HandleCurrentLanguage()
    {
        var currentCulture = GetCurrentCulture();
        if (_currentLanaguge == null || _currentLanaguge.LCID != currentCulture.LCID)
        {
            _currentLanaguge = currentCulture;
            MessageBox.Show(_currentLanaguge.Name);
        }
    }
}