Browse Source

Simplify IME integration a bit

pull/28/head
Daniel Grunwald 13 years ago
parent
commit
827dbee0d4
  1. 4
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/Caret.cs
  2. 11
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/ImeNativeWrapper.cs
  3. 43
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/ImeSupport.cs
  4. 6
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs

4
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/Caret.cs

@ -22,7 +22,6 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -22,7 +22,6 @@ namespace ICSharpCode.AvalonEdit.Editing
{
readonly TextArea textArea;
readonly TextView textView;
readonly ImeSupport ime;
readonly CaretLayer caretAdorner;
bool visible;
@ -31,7 +30,6 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -31,7 +30,6 @@ namespace ICSharpCode.AvalonEdit.Editing
this.textArea = textArea;
this.textView = textArea.TextView;
position = new TextViewPosition(1, 1, 0);
ime = new ImeSupport(textArea);
caretAdorner = new CaretLayer(textView);
textView.InsertLayer(caretAdorner, KnownLayer.Caret, LayerInsertionPosition.Replace);
@ -436,7 +434,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -436,7 +434,7 @@ namespace ICSharpCode.AvalonEdit.Editing
} else {
caretAdorner.Hide();
}
ime.UpdateCompositionWindow();
textArea.ime.UpdateCompositionWindow();
}
}

11
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/ImeNativeWrapper.cs

@ -76,16 +76,23 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -76,16 +76,23 @@ 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")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ImmDestroyContext(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")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ImmNotifyIME(IntPtr hIMC, int dwAction, int dwIndex, int dwValue = 0);
static extern bool ImmReleaseContext(IntPtr hWnd, IntPtr hIMC);
[DllImport("imm32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ImmReleaseContext(IntPtr hWnd, IntPtr hIMC);
static extern bool ImmNotifyIME(IntPtr hIMC, int dwAction, int dwIndex, int dwValue = 0);
[DllImport("imm32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ImmSetCompositionWindow(IntPtr hIMC, ref CompositionForm form);

43
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/ImeSupport.cs

@ -19,11 +19,10 @@ using ICSharpCode.AvalonEdit.Rendering; @@ -19,11 +19,10 @@ using ICSharpCode.AvalonEdit.Rendering;
namespace ICSharpCode.AvalonEdit.Editing
{
class ImeSupport : IDisposable
class ImeSupport
{
TextArea textArea;
readonly TextArea textArea;
IntPtr currentContext;
IntPtr previousContext;
HwndSource hwndSource;
public ImeSupport(TextArea textArea)
@ -32,47 +31,29 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -32,47 +31,29 @@ namespace ICSharpCode.AvalonEdit.Editing
throw new ArgumentNullException("textArea");
this.textArea = textArea;
InputMethod.SetIsInputMethodSuspended(this.textArea, true);
textArea.GotKeyboardFocus += TextAreaGotKeyboardFocus;
textArea.LostKeyboardFocus += TextAreaLostKeyboardFocus;
textArea.OptionChanged += TextAreaOptionChanged;
currentContext = IntPtr.Zero;
previousContext = IntPtr.Zero;
}
void TextAreaOptionChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "EnableImeSupport" && textArea.IsKeyboardFocusWithin) {
if (e.PropertyName == "EnableImeSupport" && textArea.IsKeyboardFocused) {
CreateContext();
}
}
public void Dispose()
{
if (textArea != null) {
textArea.GotKeyboardFocus -= TextAreaGotKeyboardFocus;
textArea.LostKeyboardFocus -= TextAreaLostKeyboardFocus;
textArea.OptionChanged -= TextAreaOptionChanged;
textArea = null;
}
ClearContext();
}
void ClearContext()
{
if (hwndSource != null) {
hwndSource.RemoveHook(WndProc);
ImeNativeWrapper.AssociateContext(hwndSource, previousContext);
previousContext = IntPtr.Zero;
ImeNativeWrapper.ReleaseContext(hwndSource, currentContext);
hwndSource = null;
currentContext = IntPtr.Zero;
hwndSource.RemoveHook(WndProc);
hwndSource = null;
}
}
void TextAreaGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
public void OnGotFocus(KeyboardFocusChangedEventArgs e)
{
if (e.OriginalSource != this.textArea)
return;
CreateContext();
}
@ -84,17 +65,15 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -84,17 +65,15 @@ namespace ICSharpCode.AvalonEdit.Editing
hwndSource = (HwndSource)PresentationSource.FromVisual(this.textArea);
if (hwndSource != null) {
currentContext = ImeNativeWrapper.GetContext(hwndSource);
previousContext = ImeNativeWrapper.AssociateContext(hwndSource, currentContext);
// ImeNativeWrapper.SetCompositionFont(hwndSource, currentContext, textArea);
hwndSource.AddHook(WndProc);
// UpdateCompositionWindow() will be called by the caret becoming visible
}
}
void TextAreaLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
public void OnLostFocus(KeyboardFocusChangedEventArgs e)
{
if (e.OriginalSource != this.textArea)
return;
if (currentContext != IntPtr.Zero)
if (e.OldFocus == textArea && currentContext != IntPtr.Zero)
ImeNativeWrapper.NotifyIme(currentContext);
ClearContext();
}
@ -103,6 +82,8 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -103,6 +82,8 @@ namespace ICSharpCode.AvalonEdit.Editing
{
switch (msg) {
case ImeNativeWrapper.WM_INPUTLANGCHANGE:
// Don't mark the message as handled; other windows
// might want to handle it as well.
ClearContext();
CreateContext();
break;
@ -115,7 +96,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -115,7 +96,7 @@ namespace ICSharpCode.AvalonEdit.Editing
public void UpdateCompositionWindow()
{
if (currentContext != IntPtr.Zero && textArea != null) {
if (currentContext != IntPtr.Zero) {
ImeNativeWrapper.SetCompositionWindow(hwndSource, currentContext, textArea);
}
}

6
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Editing/TextArea.cs

@ -29,6 +29,8 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -29,6 +29,8 @@ namespace ICSharpCode.AvalonEdit.Editing
/// </summary>
public class TextArea : Control, IScrollInfo, IWeakEventListener, ITextEditorComponent, IServiceProvider
{
internal readonly ImeSupport ime;
#region Constructor
static TextArea()
{
@ -68,6 +70,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -68,6 +70,7 @@ namespace ICSharpCode.AvalonEdit.Editing
caret = new Caret(this);
caret.PositionChanged += (sender, e) => RequestSelectionValidation();
ime = new ImeSupport(this);
leftMargins.CollectionChanged += leftMargins_CollectionChanged;
@ -754,6 +757,8 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -754,6 +757,8 @@ namespace ICSharpCode.AvalonEdit.Editing
protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
base.OnGotKeyboardFocus(e);
// First activate IME, then show caret
ime.OnGotFocus(e);
caret.Show();
}
@ -762,6 +767,7 @@ namespace ICSharpCode.AvalonEdit.Editing @@ -762,6 +767,7 @@ namespace ICSharpCode.AvalonEdit.Editing
{
base.OnLostKeyboardFocus(e);
caret.Hide();
ime.OnLostFocus(e);
}
#endregion

Loading…
Cancel
Save