c# - 将 IME 放在派生自 Control 的自定义文本框中

标签 c# .net winforms custom-controls ime

我在 C# .net 3.5 中创建了自己的单行文本框控件

我完全从头开始写这个,包括我自己的选择代码、滚动、复制/粘贴等。它甚至可以选择从左到右的文本,而不是我曾经使用过的...

我遇到的问题是 IME(输入法编辑器)集成。 IME 在一定程度上确实有效,但我遇到了一些问题。我将在这里列出其中一个。

通常,使用 TextBox 时,IME 构造在 TextBox 内呈现。但是,在我的控件中,IME 显示在屏幕的右下方。我尝试查看其他自定义控件,包括 SharpDevelop 中使用的控件。但是,这有同样的问题。输入中文、日文或韩文会导致 IME 内容在屏幕右下角完成。

我需要一些关于如何在我自己的文本框中完成此操作的指示,我查看了用于 IME 的 Windows API,但函数太多,我不知道从哪里开始。

那么,有什么想法吗?

如果任何代码示例是 C++(托管/非托管)或 VB.net 格式的都可以。我可以很容易地移动它。

最佳答案

好吧,看起来 StackOverflow 上的 IME 专家并不多......或者没有人感兴趣。

不管怎样,我想通了。

基本上,我必须捕获以下 Windows 消息:

WM_INPUTLANGCHANGE = 0x51
WM_KEYUP = 0x101
WM_CHAR = 0x102
WM_CONVERTREQUESTEX = 0x108
WM_IME_STARTCOMPOSITION = 0x10D
WM_IME_ENDCOMPOSITION = 0x10E
WM_IME_COMPOSITION = 0x10F
WM_IME_SETCONTEXT = 0x281
WM_IME_NOTIFY = 0x282
WM_IME_CONTROL = 0x283
WM_IME_COMPOSITIONFULL = 0x284
WM_IME_SELECT = 0x285
WM_IME_CHAR = 0x286
WM_IME_REQUEST = 0x0288
WM_IME_KEYDOWN = 0x290
WM_IME_KEYUP = 0x291

我正在捕获 WM_KEYUPWM_CHAR,因为如果我在合成韩文字符的过程中单击某处,我不会收到合成消息,但我需要尽管如此,还是将该字符添加到我的文本框中。这是一个奇怪的行为,我想知道这是否是一个错误。

一旦发生这种情况,韩国人、中国人和日本人之间就会有不同的行为。

韩语真的很简单(不过我不确定汉字转换,因为我不知道如何使用它)。

基本上,对于所有语言,每当我得到一个 WM_IME_COMPOSITION 时,我都必须调用 Imm32.dll 中的 ImmGetCompositionString,正如我在对 this question 的回答中所描述的那样.然后我将其显示为正在进行的合成,但不将其添加到我存储的文本中。

当一个字符串被合成时,来自 Windows 的消息对于每个 IME 都是不同的。每次,我都可以从 WM_IME_COMPOSITION 消息中获取它。

在韩语中,LParam 将只是 GCS_RESULTSTR,而 WParam 将是输入的字符,我可以将其转换为 字符

在日语中,“LParam”将是 GCS_RESULTREADSTR | GCS_RESULTREADCLAUSE | GCS_RESULTSTR0 | GCS_RESULTCLAUSE。我必须使用从上一个 WM_IME_COMPOSITION 消息中存储的 ImmGetCompositionString 的结果,因为此时它将是一个空字符串。

在中文中,LParam 将是 GCS_RESULTREADCLAUSE | GCS_RESULTSTR0 | GCS_RESULTCLAUSE。它与日语相同,除非之前存储的 ImmGetCompositionString 为空,在这种情况下我需要将 WParam 转换为 char。

在所有这三种情况下,我都必须确保清除显示的进行中的比赛。

如果我收到 WM_IME_STARTCOMPOSITION,我会设置一个合成标志(并显示正在进行的合成字符串)

如果我收到 WM_IME_ENDCOMPOSITION,我会清除该标志(并清除正在进行的合成字符串)。

有时我没有收到 WM_IME_ENDCOMPOSITION,所以我在收到 WM_CHAR 时清除我的标志。


总而言之,这是一次非常有趣的学习经历,并且仍在进行中 - 但 IME 现在终于可以在我的控制下使用了!我一直工作到凌晨 1 点才完成它。

关于c# - 将 IME 放在派生自 Control 的自定义文本框中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3287180/

相关文章:

c# - LabView 应用程序中引用的 C# .dll 是否可以访问 app.config 文件?

.net - 部署 .NET WinForms 应用程序的最恶劣的企业环境是什么?

c# - IExtenderProvider 根据对象类型仅添加一些属性

c# - 如何重命名 Windows 窗体应用程序中发布文件夹中的 EXE 文件和配置?

c# - 有没有办法创建或更新 MongoDB 索引?

c# - 有没有办法自动确定语句可能抛出的异常?

c# - 字符串到当前时间的日期

c# - 在给定支持字段的情况下获取 C# 自动属性的 PropertyInfo

c# - 如何在 C# 中枚举枚举?

c# - 绑定(bind)到使用 CreateObject 创建的已打开表单