summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhobbs <hobbs>2002-04-05 08:40:35 (GMT)
committerhobbs <hobbs>2002-04-05 08:40:35 (GMT)
commit6f886ef6c778f6cc74c677cafddae7680fc5e548 (patch)
treec99e3693f4481749cc6ea1cda4d0361b4a94b736
parentacc53ab94b6dc11efc4949650f65a9b7e0252db4 (diff)
downloadtk-6f886ef6c778f6cc74c677cafddae7680fc5e548.zip
tk-6f886ef6c778f6cc74c677cafddae7680fc5e548.tar.gz
tk-6f886ef6c778f6cc74c677cafddae7680fc5e548.tar.bz2
* win/tkWinX.c: added Tk_SetCaretPos code to position IME windows
correctly when WM_IME_STARTCOMPOSITION is received.
-rw-r--r--win/tkWinX.c88
1 files changed, 87 insertions, 1 deletions
diff --git a/win/tkWinX.c b/win/tkWinX.c
index 3fd0956..14bfec6 100644
--- a/win/tkWinX.c
+++ b/win/tkWinX.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWinX.c,v 1.19 2002/03/07 02:08:32 mdejong Exp $
+ * RCS: @(#) $Id: tkWinX.c,v 1.20 2002/04/05 08:40:35 hobbs Exp $
*/
#include "tkWinInt.h"
@@ -608,6 +608,27 @@ TkWinChildProc(hwnd, message, wParam, lParam)
result = 1;
break;
+ case WM_IME_STARTCOMPOSITION: {
+ /*
+ * Position the IME composition window according the known
+ * cursor (caret) position.
+ */
+
+ HIMC hIMC;
+ POINT pt;
+ hIMC = ImmGetContext(hwnd);
+ if (hIMC && GetCaretPos(&pt)) {
+ COMPOSITIONFORM cform;
+
+ cform.dwStyle = CFS_POINT;
+ cform.ptCurrentPos = pt;
+ result = ImmSetCompositionWindow(hIMC, &cform);
+ } else {
+ result = DefWindowProc(hwnd, message, wParam, lParam);
+ }
+ break;
+ }
+
case WM_IME_COMPOSITION:
result = 0;
if (HandleIMEComposition(hwnd, lParam) == 0) {
@@ -1478,3 +1499,68 @@ TkWinUpdatingClipboard(int mode)
tsdPtr->updatingClipboard = mode;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_SetCaretPos --
+ *
+ * This enables correct movement of focus in the MS Magnifier, as well
+ * as allowing us to correctly position the IME Window. The following
+ * Win32 APIs are used to work with MS caret:
+ *
+ * CreateCaret DestroyCaret SetCaretPos GetCaretPos
+ *
+ * Only one instance of caret can be active at any time
+ * (e.g. DestroyCaret API does not take any argument such as handle).
+ * Since do-it-right approach requires to track the create/destroy
+ * caret status all the time in a global scope among windows (or
+ * widgets), we just implement this minimal setup to get the job done.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * Sets the global Windows caret position.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height)
+{
+ static HWND caretHWND = NULL;
+ Window win;
+ HWND hwnd;
+
+ /*
+ * We adjust to the toplevel to get the coords right, as setting
+ * the IME composition window is based on the toplevel hwnd, so
+ * ignore height.
+ */
+
+ while (!Tk_IsTopLevel(tkwin)) {
+ x += Tk_X(tkwin);
+ y += Tk_Y(tkwin);
+ tkwin = Tk_Parent(tkwin);
+ if (tkwin == NULL) {
+ return;
+ }
+ }
+
+ win = Tk_WindowId(tkwin);
+ if (win) {
+ hwnd = Tk_GetHWND(win);
+ if (hwnd != caretHWND) {
+ DestroyCaret();
+ if (CreateCaret(hwnd, NULL, 0, 0)) {
+ caretHWND = hwnd;
+ }
+ }
+
+ if (!SetCaretPos(x, y) && CreateCaret(hwnd, NULL, 0, 0)) {
+ caretHWND = hwnd;
+ SetCaretPos(x, y);
+ }
+ }
+}