XNA中的中文输入(一)
XNA中的中文输入(一)
仅供个人学习使用,请勿转载,勿用于任何商业用途。
游戏中的中文输入一直是个很棘手的问题,就连wow也实现的不是很好,很多人不得不在窗口最大化模式下游戏。对大部分程序员来说,如果不开发输入法,永远也不需要关心IME是如果工作的,即使是游戏开发,除了中日韩等少数使用多字符语言的国家,也不需要关心IME。了解游戏IME开发的人,也因为种种原因,不愿过多讨论,因此相关资料非常之少。
最近花了一周时间,终于实现了中文输入。本文主要讨论如何在XNA中调用IME,有些特定WinForm下的行为也许和传统DirectX程序不太一样。本文不会给出详细的实现代码和原理,但会把所有关键步骤都写出来。
继续阅读之前,你应该先了解或准备以下资料:
1. DirectX SDK中CustomeUI的sample。虽然这并不是一个很适合“学习”的例子(代码太过于复杂),但毕竟是ms建议的标准实现方法,也是最兼容性最好的实现。
2. DirectX SDK中的Using an Input Method Editor in a Game一文,以下简称“指南”。在我看来,这同样也是一篇不太好的指南,很多关键部分讲的非常模糊。
3. Windows SDK中IME相关的文档,可在MSDN—Win32 and COM—User Interface—Internationalization—SDK Document—International Text Display找到。
4. 对于XNA开发者还需要对windows消息机制(WindowProc)以及P/Invoke有所了解。
我们要做的事情非常简单,1,在游戏程序中打开IME窗口;2,获得IME所“合成”的文字;3,隐藏IME窗口(可选)。实现的思想也很简单:拦截IME相关的windows消息,并进行处理就可以了。
要处理的第一个消息是WM_IME_SETCONTEXT(请先了解文档里Input Cotext的概念),SDK里说“Sent to an application when a window is activated”,按照我的理解,这句话的意思是每次窗口active之后,向窗口发送一次。但我在WinForm下的测试结果是很多IME状态改变都会触发这个消息。SDK里还说“By default, the operating system creates and assigns an input context to each thread”,这句话迷惑了我很久,从后来的实验来看,系统并没有“assigns an input context to each thread”,因为如果在接收到WM_IME_SETCONTEXT时,显式调用ImmAssociateContext,再Ctrl+shift,运气好的话,此时打字会发现IME窗口已经出现了!对,就这么简单(指南里竟然完全没有提到ImmAssociateContext这个函数,怨念啊,我苦苦google了一整个下午T_T)。为什么要说运气好呢?因为此时你见到IME窗口的可能性,基于你安装了哪种输入法!搜狗,恭喜你中奖了;紫光,你有50%的可能性看到;微软或者google拼音,基本上你什么都看不到。无论如何,总算是有了进展。让我讲的更详细一些,以便你能重现这个伟大的时刻J
1. 创建一个新的winForm程序,对我们先从winForm开始,然后再讨论XNA。
2. 声明以下API
{
[DllImport("imm32.dll", SetLastError = true)]
public static extern IntPtr ImmAssociateContext(IntPtr hWnd, IntPtr hIMC);
}
3. 为了方便使用API,还需要声明以下常量
public enum CompositionStringFlag
{
ReadingString = 0x0001,
ReadingStringAttribute = 0x0002,
ReadingClause = 0x0004,
CompositionString = 0x0008,
CompositionStringAttribute = 0x0010,
CompositionStringClause = 0x0020,
CursorPosition = 0x0080,
DeltaStart = 0x0100,
ResultReadingString = 0x0200,
ResultReadingStringClause = 0x0400,
ResultString = 0x0800,
ResultClause = 0x1000
}
public static class WindowMessage
{
public const int Char = 0x0102;
public const int ImeStartCompostition = 0x010D;
public const int ImeEndComposition = 0x010E;
public const int ImeComposition = 0x010F;
public const int ImeKeyLast = 0x010F;
public const int ImeSetContext = 0x0281;
public const int ImeNotify = 0x0282;
public const int ImeControl = 0x0283;
public const int ImeCompositionFull = 0x0284;
public const int ImeSelect = 0x0285;
public const int ImeChar = 0x286;
public const int ImeRequest = 0x0288;
public const int ImeKeyDown = 0x0290;
public const int ImeKeyUp = 0x0291;
public const int InputLanguageChange = 0x0051;
}
4. 为窗口添加以下函数:
{
if (m.Msg == WindowMessage.ImeSetContext)
{
if (m.WParam.ToInt32() == 1)
{
IntPtr imeContext = IMM.ImmGetContext(this.Handle);
IMM.ImmAssociateContext(this.Handle, imeContext);
}
}
}
好了,编译运行。成功没有?没有!对,就算你装了先前提到的第一种输入法,此时程序也不会有任何反应。Why?设置断点,你会发现imeContext的值是0,意味着根本没有得到正确的context。再仔细Debug,你会发现在程序启动时,WM_IME_SETCONTEXT消息被触发了不止一次,第一次消息触发时,正确得到了context,但后面的几次消息,只会返回0。所以,必须在初始化时,保存对context的引用,这是与CustomeUI例子非常不同的一点,猜想也许是winForm底层机制的原因。再次运行,你应该能看到些东西了。
现在来解决只对搜狗和紫光有效的问题(顺便说一下,之前一直觉得各种输入法之间没多大差别,这次才发现搜狗是所有输入法里最神奇的)。这是真正困扰了我一周的问题,结果却出乎意料,只需要在WndProc里添加以下代码:
{
return; //Don't pass this message to base class!!!!
}
不出意外的话,现在你已经可以调出所有输入法了。下一次,我将讨论如何取出IME中的字符
转载于:https://www.cnblogs.com/clayman/archive/2009/12/17/1626084.html
XNA中的中文输入(一)相关推荐
- Ubuntu18.04中dia中文输入
开始是希望在ubuntu中找一个比较好的画流程图工具,在网上找了一下,发现dia还可以,但在下载安装后发现我不能进行中文输入,之后有事一顿百度.google,找到几个解决方法(但我试了,都无用) 将配 ...
- 在Ubuntu终端中设置中文输入
说明:我的截图是在我配置完成后,之后截得图,在Ubuntu下切换中英文是win+空格键 1. 首先打开设置,再在设置中找到区域和语言中的管理已安装的语言 2. 再选择添加或删除语言,再在已安装语言里面 ...
- dreamweaver半角空格_在Dreamweaver MX中,中文输入时要输入空格应该()。A.在编辑窗口直接输入一个半角空格B.代码中输入...
在产品生命周期各阶段中,销售增长率最高的阶段是()A.投入期B.成长期C.成熟期D.衰退期 在一定的组织体系中,通过明文规定的渠道所进行的沟通叫()A.正式沟通B.非正式沟通C.单向沟通 肠阿巴病性溃 ...
- 开始ubuntu 14.04 的装X模式---终端模式下中文输入,听歌,上irc 开启framebuffer看电影 截图...
先上图吧 卡卡的全是在tty1 下的操作,看电影,听歌,截图 ,看图 ,上irc 等等,相当适合在小白面前装屁! 需要安装的软件: 为了能正常显示中文:安装fbterm sudo apt-get i ...
- vmware 中文输入解决方法
在vmware的ubuntu系统中无法输入中文,首先打开Language support,点击Install/Remove Languages 勾选中文后点击Apply 下载完成后再设置界面选择key ...
- centos7中mysql不能输入中文问题的解决
centos7中mysql不能输入中文问题的解决 参考文章: (1)centos7中mysql不能输入中文问题的解决 (2)https://www.cnblogs.com/qiangayz/p/868 ...
- mysql中更改字符集为utf8mysql中文输入不了问题解决
mysql中更改字符集为utf8&&mysql中文输入不了问题解决 参考文章: (1)mysql中更改字符集为utf8&&mysql中文输入不了问题解决 (2)http ...
- c#中利用keybd_event函数+自定义软键盘实现中文输入时的问题
(一)声明外部方法 [DllImport("User32.dll")] public static extern void keybd_event(byte bVK ...
- React Native 中 TextInput 组件和中文输入冲突
原文转载自我的 Github 博客 在用 React Native (下称 RN) 开发面向国人的应用时,不可避免会有用户使用中文输入法的情景.在 RN 中,负责输入内容的控件是 <TextIn ...
- IDEA的全局搜索框中,无法输入中文
问题描述:在idea的全局搜索框(快捷键Ctrl+Shift+F)中,无法输入中文字符,只能输入英文字符 解决办法:清除idea缓存并重启 1.检查输入法 我用的搜狗输入法,把和idea冲突的快捷键全 ...
最新文章
- 认识python零基础知识到实战概论的复习和回顾上
- SSL/TLSV1.0 programe in linux
- ISIS和OSPF的比较
- [单刷APUE系列]第五章——标准I/O库
- vector简单实现
- C和指针之字符串strtok函数
- 从网络到分布式-负载均衡
- 浏览器事件循环机制与Vue nextTick的实现
- 【Python】安装IPython和IPthon Notebook
- 2019智能手表推荐_戴过 100 块智能手表后,2019年我觉得这4款智能手表最值得买!...
- Django之POST GET与前后端交互
- 《编码的奥秘》读后感
- 首次项目经验总结(一)
- 子龙山人:我从Cocos2d-x团队里学到的
- 解决IP地址冲突的方法
- python 发送邮件正文字体设置_smtplib文字邮件的发送
- android平台下OpenGL ES 3.0绘制纯色背景
- SimpleMind Pro中文版
- cent os 火狐_本周关注我们:整体框架和Firefox OS
- 2021年最后一件大事!