【VC++开源代码栏目提醒】:网学会员VC++开源代码为您提供输入法编程漫谈 - 计算机教材参考,解决您在输入法编程漫谈 - 计算机教材学习中工作中的难题,参考学习。
输入法编程漫谈08-09-07
更新 大家好我是路路通。
记得那是2
007年北京的第一场雪比以往时候来的更晚一些我在此发表了一篇题为《
2007全方位、无
障碍、奇妙无穷的输入方式闪亮登场》注帖子的标题
管理员已在百忙中赐名为《路路通键盘和输入法》的帖子得到韦剑大版主的赞赏并拿得了一份数量为1的订单当时
的心情是何等的激动呀不久还将这一
广告帖置顶
人生最
幸福的事莫过于此如果老天让我遇见韦剑这个人的话我会对他说“爱辣味油”如果我
的发明变成了
产品的话我
希望送他——一套键盘。
此后天天泡在北大论坛静候Microsoft、IBM等
公司的收购支票可是等了3个月有余也没半点音信夜沉沉路茫茫革命一时转入了低潮。
轻轻的我走了点了点鼠标带着我依依
的不舍。
今天我胡汉三又回来了看到韦剑这个版主近来当得这么轻松我就来气因此决定出来搅搅局让他少几分清闲_ 还有北大论坛、加加
论坛、五笔爱好者论坛等等众多大师、高手、牛人他们的码表呀资料呀等等全
免费奉送让我几万大洋的输入法开发经费一分钱也没花出去最后只好挪作它用李振春
老师的
开源代码让我连当面拜师的机会都失去了被迫自学成才他们的
行为已到了是可忍熟不可忍地步今天我如果不出几招让他们瞧瞧那也太不象话了。
《输入法编程漫谈》小学阶段示范程序 《输入法编程漫谈》初中阶段示范程序 输入法
安装程序 拼音码表供输入法程序测试用 汉字
生成工具源代码 微软DDKIME
源代码 自由拼音3.0
源代码
自由拼音3.0
文档 输入法编程难学吗 不难一点都不难。
你这是忽悠人吧不是咱们IT界的人什么
素质会干本山大叔的那些勾当只要你有点C语言基础了解
一点windows的运行机制不出1个月准能精通。
如果这两样都不会还能学吗能如果你能做到妻
离子散、父子反目丢官下岗你都不管了哪绝对没有问题比如我当初买电脑不过是想赶赶时髦从来也没有想过编程呀啥的一开始鼠标摆弄得都不利索双击永远都是两次单击系统每周得摆上好酒好菜请人重装
一次。
就这个水平因练五笔练烦了也想自己编一个输入法。
记得当时我宣布这一伟大的决定时候话音刚落众人已是满地找牙我可不管这些去买了本谭浩强《C程序设计》整天什么活都不干不分日夜的啃了起来
时间一长老婆大人不干了下了最后通谍“要电脑还是要我”我说两样都要
老婆说不可能
最后我就一句话“电脑是要定了你爱怎的怎的”。
臭娘们敢威胁我从小吓大的还怕你不成等
学会了输入法编程就是IT界的人了IT界的人还愁没老婆说实话如果不是
法律的限制还不是要多少就有多少。
经过半年的
奋斗辛勤的汗水终于有了回报
独立的写出了一个有模有样又
实用的程序——路路通输入法1.0。
所以说“入门既不难深造也是办得到的”。
输入法程序是什么东东 输入法是一个小小的动态链接库程序。
动态链接库又是什么呢 我们知道电脑有很多文件大体上可分为数据文件和可执行文件两类数据
文件如文本
文档、音
视频文件等可执行文件如记事本、Word和Excel等它们的扩展名一般是
execomDlleml等。
动态链接库的扩展名是Dll输入法程序的扩展名是将Dll改成了ime。
动态链接库一般不能单独
运行需要借助宿主程序才能执行相关操作打个比方动态链接库输入法就是保姆宿主程序记事本就是雇主。
动态链接库又有动态加载和静态加载两种方式它们的
区别就像保姆和小时工保姆要包吃包住——静态加载费用稍高小时工只需预约——动态加载费用较低。
那种方式更好呢看你的需要比如你家有小宝宝24小时都需要有人伺候保姆比较合适如果只是搞搞
室内卫生擦擦
玻璃什么的小时工就
比较合算。
当然啦如果保姆长的美若天仙又有
大学文凭又聪明能干你想将她转正集成到你的程序去也行但做这个决定之前可要想好啦以后感情不和想
离婚可就没那么容易了。
和平分手民政局你得跑N个来回强行分手
法院你得去N次而且还要分大半家产可不像保姆、小时工那么好打发的。
输入法程序不太可能静态加载因为雇主来自五湖四海。
它的加载方式一般是手工动态加载当然也可以做到自动加载但这样做一般会让人骂流氓。
输入法编程从那入手
一般人学输入法编程都是从研究源代码
开始的网上开源的有《自由拼音》、微软的DDK其它还有一些都是根据这两个改写的。
从源代码入手是个不错的法子但很遗憾这两个代码不是带你
入门的与
国内的
计算机书籍一样都是给计算机的
本科生、
研究生、博士之类作参考用的。
网上还有一些
关于输入法
编程的文章但也只是碰碰嘴唇并没有把舌头伸进去狂搅一番初学者看了也是不得要领。
研究源代码难又无
相关的
书籍想入门还真的是不容易。
造成这种局面说白了就是输入法这种小程序低手不会高手不屑。
实际上输入法很简单它实际上就是一个查表操作。
不相信的
朋友可将你的码表导入到
Excel。
假设你的码表是基于拼音的码表分两列一列是拼音一列是汉字串那么用鼠标点击编辑-gt查找在查找
内容框中敲入shishi点击查找下一个按钮黑色矩形框立即就跳到A列的shishi的行上面对应的B列就是“试试、事事、
实施、时世、史实????”等等这些汉字串输入法
的原理就是这样。
既然输入法这么简单可是做起来却不是那么容易呢这还得从那晕到死的消息机制谈起。
消息
机制是
什么打个比方两个人面对面有话不能直说要这样子你的话-gt老盖手下-gt老盖-gt老盖手下-gt对方对方也是如此。
由于老盖事多还得排队就像你去
银行取款先在营业厅门口的机子上拿一个号比如是A911然后到一边去等候当营业员用喇叭喊“请A911到XX窗口????”时你方可去柜台取款如果这时你还在对刚才
路上碰见的美眉想入非非而没有听见对不起重新再去拿一个号排队。
这还不算完你电脑的
所有的东西都得经他批准才能使用再打个比方你两口子久别重逢正准备上演
儿童不宜的画面这时老盖说“哥们别急给我手下打个
报告等我批了先”。
如果你不听那会死得很难看。
没办法在他的统治之下咱们就得按他的旨意办事。
所以学
输入法编程先得对消息机制、硬件
访问机制有所了解。
你的《输入法编程漫谈》分个阶段 分两个阶段小学阶段、初中阶段。
每个阶段都有示范程序。
小学阶段 Win32对话框的创建 组合窗体、候选窗体的创建和操作 码表的操作 初中阶段 状态窗体
的创建和操作 输入法消息处理 输入法程序与IME的
接口处理 注文章可转载须经本人同意不得用于
商业用途而且必须注明 转
中华人民共和国-gt
北大中文论坛-gt
中文信息处理-gt输入法
讨论专区-gt路路通网友教授的《输入法编程漫谈》。
这个有点长为了节约
网络资源可用缩写 转北大路教授《输入法编程漫谈》。
在此告诉
大家一个消息路路通键盘经过一年多的
改进如今是要多小就有多小按键的数量要多大就有多大操作要多
简单就有多简单以后形码
基本上就不用拆了。
《输入法编程漫谈》小学阶段示范程序 本
程序在Win2k、WinXP下、
VC6编译通过。
编译时请进入Project-gtsettings-gtPreprocessor definitions将_MBCS去掉加上_UNICODEUNICODE 再
进入Build-gtset Active Configuration选中srf-Win32 Release 点击OK。
码表是基于拼音的含有声调
没有按字频排序。
网友可以换上
自己的码表将
目录下srfReleaseBHFile
下的py.txt替换掉即可。
程序默认只支持打开UNICODE
的文本有
能力的网友可自行
修改增加它的兼容性。
“学习输入法编程要带着
问题学活学活用学用
结合急用先学立杆见影在“用”字上狠下功夫。
为了把输入法编程的精髓真正学到手要反复
学习输入法编程的结构和算法有些
概念、
算法最好要背熟反复学习反复
运用。
” Win32对话框的创建 int
APIENTRY WinMainHINSTANCE hInstanceHINSTANCE hPrevInstance LPSTR lpCmdLineint nCmdShow MSG msg hInst hInstance if Init
ApplicationhInstance returnFALSE if InitInstancehInstancenCmdShow returnFALSE while GetMessageampmsgNULL00 TranslateMessageampmsg DispatchMessageampmsg return msg.wParam 这是Win32程序的入口函数完成窗口类的
注册、窗口创建、获取调用线程的消息、消息转换、消息分派等操作。
Init
Application函数的使用windows操作系统的最大
特点是什么当然是大大小小、无处不在的窗口想
创建一个程序一般情况下当然要创建窗口了。
这个有点像开商店先选好场地然后到工商局申请营业执照 WNDCLASSEX wc wc.cbSize sizeofWNDCLASSEX …… 商店
名称、经营
范围等等在这里填清楚。
开多少家都可以只要你的本钱足够。
之后是等候审批这个审批速度比咱们
工商局快多了只要是合法经营瞬间就给你批下来。
不用找关系送烟什么的老盖这点还算清廉。
if Re
gisterClassEx LPWNDCLASSEXampwc return FALSE 如果批准了那么你就可以
准备开张了否则就是无照
经营。
无照经营在老盖的统治下是绝对不可以的啊。
InitInstance函数的使用执照批了下一步就是装修门面了。
hWnd CreateWindowEx 装修得合乎城建的规定如果违章那你
还是不能开业。
ifhWnd returnFALSE 一切
工作都
做好了就
可以开门营业了 ShowWindowhWndnCmdShow UpdateWindowhWnd 获得系统信息。
while GetMessageampmsgNULL00 TranslateMessageampmsg DispatchMessageampmsg 这段我觉得跟咱们村公所
非常像。
GetMessage接待、接电话、跑腿的一天24小时都在村公所呆着。
TranslateMessage支书、DispatchMessage村长一般都在家里干私活有事才到村公所不像咱们上班一族那么正规的。
如果乡党委、政府有事找支书、村长GetMessage这人马上就会去通知他们不至于因为找不着人把官给丢了。
MainWndProc
函数的使用你的买卖就在这里进行。
如果不想做买卖了记得去工商局注销执照还有商场租用
合同、水呀、电呀、闭路电视、
电话等等都得报停
结算清楚我想没有谁还很乐意继续交这些费吧。
case WM_DESTROY: DeleteObjectMyFont Free
MBArray PostQuitMessage0 break default: returnDefWindowProchWndmessagewParamlParam returnDefWindowProchWndmessagewParamlParam 系统给每个窗体过程的消息、数据都是标配的很多根本就用不着这时就
需要返回给默认的函数处理。
跟老盖打交道一定要记住“早请示晚汇报先申请后使用用后归还” 创建文本框 学会了对话框的创建之后我们学习在
对话框上创建一个
文本框它
的作用就是用来接收键盘输入。
hWndEdit CreateWindowEx WS_EX_WINDOWEDGE _TquotEDITquot NULL WS_CHILD WS_VISIBLE WS_VSCROLL WS_HSCROLL ES_LEFT ES_MULTILINE ES_AUTOVSCROLL ES_AUTOHSCROLL 0 0 0 0 hWnd HMENUID_EDITCHILD H
INSTANCEGet
WindowLonghWndGWL_HINSTANCE NULL //让文本框获得焦点 SetFocushWndEdit case WM_SIZE: //让文本框填满整个对话框窗口 MoveWindow hWndEdit 0 0 LOWORDlParam HIWORDlParam TRUE break 我们
不能让文本框直接接收键盘消息我们要把它截下来经过一番加工后才让它发送出去。
就像打仗一样我们要想办法把敌人的情报偷出来改成对
我们有利的情报后再放回去。
这里要要用到一个窗口子类化的技术因这个
技术与输入法的关系不大在正规的输入法程序也不会用到它在这里就不
详细解说了有
兴趣的网友可去查相关的
资料。
在这里使用它主要是基于初学者容易理解的考虑。
输入法就是把键盘的消息截下来经
加工后再放回去没有什么神秘的东西。
键盘消息的处理 我们通过窗口子类
化的手段将操作
系统发给对话框的键盘消息截取后接下来就是如何处理这些消息了。
键盘的消息很多我们只需要处理对我们有用的消息。
输入法需用到的虚拟键主要有两类用于编码的键和功能键。
编码键一般就是26个字母键、数字键、标点符号键可根据自己的输入法进行增减功能键就是空格键、退格键、Esc键、4个
方向键、用于翻页的键等。
下面以拼音输入法为例子来说说按键消息的处理 case WM_CHAR: flg CharHandlerhWndwParamlParam break case WM_KEYDOWN: flg FunKeyHandlerNormalhWndwParamlParam break VK_ESCAPE键是取消编码串由于编码串变量g_PYBMStr是全局变量因此要调用函数InitPYBMStr将其清空。
VK_DELETE、VK_BACK与编码键都是对字符串的操作C
语言的教科书上都有例子不难
理解。
VK_SPACE与10个数字键是对候选框的词条
进行选择。
这个比较
关键你的短语取代操作系统默认的字符就是在这里处理。
VK_HOME、VK_END、VK_LEFT、VK_UP、VK_RIGHT、VK_DOWN是对编码串上面光标插入符
移动的操作在
设计你的编码串结
构的时候必须要有一个变量
存储插入符的位置。
az键
用于编码输入。
“”、 “.”用于向前翻页“-”、“”用于向后翻页。
功能键
必须是在编码串的长度不为零的情况下才需要处理这个初学者要
注意。
还有光标插入符的操作记得通知操作系统刷新一下对应的窗体否则插入符会呆在原地不动。
将字串发送到宿主程序 将选好的字串发送到宿主程序是输入法程序的目的这个
过程就是程序的核心其它的工作都是围绕这个
核心而展开的。
初学者首先要认清这个事实不要把输入法编程想象的很复杂学任何东西都一样一定要把握它住的
本质然后逐层展开最后搞清楚它的方
方面面这样才能学到它的精髓这样才能事半功倍。
我们先来看看示范程序是如何把字串发送到EDIT控件的 case MY_WM_IME_COMPOSITION: //获得最终候选串的指针 lpszResult GetCompResultStr if lpszResult whilelpszResult _T0 //用特快专递将字串发送到EDIT
控件 SendMessagehWndEditWM_CHARWPARAMlpszResult0 lpszResult //字串发送完毕隐藏候选窗体 MoveCandWindow //对
组合串结构和候选串结构初始化 InitPYBMStr InitCandStrPage break 再来看看标准的输入法程序是如何做的 BOOL MakeResultStringBOOL fFlag HIMC hIMC NULL LPINPUTCONTEXT lpIMC NULL LPCOMPOSITIONSTRING lpIMECompStr NULL LPTSTR lpConvStr NULL GENEMSG GnMsg 0 hIMC HIMCGetWindowLongGetUIWnd IMMGWL_IMC if hIMC MessageBeepUINT-1 return FALSE if lpIMC LPINPUTCONTEXTImmLockIMChIMC MessageBeepUINT-1 return FALSE lpIMC ImmLockIMChIMC lpIMECompStr LP
COMPOSITIONSTRINGImmLockIMCClpIMC-gthCompStr if fFlag lpConvStr GetConvStr if lpConvStr return FALSE _tcscpyLPTSTRLPBYTElpIMECompStr lpIMECompStr-gtdwResultStrOffsetlpConvStr lpIMECompStr-gtdwResultStrLen _tcslenlpConvStr else LPTSTRLPBYTElpIMECompStr lpIMECompStr-gtdwResultStrOffset _T0 lpIMECompStr-gtdwResultStrLen 0 InitCompADT ImmUnlockIMCClpIMC-gthCompStr GenerateMessageWM_IME_COMPOSITION0G
CS_RESULTSTR GenerateMessageWM_IME_ENDCOMPOSITION00 ImmUnlockIMChIMC return TRUE 一直到if fFlag这行代码为止之前的那些都是为了取得IMC结构
中存放结果串的
内存块没有别 的
目的。
你选好的字串必须先放到这里然后才能帮你发送出去。
你可能要问
为什么不能
直接发送呢 先来看看我们现在是
怎么杀猪。
农民兄弟把猪养大了一刀把它杀了拿去 卖钱行吗不行
政府有规定生猪要定点屠宰理由是一、可以防止病猪、老母猪、灌水猪上市 二、各种
收费有绝对的
保障你明白其中
的道理了吧 输入法的调试 普通的可执行程序调试很方便设置好断点鼠标点击感叹号或Ctrl F5就行。
但输入法是动态链接库不能单独运行所以这招就不灵了。
很多初学者不知道如何调试输入法程序因此编程的
效率很低。
如何调试输入法 其实也很简单 Project-gt
Settings-gtDebug-gtExecutable for debug session 单击它下面
编辑框右边的有三角符号的按钮弹出一个菜单点击Browse...选择你要用来调试输入法的程序即输入法的宿主程序比如记事本程序
windows
2000 C:WINNTNOTEPAD.EXE windows
XP C:WINDOWSNOTEPAD.EXE 这样在你的输入法代码中设置好断点后点击感叹号
VC就会打开记事本在Windows的
状态栏中选择你的输入法就可以像调试
普通可执行程序一样调试你的输入法了。
WM_KEYDOWN
事件 wParamnVirtKey 就是虚拟键的值。
非系统键的虚拟键代码。
lParamlKeyData。
指定重复计数值、扫描码、扩展键标志、
转换码、原有的键状态标志和暂态标志。
重复计数值 0-15指定重复计数值通常为1。
可是如果把键按下去不放应用程序不能一足够快的速度来处理这些键消息由于各种
原因那么Windows将把多个WM_KEYDOWNWM_SYSKEYDOWNWM_CHAR和WM_SYSCHAR消息
合并为一条消息
正确地对重复计数值进行增量。
当然对于WM_KEYUP或WM_SYSKEYUP重复计数值总为1。
重复计数值可以大于1是因为要将其
作为对自动键入超过限
度的响应。
用户可以从控制面板中选择高
的重复 速率来产生键入溢出的
现象。
扫描码 键盘扫描码是有键盘硬件所
产生的一个值用来标识按下或释放
的实际
物理键。
虽然
不同的键可以产 生相同的字符代码例如主键顶部的数字键和.