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 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;
        }
Example #7
0
		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);
		}