即使应用程序没有聚焦,钩子/检测窗口语言也会改变

有没有办法检测即使我的应用程序不在焦点时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使用)但如果应用程序不活动, GetKeyboardLayout将始终返回上一个已知的,过时的语言。

考虑到这一点,使用@VDohnal指向的解决方案可能是一个好主意,即找到当前最顶层的窗口并读取它的键盘布局。 以下是如何在WPF应用程序中执行此操作的概念的快速certificate。 我使用了一个额外的线程,它定期找到最顶层的窗口和准备好的键盘布局。 代码远非完美,但它可以工作,它可以帮助您实现自己的解决方案。

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