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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章