C# 自定义文本编辑器控件中 中文重复出现问题

毕设时做的一个代码编辑器,基于开源项目Fireball(http://www.codeplex.com/dotnetfireball)。在其中实现了语法加亮,括号匹配等通用代码编辑器的基础上,添加了基于DLL文件的智能提示功能。不过随后发现当输入中文的时候,在代码编辑器中会重复出现输入的中文。

最近,当时的老师让修改一下这个bug,追踪代码中的事件处理,发现当输入中文的时候有两个事件WM_IME_CHAR 和 WM_CHAR 的参数中都有输入的中文字符,并且每个事件都触发了OnKeyPress事件。而正是在OnKeyPress中将该事件中的字符显示在屏幕上。

本来想直接忽略WM_IME_CHAR事件,可是好像它对后续的WM_CHAR事件有影响,导致所有字符都不显示。由于输入英文的时候只有WM_CHAR事件,因此不能忽略该事件。

鉴于此,最后采用开关标记的方法来实现。在WndProc函数中根据事件来修改开关标记。在OnKeyPress中根据开关标记来决定是否输出。

Source Code:http://www.rayfile.com/files/f3b887e3-c1fa-11dd-a3aa-0014221b798a/

Original Report:http://www.rayfile.com/files/fd19b8cf-c1fa-11dd-aa67-0019d11a795f/

Problem Statement:

When user inputs Chinese characters using the input method editor, the phrases user inputs always are displayed twice. However, when using English, there is no problem.

Analysis:

Tracing the event raised while the user keys in characters, we can find that when using IME (Input Method Editor), there are two kinds of events which contain the inputted characters – WM_IME_CHAR and WM_CHAR.

For character ‘中’:

msg=0x286 (WM_IME_CHAR) hwnd=0x90c76 wparam=0x4e2d lparam=0x1 result=0x0

msg=0x137 (WM_CTLCOLORSCROLLBAR) hwnd=0x90c76 wparam=0x1e012c29 lparam=0xf0b1a result=0x0

msg=0x10f (WM_IME_COMPOSITION) hwnd=0x90c76 wparam=0x0 lparam=0x88 result=0x0

msg=0x10e (WM_IME_ENDCOMPOSITION) hwnd=0x90c76 wparam=0x0 lparam=0x0 result=0x0

msg=0x282 (WM_IME_NOTIFY) hwnd=0x90c76 wparam=0x4 lparam=0x1 result=0x0

msg=0x102 (WM_CHAR) hwnd=0x90c76 wparam=0x4e2d lparam=0x1 result=0x0

Checking with the original character inputting without IME, only WM_CHAR events are raised and handled.

For character ‘a’:

msg=0x100 (WM_KEYDOWN) hwnd=0x90c76 wparam=0x41 lparam=0x1e0001 result=0x0

msg=0x102 (WM_CHAR) hwnd=0x90c76 wparam=0x61 lparam=0x1e0001 result=0x0

Also, for both the two situations, we can find that the parameter ‘wparam’ stores the inputted character.

The cause for this bug is obviously the two events with the same inputted character.

Solution:

Add a flag variable to disable the insertion of the inputted character got form the WM_IME_CHAR event.

In the file “CodeEditorProject/EditControl/Forms/Windows/Forms/Widget.cs”:

Add the following class:

public class IME_Chinese_Bug

{

public static bool show = true;

}

Add following code at the beginning of the function WndProc() of class Widget:

if (m.Msg == (int)WindowMessage.WM_IME_CHAR)

IME_Chinese_Bug.show = false;

else if (m.Msg == (int)WindowMessage.WM_CHAR)

IME_Chinese_Bug.show = true;

In the file “CodeEditorProject/EditControl/EditControl/Editors/EditView/EditViewControl.cs”:

Change the code:

InsertText(e.KeyChar.ToString());

to

if(IME_Chinese_Bug.show)

InsertText(e.KeyChar.ToString());

发布了116 篇原创文章 · 获赞 0 · 访问量 8万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章