void CreateContext() { hwndSource = (HwndSource)PresentationSource.FromVisual(this.textArea); if (hwndSource != null) { if (isReadOnly) { defaultImeWnd = IntPtr.Zero; currentContext = IntPtr.Zero; } else { defaultImeWnd = ImeNativeWrapper.ImmGetDefaultIMEWnd(IntPtr.Zero); currentContext = ImeNativeWrapper.ImmGetContext(defaultImeWnd); } previousContext = ImeNativeWrapper.ImmAssociateContext(hwndSource.Handle, currentContext); hwndSource.AddHook(WndProc); // UpdateCompositionWindow() will be called by the caret becoming visible var threadMgr = ImeNativeWrapper.GetTextFrameworkThreadManager(); if (threadMgr != null) { // Even though the docu says passing null is invalid, this seems to help // activating the IME on the default input context that is shared with WPF threadMgr.SetFocus(IntPtr.Zero); } } }
public void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e) { if (e.OldFocus == textArea && currentContext != IntPtr.Zero) { ImeNativeWrapper.NotifyIme(currentContext); } ClearContext(); }
public void UpdateCompositionWindow() { if (currentContext != IntPtr.Zero) { ImeNativeWrapper.SetCompositionFont(hwndSource, currentContext, textArea); ImeNativeWrapper.SetCompositionWindow(hwndSource, currentContext, textArea); } }
void ClearContext() { if (hwndSource != null) { ImeNativeWrapper.ImmAssociateContext(hwndSource.Handle, previousContext); ImeNativeWrapper.ImmReleaseContext(defaultImeWnd, currentContext); currentContext = IntPtr.Zero; defaultImeWnd = IntPtr.Zero; hwndSource.RemoveHook(WndProc); hwndSource = null; } }