纵横码教学辅助软件新版本的设计与实现
苏州大学纵横汉字信息技术研究所
杨季文 邵荣 李培峰
一、设计思想
纵横码是一种规范、易学、快速、优秀的汉字输入编码方法,经过了几年的推广,纵横汉字输入法得到社会的承认和用户的认可。越来越多的用户已经喜欢上了纵横码。在纵横汉字输入法的推广过程中,纵横码教学辅助软件,发挥了重要的作用。本文介绍了怎样用面向对象的程序设计方法及事件驱动的概念来实现新版本的软件系统。
1以DOS为基础
虽然当今计算机科技日新月异,微机平台上主流操作系统从DOS转移到了WINDOWS,相应的应用程序也逐步转移到了WINDOWS上。但是,目前的很多地区,尤其是许多的中小学中,计算机的档次仍停留于286、386,其主流操作系统平台仍是DOS平台,而纵横汉字输入法推广与普及的重要对象是广大中小学生,因此,DOS平台上的纵横码教学辅助软件的开发仍十分必要。
2 采用面向对象的程序设计方法
不采用传统的编程方法,而采用面向对象的程度设计方法,是因为传统的编程方法在进行较大系统的设计时,存在着种种的缺陷,安全性与易维护性得不到保证。例如,用传统结构化方法所组织的软件耦合性很强,当程度代码膨胀到一定程度时,局部改动将引起“牵一发而动全身”的全局修改,维护、修改使程序员视之为畏途。
追求安全、高效率、易维护性是我们开发新版本纵横码教学辅助软件的一个主要目的,而使用面向对象的程序设计方法可以在很大程度上改善传统程序设计方法的种种不足,因此我们使用了这种设计方法。
3新旧版本结构的不同
旧版本纵横码教学辅助软件许多模块的框架是相似的,所不同的只是它们所含的内容不同而已。许多的函数的信息交换是通过全局变量来实现的,程序显得很凌乱。另外,原来版本的软件在许多的函数中自己控制键盘的读入,程序走向由函数自己进行控制,程序结构十分繁杂,而在许多的函数等待读键过程中,CPU资源就白白浪费掉了。
新版本的纵横码教学辅助软件设计过程中引入“继承”的概念来避免相似模块的重复编写,引入“事件驱动”的概念简化程序结构,提高CPU的利用效率。在程序中,一个核心的中心控制机制用于监控所有的事件,并派送到每一个事件处理程序中,而不是让程序的某一子模块,来等待事件的发生并发送到其他模块。事件驱动的实质是由事件来触发相应的一组操作。
4特点
新版本软件的主要特点如下:
● 设置配置文件,可以根据环境的变动而重新设置
● 训练,测试内容可变换
● 教学,训练速度可调
● 全程支持鼠标
● 全程图标化界面
● 对话框,文本框使用WINDOWS风格界面
● 在线帮助功能,针对操作,纵横码输入进行提示
● 测试输入速度后,可以生成成绩结果文件
● 支持在无盘工作站上使用
● 640*480分辨率下16色显示以适应256K显示存储器的机器
● 由事件驱动程序的各种操作
● 内嵌汉字系统,无须外挂中文环境
● 内存的自动三级管理,按常规内存,XMS,硬盘三级优先递减进行利用
● 使用多种技术实现图文的高速显示
二、模块与结构组织
1功能模块
新版本功能上划分为三大主模块:演示、训练和测试。
演示模块中又分四个子模块:
字身取码规则
字身补码规则
补充说明规则
词组取码规则
训练模块中分十个子模块:
笔形代码训练
主部首代码训练
副部首代码训练
字身取码识别
字身取码输入
字身补码识别
字身补码输入
常用字输入训练
随机字输入训练
词组输入训练
测试模块中分四个子模块:
测试方式1
测试方式2
测试方式3
测试方式4
2类的层次关系
新版本系统是由类为单位逐层进行组织实现的,这里给出三个最基本类层次:
最底层由三个基本类组成:
鼠标类:负责鼠标的状态的获取,鼠标指针的移动、隐藏、打开;内存管理类:负责内存的申请、分配、释放、数据的存放,它使用内存的三级管理模式;基本显示类:高速的写点、画线、画框等基本显示操作。
中间层的几个类是:
事件类:处理程序中的三类事件——鼠标事件,键盘事件,程序本身产生的事件(即消息),它维持一个消息队列,存放多个事件;汉字类:负责汉字、ASCII字符的显示 ;CKC类:负责将机内码与纵横码相互转换;窗口类:实现文本框、对话框、编辑框的显示 ;图形类:负责图片的显示、擦除。
高层的几个类是:演示类,训练类,测试类。
此外 ,还有一些辅助类。
三、系统实现
下面使用两个例子进行说明面向对象的程序设计方法,事件驱动及内存自动管理在纵横码教学辅助软件中的体现。
1 鼠标事件
程序中的事件分为三类:鼠标事件,键盘事件,以及由程序本身生成的事件即消息。下面举例说明鼠标事件的处理。
假设在演示纵横码的编码原理时,鼠标按下了界面上的帮助按钮。这时,主模块的事件接收机构接到了鼠标单击事件,它把鼠标事件放入消息队列,然后一个专门的消息派送函数将把消息传入内部。
由于当前演示模块处于激活状态,它将接收并消化掉这个消息。演示模块接到这个消息后,它又将这个消息分别传给有处理能力的子模块。此时,帮助按钮的消息处理模块接收到消息后判断是自己处理范围的消息,它将取得消息,返回一个申请帮助窗口的消息,其中包含了纵横码当前演示的进度状态标识。
申请信号将返回到主事件循环,此时,主事件循环上的帮助模块判断消息队列顶层有帮助申请消息时,将处理这个消息。它根据消息中的状态标识查帮助的索引表,找到对应的帮助内容,实例化一个阅读窗口对象,并弹出这个窗口,显示出纵横码的对应章节的帮助内容。
现在不妨再深入一步,看看窗口对象内部的工作方式。阅读窗口含有一个滚动条,滚动条上有一个定位钮,一个上滚按钮,一个下滚按钮。鼠标点击上滚按钮时,窗口中帮助内容会上滚一行。
当鼠标点击上滚按钮时,鼠标事件将被层层传入到窗口对象中,窗口对象将消息传给内部的滚动条,滚动条判断是否在自己的处理范围内,如果发现是在上滚按钮上,将改变窗口对象中的显示行的范围(改变对象中的行状态变量),同时给出一个刷新请求,返回到外层时,窗口对象接到请求,刷新窗口内的内容。
在此需要强调的是,窗口对象处理的消息内传、判断、改变行列号和刷新窗口等的操作及相关数据均被是封装在对象内部,对外部而言是透明的。这样,即使有几个窗口同时弹出也互不干扰。采用这种方式,实现了数据及功能的抽象。这对简化程序结构有很大的帮助作用,又因为代码共用,降低了代码的冗余。
可以看到,事件驱动给纵横码教学辅助的维护也带来了便利。如果要加入新的事件处理功能,只要在主循环上挂入处理事件的模块就行了。
2存储管理
纵横码教学辅助软件涉及大量内存、缓冲操作,例如字符字模库、测试的临时试卷、需要保存的屏幕、图标等等。有效的内存管理是纵横码教学辅助软件安全高效的关键。在新版本中,充分考虑了速度与空间的协调。
一般情况下,常规内存、XMS、硬盘的空间依次递增,而速度却逐级递减。从速度与环境的适应性上考虑,我们采用了这三级空间优先级递减的方法进行管理。也就是说,当需要申请一块内存空间时,内存管理机构将判断是否有足够的常规内存空间供分配;没有,将转向下一级XMS,再判断是否有足够的XMS空间供分配;还没有,转向硬盘,利用虚拟内存(硬盘上生成一个临时文件)进行分配。
仍以演示模块来举例说明。假设演示时,鼠标事件触发了帮助消息后,弹出窗口前,必须进行窗口区域的屏幕保存。此时,窗口对象的构造函数将申请一块内存进行画面的保存。内存的申请、交换、数据传递和释放等一系列操作都封装在一个内存管理类中,当申请一块内存时,由内存管理类生成一个内存对象,它负责生成内存,并进行这块内存的操作,它对外的接口是一个内存句柄及一个内存指针。它在内存申请中将自动判定当前的内存模式下内存是否够用,是否要降级申请。常规内存方式时,返回两个远指针,头指针及当前地址指针;XMS方式时,返回一个内存柄及一个内存指针;硬盘虚拟内存方式时,返回一个文件柄及一个文件指针。不管在哪种内存方式下,内存的两个指针或句柄都封存于对象中。
窗口对象申请内存后,保存数据。在退出窗口前,从内存取数据恢复屏幕区域,这一系列的内存操作均由内存对象内部处理,不需外部进行干预。
很关键的一点是怎样实现统一的内存接口,使外部的使用者感觉不到是使用的常规内存还是硬盘上的虚拟内存。我们使用了一个结构,其中包含了所使用的存储区域类型以及一个作为内存句柄的联合,联合中有三个指针,常规内存的指针类指针,XMS的指针类指针,文件名串的指针。对内存块的操作就使用这个结构指针。并且,实现了一组接口函数进行存储区域的自动转换。
就这样,纵横码教学辅助软件中的内存的缓冲操作与具体功能代码内部的应用操作实现了分离。从内存管理的方面使系统达到了安全高效的目标,并且易维护。
四、结束语
新版本软件中所实现的新思路是一种大胆的尝试,其中一定有很多不成熟的地方,但希望本软件的实现能推动纵横码其他外围软件的设计,对纵横码的推广起到积极的作用!
新版本软件中所使用了事件驱动概念与面向对象的程序设计方法,它们不仅仅适合纵横码教学辅助软件,在其他的应用软件的设计中,也有极高的应用价值,有利于系统的高效、安全、易维护性的实现。