/// <summary> /// Save the state of the conversion and sentence mode for the current IME /// so that we can restore it later. /// </summary> private void SaveImeConversionStatus(WinKeyboardDescription winKeyboard) { if (winKeyboard == null) { return; } var windowHandle = new HandleRef(this, winKeyboard.WindowHandle != IntPtr.Zero ? winKeyboard.WindowHandle : Win32.GetFocus()); var contextPtr = Win32.ImmGetContext(windowHandle); if (contextPtr == IntPtr.Zero) { return; } var contextHandle = new HandleRef(this, contextPtr); int conversionMode; int sentenceMode; Win32.ImmGetConversionStatus(contextHandle, out conversionMode, out sentenceMode); winKeyboard.ConversionMode = conversionMode; winKeyboard.SentenceMode = sentenceMode; Win32.ImmReleaseContext(windowHandle, contextHandle); }
internal WinKeyboardDescription(WinKeyboardDescription other) : base(other) { ConversionMode = other.ConversionMode; SentenceMode = other.SentenceMode; WindowHandle = other.WindowHandle; InternalLocalizedName = other.InternalLocalizedName; InputProcessorProfile = other.InputProcessorProfile; InternalName = other.InternalName; Layout = other.Layout; Locale = other.Locale; }
private void SwitchKeyboard(WinKeyboardDescription winKeyboard) { if (m_fSwitchingKeyboards) { return; } m_fSwitchingKeyboards = true; try { ((IKeyboardControllerImpl)Keyboard.Controller).ActiveKeyboard = ActivateKeyboard(winKeyboard); if (Form.ActiveForm != null) { // If we activate a keyboard while a particular Form is active, we want to know about // input language change calls for that form. The previous -= may help make sure we // don't get multiple hookups. Form.ActiveForm.InputLanguageChanged -= ActiveFormOnInputLanguageChanged; Form.ActiveForm.InputLanguageChanged += ActiveFormOnInputLanguageChanged; } // If we have a TIP (TSF Input Processor) we don't have a handle. But we do the // keyboard switching through TSF so we don't need the workaround below. if (!UseWindowsApiForKeyboardSwitching(winKeyboard)) { return; } m_ExpectedKeyboard = winKeyboard; // The following lines help to work around a Windows bug (happens at least on // XP-SP3): When you set the current input language (by any method), if there is more // than one loaded input language associated with that same culture, Windows may // initially go along with your request, and even respond to an immediate query of // the current input language with the answer you expect. However, within a fraction // of a second, it often takes the initiative to again change the input language to // the _other_ input language having that same culture. We check that the proper // input language gets set by enabling a timer so that we can re-set the input // language if necessary. m_fSwitchedLanguages = true; // stop timer first so that the 0.5s interval restarts. m_Timer.Stop(); m_Timer.Start(); } finally { m_fSwitchingKeyboards = false; } }
private WinKeyboardDescription ActivateKeyboard(WinKeyboardDescription winKeyboard) { try { if (UseWindowsApiForKeyboardSwitching(winKeyboard)) { // Win XP with regular keyboard, or TSF disabled Win32.ActivateKeyboardLayout(new HandleRef(this, winKeyboard.InputLanguage.Handle), 0); return(winKeyboard); } var profile = winKeyboard.InputProcessorProfile; if ((profile.Flags & TfIppFlags.Enabled) == 0) { return(winKeyboard); } ProcessorProfiles.ChangeCurrentLanguage(profile.LangId); if (ProfileMgr == null) { // Win XP with TIP (TSF Input Processor) ProcessorProfiles.ActivateLanguageProfile(ref profile.ClsId, profile.LangId, ref profile.GuidProfile); } else { // Windows >= Vista with either TIP or regular keyboard ProfileMgr.ActivateProfile(profile.ProfileType, profile.LangId, ref profile.ClsId, ref profile.GuidProfile, profile.Hkl, TfIppMf.DontCareCurrentInputLanguage); } } catch (ArgumentException) { // throws exception for non-supported culture, though seems to set it OK. } catch (COMException e) { var profile = winKeyboard.InputProcessorProfile; var msg = string.Format("Got COM exception trying to activate IM:" + Environment.NewLine + "LangId={0}, clsId={1}, hkl={2}, guidProfile={3}, flags={4}, type={5}, catId={6}", profile.LangId, profile.ClsId, profile.Hkl, profile.GuidProfile, profile.Flags, profile.ProfileType, profile.CatId); throw new ApplicationException(msg, e); } return(winKeyboard); }
private void OnTimerTick(object sender, EventArgs eventArgs) { if (m_ExpectedKeyboard == null || !m_fSwitchedLanguages) { return; } if (InputLanguage.CurrentInputLanguage.Culture.KeyboardLayoutId == m_ExpectedKeyboard.InputLanguage.Culture.KeyboardLayoutId) { m_ExpectedKeyboard = null; m_fSwitchedLanguages = false; m_Timer.Enabled = false; return; } SwitchKeyboard(m_ExpectedKeyboard); }
private void OnTimerTick(object sender, EventArgs eventArgs) { if (m_ExpectedKeyboard == null || !m_fSwitchedLanguages) { return; } // This code gets only called if TSF is not available(e.g. Windows XP) if (InputLanguage.CurrentInputLanguage.Culture.KeyboardLayoutId == m_ExpectedKeyboard.InputLanguage.Culture.KeyboardLayoutId) { m_ExpectedKeyboard = null; m_fSwitchedLanguages = false; m_Timer.Enabled = false; return; } SwitchKeyboard(m_ExpectedKeyboard); }
private bool UseWindowsApiForKeyboardSwitching(WinKeyboardDescription winKeyboard) { return ProcessorProfiles == null || (ProfileMgr == null && winKeyboard.InputProcessorProfile.Hkl == IntPtr.Zero); }
private void SwitchKeyboard(WinKeyboardDescription winKeyboard) { if (m_fSwitchingKeyboards) return; m_fSwitchingKeyboards = true; try { ((IKeyboardControllerImpl)Keyboard.Controller).ActiveKeyboard = ActivateKeyboard(winKeyboard); if (Form.ActiveForm != null) { // If we activate a keyboard while a particular Form is active, we want to know about // input language change calls for that form. The previous -= may help make sure we // don't get multiple hookups. Form.ActiveForm.InputLanguageChanged -= ActiveFormOnInputLanguageChanged; Form.ActiveForm.InputLanguageChanged += ActiveFormOnInputLanguageChanged; } // If we have a TIP (TSF Input Processor) we don't have a handle. But we do the // keyboard switching through TSF so we don't need the workaround below. if (!UseWindowsApiForKeyboardSwitching(winKeyboard)) return; m_ExpectedKeyboard = winKeyboard; // The following lines help to work around a Windows bug (happens at least on // XP-SP3): When you set the current input language (by any method), if there is more // than one loaded input language associated with that same culture, Windows may // initially go along with your request, and even respond to an immediate query of // the current input language with the answer you expect. However, within a fraction // of a second, it often takes the initiative to again change the input language to // the _other_ input language having that same culture. We check that the proper // input language gets set by enabling a timer so that we can re-set the input // language if necessary. m_fSwitchedLanguages = true; // stop timer first so that the 0.5s interval restarts. m_Timer.Stop(); m_Timer.Start(); } finally { m_fSwitchingKeyboards = false; } }
/// <summary> /// Save the state of the conversion and sentence mode for the current IME /// so that we can restore it later. /// </summary> private void SaveImeConversionStatus(WinKeyboardDescription winKeyboard) { if (winKeyboard == null) return; var windowHandle = new HandleRef(this, winKeyboard.WindowHandle != IntPtr.Zero ? winKeyboard.WindowHandle : Win32.GetFocus()); var contextPtr = Win32.ImmGetContext(windowHandle); if (contextPtr == IntPtr.Zero) return; var contextHandle = new HandleRef(this, contextPtr); int conversionMode; int sentenceMode; Win32.ImmGetConversionStatus(contextHandle, out conversionMode, out sentenceMode); winKeyboard.ConversionMode = conversionMode; winKeyboard.SentenceMode = sentenceMode; Win32.ImmReleaseContext(windowHandle, contextHandle); }
private void OnTimerTick(object sender, EventArgs eventArgs) { if (m_ExpectedKeyboard == null || !m_fSwitchedLanguages) return; if (InputLanguage.CurrentInputLanguage.Culture.KeyboardLayoutId == m_ExpectedKeyboard.InputLanguage.Culture.KeyboardLayoutId) { m_ExpectedKeyboard = null; m_fSwitchedLanguages = false; m_Timer.Enabled = false; return; } SwitchKeyboard(m_ExpectedKeyboard); }
private WinKeyboardDescription ActivateKeyboard(WinKeyboardDescription winKeyboard) { try { if (UseWindowsApiForKeyboardSwitching(winKeyboard)) { // Win XP with regular keyboard, or TSF disabled Win32.ActivateKeyboardLayout(new HandleRef(this, winKeyboard.InputLanguage.Handle), 0); return winKeyboard; } var profile = winKeyboard.InputProcessorProfile; if ((profile.Flags & TfIppFlags.Enabled) == 0) return winKeyboard; ProcessorProfiles.ChangeCurrentLanguage(profile.LangId); if (ProfileMgr == null) { // Win XP with TIP (TSF Input Processor) ProcessorProfiles.ActivateLanguageProfile(ref profile.ClsId, profile.LangId, ref profile.GuidProfile); } else { // Windows >= Vista with either TIP or regular keyboard ProfileMgr.ActivateProfile(profile.ProfileType, profile.LangId, ref profile.ClsId, ref profile.GuidProfile, profile.Hkl, TfIppMf.DontCareCurrentInputLanguage); } } catch (ArgumentException) { // throws exception for non-supported culture, though seems to set it OK. } catch (COMException e) { var profile = winKeyboard.InputProcessorProfile; var msg = string.Format("Got COM exception trying to activate IM:" + Environment.NewLine + "LangId={0}, clsId={1}, hkl={2}, guidProfile={3}, flags={4}, type={5}, catId={6}", profile.LangId, profile.ClsId, profile.Hkl, profile.GuidProfile, profile.Flags, profile.ProfileType, profile.CatId); throw new ApplicationException(msg, e); } return winKeyboard; }
private bool UseWindowsApiForKeyboardSwitching(WinKeyboardDescription winKeyboard) { return(ProcessorProfiles == null || (ProfileMgr == null && winKeyboard.InputProcessorProfile.Hkl == IntPtr.Zero)); }
private void OnTimerTick(object sender, EventArgs eventArgs) { if (m_ExpectedKeyboard == null || !m_fSwitchedLanguages) return; // This code gets only called if TSF is not available(e.g. Windows XP) if (InputLanguage.CurrentInputLanguage.Culture.KeyboardLayoutId == m_ExpectedKeyboard.InputLanguage.Culture.KeyboardLayoutId) { m_ExpectedKeyboard = null; m_fSwitchedLanguages = false; m_Timer.Enabled = false; return; } SwitchKeyboard(m_ExpectedKeyboard); }