diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/ImeNativeWrapper.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/ImeNativeWrapper.cs index 36744269ac..9a32528095 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/ImeNativeWrapper.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/ImeNativeWrapper.cs @@ -76,15 +76,16 @@ namespace ICSharpCode.AvalonEdit.Editing public const int WM_IME_SETCONTEXT = 0x281; public const int WM_INPUTLANGCHANGE = 0x51; - [DllImport("imm32.dll")] - public static extern IntPtr ImmCreateContext(); +// [DllImport("imm32.dll")] +// public static extern IntPtr ImmCreateContext(); +// +// [DllImport("imm32.dll")] +// [return: MarshalAs(UnmanagedType.Bool)] +// public static extern bool ImmDestroyContext(IntPtr hIMC); - [DllImport("imm32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool ImmDestroyContext(IntPtr hIMC); +// [DllImport("imm32.dll")] +// public static extern IntPtr ImmAssociateContext(IntPtr hWnd, IntPtr hIMC); - [DllImport("imm32.dll")] - static extern IntPtr ImmAssociateContext(IntPtr hWnd, IntPtr hIMC); [DllImport("imm32.dll")] static extern IntPtr ImmGetContext(IntPtr hWnd); [DllImport("imm32.dll")] @@ -103,11 +104,19 @@ namespace ICSharpCode.AvalonEdit.Editing [return: MarshalAs(UnmanagedType.Bool)] static extern bool ImmGetCompositionFont(IntPtr hIMC, out LOGFONT font); - public static IntPtr AssociateContext(HwndSource source, IntPtr hIMC) + [DllImport("msctf.dll")] + static extern int TF_CreateThreadMgr(out ITfThreadMgr threadMgr); + + [ThreadStatic] static bool textFrameworkThreadMgrInitialized; + [ThreadStatic] static ITfThreadMgr textFrameworkThreadMgr; + + public static ITfThreadMgr GetTextFrameworkThreadManager() { - if (source == null) - throw new ArgumentNullException("source"); - return ImmAssociateContext(source.Handle, hIMC); + if (!textFrameworkThreadMgrInitialized) { + textFrameworkThreadMgrInitialized = true; + TF_CreateThreadMgr(out textFrameworkThreadMgr); + } + return textFrameworkThreadMgr; } public static bool NotifyIme(IntPtr hIMC) @@ -194,4 +203,20 @@ namespace ICSharpCode.AvalonEdit.Editing .TransformToDevice(source.RootVisual); // rect on HWND } } + + [ComImport, Guid("aa80e801-2021-11d2-93e0-0060b067b86e"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + interface ITfThreadMgr + { + void Activate(out int clientId); + void Deactivate(); + void CreateDocumentMgr(out object docMgr); + void EnumDocumentMgrs(out object enumDocMgrs); + void GetFocus(out object docMgr); + void SetFocus(object docMgr); + void AssociateFocus(IntPtr hwnd, object newDocMgr, out object prevDocMgr); + void IsThreadFocus([MarshalAs(UnmanagedType.Bool)] out bool isFocus); + void GetFunctionProvider(ref Guid classId, out object funcProvider); + void EnumFunctionProviders(out object enumProviders); + void GetGlobalCompartment(out object compartmentMgr); + } } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/ImeSupport.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/ImeSupport.cs index 4e6dc51af0..e6bf4f11ae 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/ImeSupport.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/ImeSupport.cs @@ -23,7 +23,7 @@ namespace ICSharpCode.AvalonEdit.Editing { readonly TextArea textArea; IntPtr currentContext; - IntPtr previousContext; + //IntPtr previousContext; HwndSource hwndSource; public ImeSupport(TextArea textArea) @@ -46,8 +46,9 @@ namespace ICSharpCode.AvalonEdit.Editing void ClearContext() { if (hwndSource != null) { - ImeNativeWrapper.AssociateContext(hwndSource, previousContext); - ImeNativeWrapper.ImmDestroyContext(currentContext); + //ImeNativeWrapper.AssociateContext(hwndSource, previousContext); + //ImeNativeWrapper.ImmDestroyContext(currentContext); + ImeNativeWrapper.ReleaseContext(hwndSource, currentContext); currentContext = IntPtr.Zero; hwndSource.RemoveHook(WndProc); hwndSource = null; @@ -66,11 +67,19 @@ namespace ICSharpCode.AvalonEdit.Editing return; hwndSource = (HwndSource)PresentationSource.FromVisual(this.textArea); if (hwndSource != null) { - currentContext = ImeNativeWrapper.ImmCreateContext(); - previousContext = ImeNativeWrapper.AssociateContext(hwndSource, currentContext); + //currentContext = ImeNativeWrapper.ImmCreateContext(); + //previousContext = ImeNativeWrapper.AssociateContext(hwndSource, currentContext); + currentContext = ImeNativeWrapper.GetContext(hwndSource); // ImeNativeWrapper.SetCompositionFont(hwndSource, currentContext, textArea); 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(null); + } } }