发现一个自由拼音输入法错误


如果:

上图有6个词组,如果你这时候按Shift+1,就可以删除掉前面的“删除错误”这个词。“删除错误”是我自己造的,属于用户词组。
如果:
如果这时候输入Shift+3,自由拼音输入法就会出现下面的错误。
错误在自由拼音输入法源代码的HZmodenormal.c文件的DeletePhrase函数中,这个函数的功能是删除用户词组(用户词库)。里面有这样一段:
if(0 <--错误是这一句 lpKPh = (lpPYCand->aPhrase+wIdx)->lpKeyPH;
lpHZPh = (lpPYCand->aPhrase+wIdx)->lpHZPH;
if( ((LPBYTE)lpKPh >= (LPBYTE)lpMapFileBase
&& (LPBYTE)lpKPh < (LPBYTE)lpMapFileBase + MAX_PY_NUM*sizeof(KEYPH) ) || ((LPBYTE)lpKPh >= (LPBYTE)lpMapFileBase + 2*MAX_PY_NUM*sizeof(KEYPH)
&&(LPBYTE)lpKPh < (LPBYTE)lpMapFileBase + dwMapFileUsrOffset ) ) { lpHZPh->dwAttrib = 0;
wRet = 1;
}
else{
lpCurHZPh = lpKPh->lpHZPH; <--程序运行到这出错
。。。。。。
C语言是允许(0
这一句被C语言解释成:0
本来按Shift+3已经超出了选词范围,但(0 lpHZPH;这是在引用空指针。
把 if(0
自由拼音输入法的作者肯定是一时大意才会出现这样的错误,在这还是要感谢自由拼音输入法的作者李振春为我们免费提供的源代码。

童年游戏


捉虫 现在那个虫子 你还记得吗 ?

放风筝 相信每个人都有一个儿时的风筝

玩手指头的游戏 现在有时还玩呢

滚铁环 你的那个铁环已经生锈了吧

捏黄泥 手里的黄泥带给你的乐趣 至今难忘吧

打野果子 拿着长长的竹竿 去弄果子吃 那个美味啊

打仗 两帮人打仗 你有没有 被打死后 又活过来的经历呢?

折飞机 用纸折的飞机 据说在嘴里哈过气后会飞的更远

画丁老头 随便一块地方就是你的画板

吹泡泡 你有没有要做吹泡泡用的水而让家里的洗衣粉和香皂都遭殃呢?

读自由拼音输入法的源代码


到今天,自由拼音输入法的源代码完整的看了一遍,程序的算法基本弄清楚了。

不过一些细节没有搞懂,比如汉字编码、windows的一些消息处理。

还有,关于IME的运行流程我还没有一个清晰完整的概念。

IME里面使用的结构元素,自由拼音并没有全部处理,

比如:COMPOSITIONSTR

typedef struct tagCOMPOSITIONSTR { //用于存放编码信息的信息:所有的实际信息放在本结构的后面
DWORD dwSize; //结构大小(包括和这个结构一起构成一个新的结构的数据,也就是这个结构后面的数据)
DWORD dwCompReadAttrLen; //读入的编码属性长度 未处理
DWORD dwCompReadAttrOffset; //存放在内存的位置 未处理
DWORD dwCompReadClsLen; //读入的子串长度 未处理
DWORD dwCompReadClsOffset; //存放在内存的位置 未处理
DWORD dwCompReadStrLen; //读入的编码长度 未处理
DWORD dwCompReadStrOffset; //存放在内存的位置 未处理
DWORD dwCompAttrLen; //编码属性长度 未处理
DWORD dwCompAttrOffset; //存放在内存的位置 未处理
DWORD dwCompClsLen; //编码子串长度 未处理
DWORD dwCompClsOffset; //存放在内存的位置 未处理
DWORD dwCompStrLen; //编码串长度
DWORD dwCompStrOffset; //存放在内存的位置
DWORD dwCursorPos; //当前光标位置
DWORD dwDeltaStart; //被修改编码的位置 未处理
DWORD dwResultReadClsLen; //读入结果子串长度 未处理
DWORD dwResultReadClsOffset; //存放在内存的位置 未处理
DWORD dwResultReadStrLen; //读入的编码长度 未处理
DWORD dwResultReadStrOffset; //存放在内存的位置 未处理
DWORD dwResultClsLen; //结果子串长度 未处理
DWORD dwResultClsOffset; //存放在内存的位置 未处理
DWORD dwResultStrLen; //结果串长度
DWORD dwResultStrOffset; //存放在内存的位置
DWORD dwPrivateSize; //用户自定义数据长度 未处理
DWORD dwPrivateOffset; //存放在内存的位置 未处理
} COMPOSITIONSTR;

不知道为什么可以不处理,这些未处理结构元素有什么作用,这些问题“自由拼音”是不能回答了。

看样子要找些英文资料并结合调试来搞清楚了。