星期五, 十一月 14, 2008

Emacs-CVS的Win32版本输入太快丢失汉字

前天下载了最新的Source编译了一下Emacs-CVS发现Windows输入法部分的处理现在已经是接收的UNICODE的字符了,处理方法是对WM_IME_CHAR这个消息进行处理。不过在Emacs里用了一个标志ignore_ime_char来判断是否处理后续的WM_IME_CHAR消息。因为Windows默认的是为每个字符都生成一个WM_IME_CHAR消息,这个消息如果没有被程序处理,转入默认处理程序,就会变成两个WM_CHAR消息,分开传高字节和低字节。Emacs-CVS的WM_IME_CHAR的事件里调用了ImmGetCompositionString把整个输入都取出来了,所以必须要这个标志来跳过后续的WM_IME_CHAR消息。

这个标志在WM_IME_ENDCOMPOSITION消息被收到事回复的。也就是如果输入法没有发这个消息过来,比如我用日文输入法是,自动上词的时候就没有这个消息,所以标志没恢复,只要一直是自动上词就一直输入不了。

另一个问题是,光标跟随无法工作。
由于以前修改过Emacs的输入法部分,所以对Win32输入法的部分还是有点了解的。
所以对Emacs的输入法部分做了些修改再编译。改成监听WM_IME_COMPOSITION消息。
另外添加了光标跟随。
如果要完美的话,还应该添加字体设置,把光标处的字体信息传给输入法。这个以后有空再做吧。


Index: src/w32fns.c
===================================================================
RCS file: /sources/emacs/emacs/src/w32fns.c,v
retrieving revision 1.349
diff -U 3 -r1.349 w32fns.c
--- src/w32fns.c 30 Oct 2008 01:27:07 -0000 1.349
+++ src/w32fns.c 14 Nov 2008 01:40:32 -0000
@@ -255,6 +255,9 @@
typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags);
typedef BOOL (WINAPI * GetMonitorInfo_Proc)
(IN HMONITOR monitor, OUT struct MONITOR_INFO* info);
+typedef HWND (WINAPI * ImmReleaseContext_Proc) (IN HWND hWnd, IN HIMC himc);
+typedef HWND (WINAPI * ImmSetCompositionWindow_Proc)
+ (IN HIMC himc, IN LPCOMPOSITIONFORM compform);

TrackMouseEvent_Proc track_mouse_event_fn = NULL;
ClipboardSequence_Proc clipboard_sequence_fn = NULL;
@@ -262,11 +265,11 @@
ImmGetContext_Proc get_ime_context_fn = NULL;
MonitorFromPoint_Proc monitor_from_point_fn = NULL;
GetMonitorInfo_Proc get_monitor_info_fn = NULL;
+ImmReleaseContext_Proc release_ime_context_fn = NULL;
+ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL;

extern AppendMenuW_Proc unicode_append_menu;

-/* Flag to selectively ignore WM_IME_CHAR messages. */
-static int ignore_ime_char = 0;

/* W95 mousewheel handler */
unsigned int msh_mousewheel = 0;
@@ -3134,15 +3601,14 @@
}
break;

- case WM_IME_CHAR:
+ case WM_IME_COMPOSITION:
/* If we can't get the IME result as unicode, use default processing,
which will at least allow characters decodable in the system locale
get through. */
if (!get_composition_string_fn)
goto dflt;
-
- else if (!ignore_ime_char)
- {
+ if (lParam & GCS_RESULTSTR)
+ {
wchar_t * buffer;
int size, i;
W32Msg wmsg;
@@ -3159,14 +3625,47 @@
my_post_msg (&wmsg, hwnd, WM_UNICHAR, (WPARAM) buffer[i],
lParam);
}
- /* We output the whole string above, so ignore following ones
- until we are notified of the end of composition. */
- ignore_ime_char = 1;
+ release_ime_context_fn (hwnd, context);
}
+ else
+ {
+ goto dflt;
+ }
break;
-
+ case WM_IME_STARTCOMPOSITION:
+ if (!set_ime_composition_window_fn)
+ goto dflt;
+ HIMC context = get_ime_context_fn (hwnd);
+ if (!context)
+ {
+ break;
+ }
+ f = x_window_to_frame (dpyinfo, hwnd);
+ COMPOSITIONFORM compform;
+ struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
+ compform.dwStyle = CFS_RECT;
+ compform.ptCurrentPos.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
+
+ compform.ptCurrentPos.y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y);
+
+ compform.rcArea.left = (WINDOW_BOX_LEFT_EDGE_X (w)
+ + WINDOW_LEFT_MARGIN_WIDTH (w)
+ + WINDOW_LEFT_FRINGE_WIDTH (w));
+
+ compform.rcArea.top = (WINDOW_TOP_EDGE_Y (w)
+ + WINDOW_HEADER_LINE_HEIGHT (w));
+
+ compform.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w)
+ - WINDOW_RIGHT_MARGIN_WIDTH (w)
+ - WINDOW_RIGHT_FRINGE_WIDTH (w));
+
+ compform.rcArea.bottom = (WINDOW_BOTTOM_EDGE_Y (w)
+ - WINDOW_MODE_LINE_HEIGHT (w));
+ set_ime_composition_window_fn(context, &compform);
+ release_ime_context_fn (hwnd, context);
+
+ break;
case WM_IME_ENDCOMPOSITION:
- ignore_ime_char = 0;
goto dflt;

/* Simulate middle mouse button events when left and right buttons
@@ -7258,6 +7842,10 @@
GetProcAddress (imm32_lib, "ImmGetCompositionStringW");
get_ime_context_fn = (ImmGetContext_Proc)
GetProcAddress (imm32_lib, "ImmGetContext");
+ release_ime_context_fn = (ImmReleaseContext_Proc)
+ GetProcAddress (imm32_lib, "ImmReleaseContext");
+ set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc)
+ GetProcAddress (imm32_lib, "ImmSetCompositionWindow");
}
DEFVAR_INT ("w32-ansi-code-page",
&w32_ansi_code_page,
Index: src/w32term.c
===================================================================
RCS file: /sources/emacs/emacs/src/w32term.c,v
retrieving revision 1.308
diff -U 3 -r1.308 w32term.c
--- src/w32term.c 27 Oct 2008 22:20:27 -0000 1.308
+++ src/w32term.c 14 Nov 2008 01:43:34 -0000
@@ -33,6 +33,7 @@
#include
#include
#include
+#include

#include "charset.h"
#include "character.h"
@@ -5059,7 +5060,11 @@
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
HWND hwnd = FRAME_W32_WINDOW (f);
-
+ if (f == FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame)
+ {
+ PostMessage (hwnd,
+ WM_IME_STARTCOMPOSITION, 0, 0);
+ }
w32_system_caret_x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
w32_system_caret_y




没有评论:

发表评论