我在电脑上使用韩语。如果我在TexBox控件中键入值TextBoxChanged事件触发了三次。我第一次得到打字的值,第二次我得到了空值,我得到了输入值。
如果有人知道原因。
提前致谢。
答案 0 :(得分:1)
原因是韩国IME将跟踪击键并显示 中间人物。所以当我们让richtextbox输出其文本时 TextChanged事件,它将打破IME的工作
这确实是由于RichTextBox中的一个缺陷导致每次完成一个字符时导致IME输入模式退出,因为向IME发送WM_IME_COMPOSITION窗口消息导致其认为IME已完成。检索RichTextBox的Text属性时会触发此操作。 这是一个解决方法,它覆盖了RichTextBox窗口过程,以拦截和避免这个错误的韩文IME条目的代码路径,并使用Text的内部值来避免在IME处于合成中时调用基础控件的属性,但仍然在每个组合后更新输入字符。 请注意,该类公开了一个名为KoreanWorkaroundEnabled的bool属性,默认情况下为true。您可以将此设置为false以将行为恢复为默认值,如果您的文本输入语言是中文或日文,则必须使用该行为。在这些情况下,此解决方法将打破正常行为。您可以使用主机表单上的InputLanguageChanged事件根据当前输入语言设置属性:
public Form1()
{
InitializeComponent();
this.InputLanguageChanged += Form1_InputLanguageChanged;
}
void Form1_InputLanguageChanged(object sender, InputLanguageChangedEventArgs e)
{
if (!e.InputLanguage.Culture.TwoLetterISOLanguageName.Equals("ko"))
richTextBoxKorean1.KoreanWorkaroundEnabled = false;
else
richTextBoxKorean1.KoreanWorkaroundEnabled = true;
}
这是重写的RichTextBox类,它实现了 解决方法:
public class RichTextBoxKorean : RichTextBox
{
[DllImport("imm32.dll", CharSet = CharSet.Unicode)]
private static extern int ImmGetCompositionString(IntPtr hIMC, uint dwIndex, byte[] lpBuf, int dwBufLen);
[DllImport("imm32.dll", CharSet = CharSet.Unicode)]
private static extern IntPtr ImmGetContext(IntPtr hWnd);
[DllImport("imm32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr ImmReleaseContext(IntPtr hWnd, IntPtr context);
public enum WM_IME
{
GCS_RESULTSTR = 0x800,
EM_STREAMOUT = 0x044A,
WM_IME_COMPOSITION =0x10F,
WM_IME_ENDCOMPOSITION =0x10E,
WM_IME_STARTCOMPOSITION =0x10D
}
private bool skipImeComposition = false;
private bool imeComposing = false;
public bool KoreanWorkaroundEnabled = true;
string _mText = "";
protected override void WndProc(ref Message m)
{
if (KoreanWorkaroundEnabled)
{
switch (m.Msg)
{
case (int)WM_IME.EM_STREAMOUT:
if (imeComposing)
{
skipImeComposition = true;
}
base.WndProc(ref m);
break;
case (int)WM_IME.WM_IME_COMPOSITION:
if (m.LParam.ToInt32() == (int)WM_IME.GCS_RESULTSTR)
{
IntPtr hImm = ImmGetContext(this.Handle);
int dwSize = ImmGetCompositionString(hImm, (int)WM_IME.GCS_RESULTSTR, null, 0);
byte[] outstr = new byte[dwSize];
ImmGetCompositionString(hImm, (int)WM_IME.GCS_RESULTSTR, outstr, dwSize);
_mText += Encoding.Unicode.GetString(outstr).ToString();
ImmReleaseContext(this.Handle, hImm);
}
if (skipImeComposition)
{
skipImeComposition = false;
break;
}
base.WndProc(ref m);
break;
case (int)WM_IME.WM_IME_STARTCOMPOSITION:
imeComposing = true;
base.WndProc(ref m);
break;
case (int)WM_IME.WM_IME_ENDCOMPOSITION:
imeComposing = false;
base.WndProc(ref m);
break;
default:
base.WndProc(ref m);
break;
}
}
else
base.WndProc(ref m);
}
public override string Text
{
get
{
if (!imeComposing)
{
_mText = base.Text;
return base.Text;
}
else
{
return _mText;
}
}
set
{
base.Text = value;
_mText = value;
}
}
}