summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe Heidrich <fheidric>2007-08-22 21:10:42 +0000
committerFelipe Heidrich <fheidric>2007-08-22 21:10:42 +0000
commitf295d81c96c5f0cad60547a25236d1a3bb649162 (patch)
tree5aa69be584dc0d2106f08fc873c9bafeaeba1bf2
parentdeba00683b7e799ad97b05b6dcbb1d19c053de72 (diff)
downloadeclipse.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
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java103
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Event.java47
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java61
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Canvas.java296
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Caret.java29
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&lt;&lt;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);
}