2010-07-20 46 views
7

衍生我已经创建了C#.net我自己的单行文本框控件3.5把IME在自定义文本框,从控制

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

我遇到的问题是IME(输入法编辑器)集成。 IME在某种程度上确实起作用,但我遇到了一些问题。我会在这里列出其中一个。

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

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

那么,有什么想法?

这很好,如果任何代码示例是在C++(托管/非托管)或VB.net。我可以轻松地将它移动。

回答

10

好吧,看起来好像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,我有我的答案已经描述this question调用ImmGetCompositionString在Imm32.dll。然后我将其显示为正在撰写的作文,但不要将其添加到我存储的文本中。

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

在韩国,LParam将只是GCS_RESULTSTRWParam将输入的字符,我可以只投给char

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

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

在所有这三种情况下,我都必须确保显示的正在进行的压缩过程已被清除。

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

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

有时我没有收到WM_IME_ENDCOMPOSITION,所以我收到WM_CHAR后清除我的国旗。


总而言之,这是一个非常有趣的学习经验,以及一个仍在进行中 - 但IME现在是我的控制使用,最后一次!我一直工作到凌晨1点才完成。

+1

刚刚发现http://stackoverflow.com/questions/434048/how-do-you-use-ime,早就看到了! – 2010-07-21 02:00:08