diff options
author | Felipe Heidrich <fheidric> | 2007-08-22 21:10:42 +0000 |
---|---|---|
committer | Felipe Heidrich <fheidric> | 2007-08-22 21:10:42 +0000 |
commit | f295d81c96c5f0cad60547a25236d1a3bb649162 (patch) | |
tree | 5aa69be584dc0d2106f08fc873c9bafeaeba1bf2 | |
parent | deba00683b7e799ad97b05b6dcbb1d19c053de72 (diff) | |
download | eclipse.platform.swt-f295d81c96c5f0cad60547a25236d1a3bb649162.tar.gz eclipse.platform.swt-f295d81c96c5f0cad60547a25236d1a3bb649162.tar.xz eclipse.platform.swt-f295d81c96c5f0cad60547a25236d1a3bb649162.zip |
Bug 108591 - SWT StyledText does not support inline Input method
5 files changed, 480 insertions, 56 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java index d8f99d1aab..dd74d39278 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java @@ -611,7 +611,105 @@ public class SWT { */ public static final int PaintItem = 42; + /** + * The IME composition event type (value is 43). + * <p> + * The IME composition event is sent to allow + * custom text editors to implement in-line + * editing of international text. + * </p> + * + * The detail field indicates the action to be taken: + * <p><ul> + * <li>{@link SWT#COMPOSITION_CHANGED}</li> + * <li>{@link SWT#COMPOSITION_HITTEST}</li> + * </ul></p> + * + * @see org.eclipse.swt.widgets.Widget#addListener + * @see org.eclipse.swt.widgets.Display#addFilter + * @see org.eclipse.swt.widgets.Event + * + * @since 3.4 + */ + public static final int ImeComposition = 43; + /* Event Details */ + + /** + * The IME composition event detail that indicates + * a change in the IME composition. The text, ranges, + * and styles fields of the event define the appearance + * of the composition text. The index field of the event + * indicates the offset of the caret within the text. + * The wideCaret field indicates that the caret should + * be set to the width of the text (value is 1). + * + * @see SWT#ImeComposition + * + * @since 3.4 + */ + public static final int COMPOSITION_CHANGED = 1; + + /** + * The IME composition event detail that indicates + * that an IME hit test occurred. The x and y fields + * of the event are used by the application to set + * the hitTest, index and trailing fields of the event. + * + * The hitTest values are: + * <p><ul> + * <li>{@link SWT#HITTEST_OUTSIDE_TEXT}</li> + * <li>{@link SWT#HITTEST_INSIDE_TEXT}</li> + * <li>{@link SWT#HITTEST_INSIDE_COMPOSITION}</li> + * </ul></p> + * + * The index field of the event is the caret offset + * relative to the composition text. The trailing field + * is used to indicate that the hit test occurred in the + * leading edge (0) or trailing edge (1) of the character + * at index (value is 2). + * + * @see SWT#ImeComposition + * @see org.eclipse.swt.graphics.TextLayout#getOffset(int, int, int[]) + * + * @since 3.4 + */ + public static final int COMPOSITION_HITTEST = 2; + + /** + * Indicates that a hit test has occurred outside of + * the text (value is 1). + * + * @see SWT#COMPOSITION_HITTEST + * @see org.eclipse.swt.widgets.Event#hitTest + * + * @since 3.4 + */ + public static final int HITTEST_OUTSIDE_TEXT = 1; + + + /** + * Indicates that a hit test has occurred inside of + * the text (value is 2). + * + * @see SWT#COMPOSITION_HITTEST + * @see org.eclipse.swt.widgets.Event#hitTest + * + * @since 3.4 + */ + public static final int HITTEST_INSIDE_TEXT = 2; + + /** + * Indicates that a hit test has occurred inside of + * the IME composition text (value is 3). + * + * @see SWT#COMPOSITION_HITTEST + * @see org.eclipse.swt.widgets.Event#hitTest + * + * @since 3.4 + */ + public static final int HITTEST_INSIDE_COMPOSITION = 3; + /** * Indicates that a user-interface component is being dragged, @@ -1419,11 +1517,6 @@ public class SWT { */ public static final int UNDERLINE_ERROR = 2; - /* DO NOT USE - API UNDER CONSTRUCTION */ - public static final int UNDERLINE_IME_INPUT = 3; - public static final int UNDERLINE_IME_CONVERTED = 4; - public static final int UNDERLINE_IME_TARGET_CONVERTED = 5; - /** * Style constant for align top behavior (value is 1<<7, * since align UP and align TOP are considered the same). diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Event.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Event.java index c7759e5975..d9151f94a3 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Event.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Event.java @@ -173,6 +173,53 @@ public class Event { * be inserted or deleted. */ public String text; + + /** + * the ranges in the text where styles should be applied. + * + * @since 3.4 + */ + public int [] ranges; + + /** + * the styles for the text. + * + * @since 3.4 + */ + public TextStyle [] styles; + + /** + * the hitTest that indicates a part given a x and y location. + * + * @see org.eclipse.swt.SWT#COMPOSITION_HITTEST + * @see org.eclipse.swt.SWT#HITTEST_INSIDE_COMPOSITION + * @see org.eclipse.swt.SWT#HITTEST_INSIDE_TEXT + * @see org.eclipse.swt.SWT#HITTEST_OUTSIDE_TEXT + * + * @since 3.4 + */ + public int hitTest; + + /** + * the trailing specifies if the hit test occurred in the + * leading (0) or trailing edge (1) of the character. + * + * @see org.eclipse.swt.SWT#COMPOSITION_HITTEST + * @see org.eclipse.swt.graphics.TextLayout#getOffset(int, int, int[]) + * + * @since 3.4 + */ + public int trailing; + + /** + * this flag is set by the IME to indicate to the application that + * a wide caret should be use. + * + * @see org.eclipse.swt.SWT#COMPOSITION_CHANGED + * + * @since 3.4 + */ + public boolean wideCaret; /** * depending on the event, a flag indicating whether the operation diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java index d0fe9dc901..43cbe03790 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java @@ -59,6 +59,11 @@ public final class TextLayout extends Resource { OS.IIDFromString("{DCCFC162-2B38-11d2-B7EC-00C04F8F5D9A}\0".toCharArray(), IID_IMLangFontLink2); } + /* Caret has a copy of these constants */ + static final int UNDERLINE_IME_DOT = 1 << 16; + static final int UNDERLINE_IME_DASH = 2 << 16; + static final int UNDERLINE_IME_THICK = 3 << 16; + class StyleItem { TextStyle style; int start, length; @@ -901,8 +906,7 @@ void drawLines(boolean advance, int /*long*/ graphics, int x, int y, StyleItem r Gdip.Color_delete(gdiColor); } switch (style.underlineStyle) { - case SWT.UNDERLINE_ERROR: - case SWT.UNDERLINE_IME_INPUT: + case SWT.UNDERLINE_ERROR: { int squigglyThickness = 1; int squigglyHeight = 2 * squigglyThickness; int squigglyY = Math.min(underlineY, y + run.ascent + run.descent - squigglyHeight - 1); @@ -911,10 +915,7 @@ void drawLines(boolean advance, int /*long*/ graphics, int x, int y, StyleItem r Gdip.Graphics_DrawLines(graphics, pen, points, points.length / 2); Gdip.Pen_delete(pen); break; - case SWT.UNDERLINE_IME_TARGET_CONVERTED: - Gdip.Graphics_FillRectangle(graphics, brush, x - run.underlineThickness, underlineY, run.width, run.underlineThickness * 2); - break; - case SWT.UNDERLINE_IME_CONVERTED: + } case SWT.UNDERLINE_SINGLE: Gdip.Graphics_FillRectangle(graphics, brush, x, underlineY, run.width, run.underlineThickness); break; @@ -922,6 +923,18 @@ void drawLines(boolean advance, int /*long*/ graphics, int x, int y, StyleItem r Gdip.Graphics_FillRectangle(graphics, brush, x, underlineY, run.width, run.underlineThickness); Gdip.Graphics_FillRectangle(graphics, brush, x, underlineY + run.underlineThickness * 2, run.width, run.underlineThickness); break; + case UNDERLINE_IME_THICK: + Gdip.Graphics_FillRectangle(graphics, brush, x - run.underlineThickness, underlineY, run.width, run.underlineThickness * 2); + break; + case UNDERLINE_IME_DOT: + case UNDERLINE_IME_DASH: { + int /*long*/ pen = Gdip.Pen_new(brush, 1); + int dashStyle = style.underlineStyle == UNDERLINE_IME_DOT ? Gdip.DashStyleDot : Gdip.DashStyleDash; + Gdip.Pen_SetDashStyle(pen, dashStyle); + Gdip.Graphics_DrawLine(graphics, pen, x, underlineY, x + run.width, underlineY); + Gdip.Pen_delete(pen); + break; + } } if (brush != color) Gdip.SolidBrush_delete(brush); } @@ -948,8 +961,7 @@ void drawLines(boolean advance, int /*long*/ graphics, int x, int y, StyleItem r colorRefUnderline = style.underlineColor.handle; } switch (style.underlineStyle) { - case SWT.UNDERLINE_ERROR: - case SWT.UNDERLINE_IME_INPUT: + case SWT.UNDERLINE_ERROR: { int squigglyThickness = 1; int squigglyHeight = 2 * squigglyThickness; int squigglyY = Math.min(underlineY, y + run.ascent + run.descent - squigglyHeight - 1); @@ -970,17 +982,17 @@ void drawLines(boolean advance, int /*long*/ graphics, int x, int y, StyleItem r OS.SelectObject(graphics, oldPen); OS.DeleteObject(pen); break; - case SWT.UNDERLINE_IME_TARGET_CONVERTED: + } + case SWT.UNDERLINE_SINGLE: brushUnderline = OS.CreateSolidBrush(colorRefUnderline); - OS.SetRect(rect, x, underlineY - run.underlineThickness, x + run.width, underlineY + run.underlineThickness); + OS.SetRect(rect, x, underlineY, x + run.width, underlineY + run.underlineThickness); if (clipRect != null) { rect.left = Math.max(rect.left, clipRect.left); rect.right = Math.min(rect.right, clipRect.right); } OS.FillRect(graphics, rect, brushUnderline); break; - case SWT.UNDERLINE_IME_CONVERTED: - case SWT.UNDERLINE_SINGLE: + case SWT.UNDERLINE_DOUBLE: brushUnderline = OS.CreateSolidBrush(colorRefUnderline); OS.SetRect(rect, x, underlineY, x + run.width, underlineY + run.underlineThickness); if (clipRect != null) { @@ -988,22 +1000,39 @@ void drawLines(boolean advance, int /*long*/ graphics, int x, int y, StyleItem r rect.right = Math.min(rect.right, clipRect.right); } OS.FillRect(graphics, rect, brushUnderline); + OS.SetRect(rect, x, underlineY + run.underlineThickness * 2, x + run.width, underlineY + run.underlineThickness * 3); + if (clipRect != null) { + rect.left = Math.max(rect.left, clipRect.left); + rect.right = Math.min(rect.right, clipRect.right); + } + OS.FillRect(graphics, rect, brushUnderline); break; - case SWT.UNDERLINE_DOUBLE: + case UNDERLINE_IME_THICK: brushUnderline = OS.CreateSolidBrush(colorRefUnderline); - OS.SetRect(rect, x, underlineY, x + run.width, underlineY + run.underlineThickness); + OS.SetRect(rect, x, underlineY - run.underlineThickness, x + run.width, underlineY + run.underlineThickness); if (clipRect != null) { rect.left = Math.max(rect.left, clipRect.left); rect.right = Math.min(rect.right, clipRect.right); } OS.FillRect(graphics, rect, brushUnderline); - OS.SetRect(rect, x, underlineY + run.underlineThickness * 2, x + run.width, underlineY + run.underlineThickness * 3); + break; + case UNDERLINE_IME_DASH: + case UNDERLINE_IME_DOT: { + underlineY = y + run.ascent + run.descent; + int penStyle = style.underlineStyle == UNDERLINE_IME_DASH ? OS.PS_DASH : OS.PS_DOT; + int /*long*/ pen = OS.CreatePen(penStyle, 1, colorRefUnderline); + int /*long*/ oldPen = OS.SelectObject(graphics, pen); + OS.SetRect(rect, x, underlineY, x + run.width, underlineY + run.underlineThickness); if (clipRect != null) { rect.left = Math.max(rect.left, clipRect.left); rect.right = Math.min(rect.right, clipRect.right); } - OS.FillRect(graphics, rect, brushUnderline); + OS.MoveToEx(graphics, rect.left, rect.top, 0); + OS.LineTo(graphics, rect.right, rect.top); + OS.SelectObject(graphics, oldPen); + OS.DeleteObject(pen); break; + } } } if (style.strikeout) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java index 20f61fa6a6..830363a90d 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java @@ -38,6 +38,24 @@ import org.eclipse.swt.graphics.*; public class Canvas extends Composite { Caret caret; + static final int WM_MSIME_MOUSE = OS.RegisterWindowMessage (new TCHAR (0, "MSIMEMouseOperation", true)); + + static final byte [] IID_ITfInputProcessorProfiles = new byte [16]; + static final byte [] IID_ITfDisplayAttributeProvider = new byte [16]; + static final byte [] CLSID_TF_InputProcessorProfiles = new byte [16]; + static final byte [] GUID_TFCAT_TIP_KEYBOARD = new byte [16]; + static { + OS.IIDFromString ("{1F02B6C5-7842-4EE6-8A0B-9A24183A95CA}\0".toCharArray (), IID_ITfInputProcessorProfiles); + OS.IIDFromString ("{fee47777-163c-4769-996a-6e9c50ad8f54}\0".toCharArray (), IID_ITfDisplayAttributeProvider); + OS.IIDFromString ("{33C53A50-F456-4884-B049-85FD643ECFED}\0".toCharArray (), CLSID_TF_InputProcessorProfiles); + OS.IIDFromString ("{34745C63-B2F0-4784-8B67-5E12C8701A31}\0".toCharArray (), GUID_TFCAT_TIP_KEYBOARD); + } + + /* TextLayout has a copy of these constants */ + static final int UNDERLINE_IME_DOT = 1 << 16; + static final int UNDERLINE_IME_DASH = 2 << 16; + static final int UNDERLINE_IME_THICK = 3 << 16; + /** * Prevents uninitialized instances from being created outside the package. */ @@ -109,6 +127,49 @@ public Caret getCaret () { return caret; } +TF_DISPLAYATTRIBUTE getDisplayAttribute (short langid, int attInfo) { + int /*long*/ [] pProfiles = new int /*long*/ [1]; + int hr = OS.CoCreateInstance (CLSID_TF_InputProcessorProfiles, 0, OS.CLSCTX_INPROC_SERVER, IID_ITfInputProcessorProfiles, pProfiles); + TF_DISPLAYATTRIBUTE pda = null; + if (hr == OS.S_OK) { + byte [] pclsid = new byte [16]; + byte [] pguidProfile = new byte [16]; + /* pProfiles.GetDefaultLanguageProfile () */ + hr = OS.VtblCall (8, pProfiles [0], langid, GUID_TFCAT_TIP_KEYBOARD, pclsid, pguidProfile); + if (hr == OS.S_OK) { + int /*long*/ [] pProvider = new int /*long*/ [1]; + hr = OS.CoCreateInstance (pclsid, 0, OS.CLSCTX_INPROC_SERVER, IID_ITfDisplayAttributeProvider, pProvider); + if (hr == OS.S_OK) { + int /*long*/ [] pEnum = new int /*long*/ [1]; + /* pProvider.EnumDisplayAttributeInfo () */ + hr = OS.VtblCall (3, pProvider [0], pEnum); + if (hr == OS.S_OK) { + int /*long*/ [] pDispInfo = new int /*long*/ [1]; + TF_DISPLAYATTRIBUTE tempPda = new TF_DISPLAYATTRIBUTE (); + /* pEnum.Next () */ + while ((hr = OS.VtblCall (4, pEnum [0], 1, pDispInfo, null)) == OS.S_OK) { + /* pDispInfo.GetAttributeInfo(); */ + OS.VtblCall (5, pDispInfo [0], tempPda); + /* pDispInfo.Release () */ + OS.VtblCall (2, pDispInfo [0]); + if (tempPda.bAttr == attInfo) { + pda = tempPda; + break; + } + } + /* pEnum.Release () */ + hr = OS.VtblCall (2, pEnum [0]); + } + /* pProvider.Release () */ + hr = OS.VtblCall (2, pProvider [0]); + } + } + /* pProfiles.Release () */ + hr = OS.VtblCall (2, pProfiles [0]); + } + return pda; +} + void releaseChildren (boolean destroy) { if (caret != null) { caret.release (false); @@ -292,34 +353,182 @@ int /*long*/ windowProc (int /*long*/ hwnd, int msg, int /*long*/ wParam, int /* } LRESULT WM_IME_COMPOSITION (int /*long*/ wParam, int /*long*/ lParam) { - LRESULT result = super.WM_IME_COMPOSITION (wParam, lParam); - /* - * Bug in Windows. On Korean Windows XP, the IME window - * for the Korean Input System (MS-IME 2002) always opens - * in the top left corner of the screen, despite the fact - * that ImmSetCompositionWindow() was called to position - * the IME when focus is gained. The fix is to position - * the IME on every WM_IME_COMPOSITION message. - */ - if (!OS.IsWinCE && OS.WIN32_VERSION == OS.VERSION (5, 1)) { - if (OS.IsDBLocale) { - short langID = OS.GetSystemDefaultUILanguage (); - short primaryLang = OS.PRIMARYLANGID (langID); - if (primaryLang == OS.LANG_KOREAN) { - if (caret != null && caret.isFocusCaret ()) { - POINT ptCurrentPos = new POINT (); - if (OS.GetCaretPos (ptCurrentPos)) { - COMPOSITIONFORM lpCompForm = new COMPOSITIONFORM (); - lpCompForm.dwStyle = OS.CFS_POINT; - lpCompForm.x = ptCurrentPos.x; - lpCompForm.y = ptCurrentPos.y; - int /*long*/ hIMC = OS.ImmGetContext (handle); - OS.ImmSetCompositionWindow (hIMC, lpCompForm); - OS.ImmReleaseContext (handle, hIMC); + LRESULT result = super.WM_IME_COMPOSITION (wParam, lParam); + if (OS.IsDBLocale && hooks (SWT.ImeComposition)) { + int /*long*/ hIMC = OS.ImmGetContext (handle); + if (hIMC != 0) { + TCHAR buffer = null; + if ((lParam & OS.GCS_RESULTSTR) != 0) { + int length = OS.ImmGetCompositionString (hIMC, OS.GCS_RESULTSTR, null, 0); + if (length > 0) { + buffer = new TCHAR (getCodePage (), length / TCHAR.sizeof); + OS.ImmGetCompositionString (hIMC, OS.GCS_RESULTSTR, buffer, length); + String text = buffer.toString (); + Event event = new Event (); + event.detail = SWT.COMPOSITION_CHANGED; + event.text = text; + event.count = text.length (); + sendEvent (SWT.ImeComposition, event); + if (event.doit) { + Display display = this.display; + display.lastKey = 0; + display.lastVirtual = display.lastNull = display.lastDead = false; + length = text.length (); + for (int i = 0; i < length; i++) { + char c = text.charAt (i); + display.lastAscii = c; + event = new Event (); + event.character = c; + sendEvent (SWT.KeyDown, event); + } } } + if ((lParam & OS.GCS_COMPSTR) == 0) return LRESULT.ONE; } + + int index = 0; + int [] ranges = null; + TextStyle [] styles = null; + int /*long*/ layout = OS.GetKeyboardLayout (0); + short langID = (short)OS.LOWORD (layout); + if ((lParam & OS.GCS_COMPSTR) != 0) { + int length = OS.ImmGetCompositionString (hIMC, OS.GCS_COMPSTR, null, 0); + if (length > 0) { + buffer = new TCHAR (getCodePage (), length / TCHAR.sizeof); + OS.ImmGetCompositionString (hIMC, OS.GCS_COMPSTR, buffer, length); + if ((lParam & OS.GCS_CURSORPOS) != 0) { + index = OS.ImmGetCompositionString (hIMC, OS.GCS_CURSORPOS, null, 0); + } + int [] clauses = null; + if ((lParam & OS.GCS_COMPCLAUSE) != 0) { + length = OS.ImmGetCompositionStringW (hIMC, OS.GCS_COMPCLAUSE, (int [])null, 0); + if (length > 0) { + clauses = new int [length / 4]; + OS.ImmGetCompositionStringW (hIMC, OS.GCS_COMPCLAUSE, clauses, length); + } + } + if ((lParam & OS.GCS_COMPATTR) != 0 && clauses != null) { + length = OS.ImmGetCompositionStringA (hIMC, OS.GCS_COMPATTR, (byte [])null, 0); + if (length > 0) { + byte [] attrs = new byte [length]; + OS.ImmGetCompositionStringA (hIMC, OS.GCS_COMPATTR, attrs, length); + length = clauses.length - 1; + ranges = new int [length * 2]; + styles = new TextStyle [length]; + TF_DISPLAYATTRIBUTE attr = null; + TextStyle style = null; + for (int i = 0; i < length; i++) { + ranges [i * 2] = clauses [i]; + ranges [i * 2 + 1] = clauses [i + 1] - clauses [i]; + styles [i] = style = new TextStyle (); + attr = getDisplayAttribute (langID, attrs [clauses [i]]); + if (attr != null) { + switch (attr.crText.type) { + case OS.TF_CT_COLORREF: + style.foreground = Color.win32_new (display, attr.crText.cr); + break; + case OS.TF_CT_SYSCOLOR: + int colorRef = OS.GetSysColor (attr.crText.cr); + style.foreground = Color.win32_new (display, colorRef); + break; + } + switch (attr.crBk.type) { + case OS.TF_CT_COLORREF: + style.background = Color.win32_new (display, attr.crBk.cr); + break; + case OS.TF_CT_SYSCOLOR: + int colorRef = OS.GetSysColor (attr.crBk.cr); + style.background = Color.win32_new (display, colorRef); + break; + } + switch (attr.crLine.type) { + case OS.TF_CT_COLORREF: + style.underlineColor = Color.win32_new (display, attr.crLine.cr); + break; + case OS.TF_CT_SYSCOLOR: + int colorRef = OS.GetSysColor (attr.crLine.cr); + style.underlineColor = Color.win32_new (display, colorRef); + break; + } + style.underline = attr.lsStyle != OS.TF_LS_NONE; + switch (attr.lsStyle) { + case OS.TF_LS_SQUIGGLE: + style.underlineStyle = SWT.UNDERLINE_ERROR; + break; + case OS.TF_LS_DASH: + style.underlineStyle = UNDERLINE_IME_DASH; + break; + case OS.TF_LS_DOT: + style.underlineStyle = UNDERLINE_IME_DOT; + break; + case OS.TF_LS_SOLID: + style.underlineStyle = attr.fBoldLine ? UNDERLINE_IME_THICK : SWT.UNDERLINE_SINGLE; + break; + } + } + } + } + } + } + OS.ImmReleaseContext (handle, hIMC); + } + String text = buffer != null ? buffer.toString () : ""; + Event event = new Event (); + event.detail = SWT.COMPOSITION_CHANGED; + event.text = text; + event.index = index; + event.count = 0; + event.ranges = ranges; + event.styles = styles; + event.wideCaret = OS.PRIMARYLANGID (langID) == OS.LANG_KOREAN; + sendEvent (SWT.ImeComposition, event); } + return LRESULT.ONE; + } else { + /* + * Bug in Windows. On Korean Windows XP, the IME window + * for the Korean Input System (MS-IME 2002) always opens + * in the top left corner of the screen, despite the fact + * that ImmSetCompositionWindow() was called to position + * the IME when focus is gained. The fix is to position + * the IME on every WM_IME_COMPOSITION message. + */ + if (!OS.IsWinCE && OS.WIN32_VERSION == OS.VERSION (5, 1)) { + if (OS.IsDBLocale) { + short langID = OS.GetSystemDefaultUILanguage (); + short primaryLang = OS.PRIMARYLANGID (langID); + if (primaryLang == OS.LANG_KOREAN) { + if (caret != null && caret.isFocusCaret ()) { + POINT ptCurrentPos = new POINT (); + if (OS.GetCaretPos (ptCurrentPos)) { + COMPOSITIONFORM lpCompForm = new COMPOSITIONFORM (); + lpCompForm.dwStyle = OS.CFS_POINT; + lpCompForm.x = ptCurrentPos.x; + lpCompForm.y = ptCurrentPos.y; + int /*long*/ hIMC = OS.ImmGetContext (handle); + OS.ImmSetCompositionWindow (hIMC, lpCompForm); + OS.ImmReleaseContext (handle, hIMC); + } + } + } + } + } + } + return result; +} + +LRESULT WM_IME_COMPOSITION_START (int /*long*/ wParam, int /*long*/ lParam) { + LRESULT result = super.WM_IME_COMPOSITION_START (wParam, lParam); + if (OS.IsDBLocale && hooks (SWT.ImeComposition)) { + return LRESULT.ONE; + } + return result; +} + +LRESULT WM_IME_ENDCOMPOSITION (int /*long*/ wParam, int /*long*/ lParam) { + LRESULT result = super.WM_IME_ENDCOMPOSITION (wParam, lParam); + if (OS.IsDBLocale && hooks (SWT.ImeComposition)) { + return LRESULT.ONE; } return result; } @@ -334,11 +543,50 @@ LRESULT WM_INPUTLANGCHANGE (int /*long*/ wParam, int /*long*/ lParam) { } LRESULT WM_KILLFOCUS (int /*long*/ wParam, int /*long*/ lParam) { + if (OS.IsDBLocale && hooks (SWT.ImeComposition)) { + int hIMC = OS.ImmGetContext (handle); + if (hIMC != 0) { + if (OS.ImmGetOpenStatus (hIMC)) { + OS.ImmNotifyIME (hIMC, OS.NI_COMPOSITIONSTR, OS.CPS_COMPLETE, 0); + } + OS.ImmReleaseContext (handle, hIMC); + } + } LRESULT result = super.WM_KILLFOCUS (wParam, lParam); if (caret != null) caret.killFocus (); return result; } +LRESULT WM_LBUTTONDOWN (int /*long*/ wParam, int /*long*/ lParam) { + if (OS.IsDBLocale && hooks (SWT.ImeComposition)) { + int hIMC = OS.ImmGetContext (handle); + if (hIMC != 0) { + if (OS.ImmGetOpenStatus (hIMC)) { + int length = OS.ImmGetCompositionString (hIMC, OS.GCS_COMPSTR, null, 0); + if (length > 0) { + Event event = new Event (); + event.detail = SWT.COMPOSITION_HITTEST; + event.x = OS.GET_X_LPARAM (lParam); + event.y = OS.GET_Y_LPARAM (lParam); + sendEvent (SWT.ImeComposition, event); + if (event.hitTest == SWT.HITTEST_INSIDE_COMPOSITION) { + int imeWnd = OS.ImmGetDefaultIMEWnd (handle); + int action = OS.IMEMOUSE_LDOWN; + int offset = event.index + event.trailing; + int trailing = event.trailing > 0 ? 1 : 2; + int w = ((action & 0xFF) | (trailing & 0xFF) << 8) | ((offset & 0xFFFF) << 16); + OS.SendMessage (imeWnd, WM_MSIME_MOUSE, w, hIMC); + } else { + OS.ImmNotifyIME (hIMC, OS.NI_COMPOSITIONSTR, OS.CPS_COMPLETE, 0); + } + } + } + OS.ImmReleaseContext (handle, hIMC); + } + } + return super.WM_LBUTTONDOWN (wParam, lParam); +} + LRESULT WM_SETFOCUS (int /*long*/ wParam, int /*long*/ lParam) { LRESULT result = super.WM_SETFOCUS (wParam, lParam); if (caret != null) caret.setFocus (); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Caret.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Caret.java index 6698835877..ab572154c0 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Caret.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Caret.java @@ -263,18 +263,25 @@ void resizeIME () { POINT ptCurrentPos = new POINT (); if (!OS.GetCaretPos (ptCurrentPos)) return; int /*long*/ hwnd = parent.handle; - RECT rect = new RECT (); - OS.GetClientRect (hwnd, rect); - COMPOSITIONFORM lpCompForm = new COMPOSITIONFORM (); - lpCompForm.dwStyle = OS.CFS_RECT; - lpCompForm.x = ptCurrentPos.x; - lpCompForm.y = ptCurrentPos.y; - lpCompForm.left = rect.left; - lpCompForm.right = rect.right; - lpCompForm.top = rect.top; - lpCompForm.bottom = rect.bottom; int /*long*/ hIMC = OS.ImmGetContext (hwnd); - OS.ImmSetCompositionWindow (hIMC, lpCompForm); + if (parent.hooks (SWT.ImeComposition)) { + CANDIDATEFORM lpCandidate = new CANDIDATEFORM (); + lpCandidate.dwStyle = OS.CFS_CANDIDATEPOS; + lpCandidate.ptCurrentPos = ptCurrentPos; + OS.ImmSetCandidateWindow (hIMC, lpCandidate); + } else { + RECT rect = new RECT (); + OS.GetClientRect (hwnd, rect); + COMPOSITIONFORM lpCompForm = new COMPOSITIONFORM (); + lpCompForm.dwStyle = OS.CFS_RECT; + lpCompForm.x = ptCurrentPos.x; + lpCompForm.y = ptCurrentPos.y; + lpCompForm.left = rect.left; + lpCompForm.right = rect.right; + lpCompForm.top = rect.top; + lpCompForm.bottom = rect.bottom; + OS.ImmSetCompositionWindow (hIMC, lpCompForm); + } OS.ImmReleaseContext (hwnd, hIMC); } |