版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Ultimate Chinese Editor 文档文档Documents of UCE 1.0哈尔滨工业大学计算机系哈尔滨工业大学计算机系Last modified on 2002-9-12目录目录 Contents关于本软件关于本软件3软件描述3背景3软件的主要特色4参与人员(本软件)4功能模块功能模块4内核模块4键盘控制模块6汉字输入法模块7UNDO模块8MESSAGEBOX对话框模块 8显示输出模块9文件列表文件列表9功能模块函数列表功能模块函数列表10LIST.C10EDITOR.C11BITMAP.H12I. How come.12II. Crack it.12III. First
2、 Use the Power . 15IV. Future Improvement .16WINFUNC.H16I. Design Purpose . 16II. The Data Structure .17II. The Functions . 19III. Apply The Header .21GOUTPUT.H22IMD.H24功能函数的算法说明功能函数的算法说明(部分部分) 25APPENDCHAR()在末尾追加一个字符25VOID INTERRUPT FAR CURSORHANDLER()显示光标的时间中段句柄的函数25VOID SCROLLWINDOWUP(UNSIGNED IN
3、T N)从第N行后显示区域下滚26VOID GETHZ(CHAR INCODE,CHAR BYTES)获取汉字字模28VOID PUTASCCOLOR(.) 在特定位置用特定颜色显示 ASCII 字符28VOID PUTCNCOLOR(.); 在特定位置用特定颜色显示汉字字符28问题解决及存在的问题问题解决及存在的问题30个人感受个人感受30虚空中的执著30感受团队(ENJOY TEAMWORK)31经验及教训经验及教训32致谢致谢32附录附录32西文方式下挂接 UCDOS 5.0 中的万能汉字输入法32关于本软件关于本软件软件描述软件描述软件中文名称:中文编辑器软件英文名称:Ultimate
4、 Chinese Editor运行环境:DOS 环境编写语言:C编译环境:Turbo C+V1.0版本:Version 1.0背景背景本软件是哈尔滨工业大学计算机系 2001 级本科生的年级作业作品。2001 年 7 月,和为等计算机系 2001 级 7 名本科生在关毅关毅老师的领导下组成开发小组,利用假期时间完成两个题目:通讯录和编辑器.本软件即是编辑器小组的作品。此次活动的目的是,通过年级大作业形式的活动来培养互相协作、互相配合的团队精神,通过活动中的实际练习来加深已学知识的理解,同时又增加了学习新知识的乐趣(如果加学分就更好了)。关老师考虑到 2001 级本科生所学的专业课有限,高级语言
5、课程仅涉及 C 语言,要求软件的所有代码用 C 编写。这个编辑器的所有代码可在 TurboC+v1.0 中编译通过。Turbo C+V1.0 是 Borland 公司的产品,编辑环境比 TurboC2.0 有较大的改善,而且对 C 支持的非常好,故此成为我们的首选。而且我们还用工程管理,使各自的模块相对独立,方便管理。软件的主要特色软件的主要特色Ultimate Chinese Editor V1.0 具有以下几方面特色:较强的处理中文的能力,对中文整体识别,您不会看到“半个汉字”引起的屏幕混乱。能够脱离汉字系统,有独立的输入法,让您在没有汉字系统的情况下能够自由录入、编辑文本。支持块操作。有
6、比较友好的界面,有提示对话框,帮助您更好的编辑。提供源代码,期望与您交流。 (贻笑大方了)有详细的文档(值得一看哦不是吹牛吧).参与人员(本软件)参与人员(本软件)杨碧辉 0103111 班 负责显示模块部分陈奂章 0103112 班 负责菜单和界面部分高立琦 0103113 班 负责数据操作、管理模块部分gao_功能模块功能模块内核模块内核模块内核是对数据处理的核心程序。著名的计算机科学家沃斯(N.Wirth)提出了“数据结构+算法设计=程序” 。确定了合适的数据结构,设计出精美的算法,我们的程序的功能的实现才能变为可能。我们首先分析了一下编辑器的数据结构特点:1)不定性。编辑器的行列是不定
7、的,即我们不能预先知道要处理多大的文本。2)不规则性。每一行的数据量不定,不能用一个固定、通用的数组来存放。3)非连续性。编辑器需要频繁的插入、删除操作,如果用固定、连续的空间存放,势必降低运算的效率。这些特点是我们排除了数组、队列等数据结构类型,我们的目光锁定在链表上。链表具有可以动态添加、删除节点,不需要连续的内存区域等特点,适用于编辑器的数据要求。我们设计以每个字符为单位的基本结构。为了方便处理中文,我们将一个汉字看作一个中文自符。字符单元的结构如下:struct CHAR_NOTEchar c, c1;CHAR_NOTE *pNext, *pPre;若干个字符节点连在一起便形成了一行。
8、行链表示意图我们又设计了一个行的结构体:struct LINE_NOTEint Len;int MaxCaretx;CHAR_NOTE *pHead,*pEnd;LINE_NOTE*pNext, *pPre;int Bx1, Bx2;用来管理一行的链表。如 pHead 用来记录链表表头的指针,pEnd 用来记录链表最末一个字符的指针。编辑器的核心任务就是维护这样的一个复杂的“双链表” 。文件 LIST.C 中提供许多函数,如 InsertAfter(), AppendChar(), SeekChar()等函数来维护双链表。函数的功能在模块功能中有详细介绍。键盘控制模块键盘控制模块键盘控制模块示
9、意图主干程序采用 while 循环,如代码:while(1)dok=GetInputWord(s); /*取当前输入法模块返回的字串*/ while(k=0 & *s=0);if(k=0) /*字串有效*/p=s;while(*p) AddChar(*p+);else /*为不可显示按键*/key.i=k;if(key.c0 != 0)flag=1;switch(key.i)/*控制键*/case C_Y:case C_Z:case C_S:if(flag)switch(key.c0)case ENTER :case BACKSPACE:KeyBackspace();break;case ES
10、C:default:AddChar(key.c0);break;elseswitch(key.c1)/*功能键*/case UP:case DOWN:.每一按键对应一个处理模块,各个处理模块调用 LIST.C 中的模块并协调显示的数据和内存中的数据的一致性。比如,KeyUp(), KeyDown() 为控制光标键的处理模块,改动内存当前字符的指针并改变屏幕上当前光标的位置。汉字输汉字输入入法模块法模块由于我们的编辑器独立于汉字系统,且又要处理中文,故而我们必须提供中文输入法模块以供用户来输入中文。汉字的输入是通过 bioskey()取得键盘的扫描码,根据键盘的扫描码算出汉字的输入码,最后根据输
11、入码从字库中查找相同的输入码,取得汉字的内码来实现的。我们采用 UCDOS5.0 中的 IMD 输入法码表文件,该码表文件有几个优点:1)UCDOS 中广泛支持,提供众多码表文件2)码表文件结构清晰3)输入法算法通用,可以挂接多种输入法。关于输入法码表文件的结构,输入法算法,请详见附录。这部分资料我们取自网络。Undo 模块模块该模块提供简单的 Undo 功能,能恢复被删除的 200 个字符,并将恢复的字符插入当前位置。Undo 模块采用循环队列的数据结构来管被删除节点的信息。一般的,队列遵循先进先出的原则(FIFO: First In First Out) 。普通的队列在一个元素出列时,期它
12、的元素都要向前移动一个位置。在内存中表现为所有单元的元素向前移动一个位置。这样势必会增加操作时间。我们采用循环队列,因为循环队列采用两个指针:Head 和 Tail,分别指向队列的第一个和最后一个元素。通过修改两个指针实现“先进先出” ,节省了操作时间。添加一个元素时,Tail=Tail mod maxsize + 1;删除一个元素时,Head=Head mod maxsize + 1。当Head 与 Tail 相等时,表示该队列为空;当 Head=(Tail mod maxsize) + 1 时,队列为满。环形队列示意图MessageBox 对话框模块对话框模块在编辑器中,我们增加了对话框模
13、块,如图所示:对话框模块存放在 MESSBOX.H 和 MESSBOX.C 文件中。主要调用函数声明如下:int MessageBox(char *messtr, char *title, MESSAGETYPE choice);参数说明:char *messstr 为信息字符串,不能为空char *title为标题字符串,可以为空(”或 NULL)MESSTYPEINFO choice为按钮类型选择参数。共有以下几种选择:Q_YESNO=1Q_YESQ_YESNOCANCELIN_YESNOIN_YESIN_YESNOCANCELIN_OKIM_YESNOIM_YESIM_YESNOCANC
14、EL E_YESNOE_YESE_YESNOCANCELE_OKINPUT其中,Q_xxx 为疑问对话框(Questioning),IN_xxx 为信息对话框(Information),IM_xxx 为重要信息对话框(Important information),E_xxx 为错误对话框(Error),特别地,INPUT 为输入对话框的入口参数。返回值说明:如果选择左边第一的按钮,返回 1;左边第二个按钮,返回 2;以此类推。显示输显示输出出模块模块显示输出模块主要采用直接写视屏内存的方法来实现。通过视屏的端口0 x3ce,0 x3cf,0 x3c4,0 x3c5 和视屏的内存地址 0 xa0
15、000000 的直接操作来组成视屏显示的一系列函数。虽然通过直接写视屏的方式来实现的函数有一些移植性问题,但是大大提高了显示的速度,在鱼和熊掌不可兼得的情况下只好采取这样的措施。文件列表文件列表LIST.C内核数据操作函数库CURSOR.C光标操作函数库EDITOR.C键盘操作IMD.C输入法操作函数库MAIN.C主过程OPENDLG.C“打开”对话框的程序文件UNDO.CUndo 的程序文件GOUTPUT.H汉字显示的函数文件WINFUNC.H窗口绘制的函数文件FACE.C界面的程序文件HZK16汉字库文件XMS_OBJ.OBJWB.IMD五笔输入法文件PY.IMD拼音输入法文件功能模块函数
16、列表功能模块函数列表LIST.C该文件中提供如下的功能函数(列表)函数名称参数声明功能介绍InitDocument()初始化文档void InitLinenote()LINE_NOTE *lnvoid InitDocument()void AppendLine()void AppendChar()char c, char c1int AppendString()const char *s, int option添加一个字符串option 为 1,在末尾添加option 为 0,在当前位置添加void ReleaseAll()释放所有节点int NextLine()当前行指针下移int PreL
17、ine()当前行指针上移int GetLineLength()取得当前行的长度int GetLines()取得总行数int SeekLine(int LineNo)按行号移动指针int SeekLineTail()移动到最末行int SeekLineHead()移动到首行int SeekHead()移动到当前行的开始int SeekTail()移动到当前行的最末节点int NextChar()下一个字符int PreChar()前一个字符int SeekChar(int x)按标号移动指针int IsEmptyLine()测试该行是否为空void InsertAfter()char c, ch
18、ar c1后插一个节点void InsertBefore()char c, char c1前插一个节点void DeleteBefore()删除前一个节点void DeleteChar()删除当前节点void DeleteHead()删除一行最先的一个节点void DeleteTail()删除一行最后的一个节点void DisplayLine()显示一行int Free(CHAR_NOTE *p)释放节点空间int WriteTxt()char *filename写入文件void InsertLineAfter()在当前行后插一行void EnterLine()在当前实现换行功能,即把当前字符
19、以后的字符下移一行void DeleteCurrentLine()N/A删除当前行void Delete()CHAR_NOTE *pChar删除当前字符int Undo()N/A实现 Undo 功能void SetBlock()int x1, int y1, int x2, int y2设置块void ClearBlock()N/A清除定义的块其中 Document 是由 DOCUMENT 的结构体定义的变量。DOCUMENT 定义如下:struct DOCUMENT_typeLINE_NOTE *pHead;LINE_NOTE *pTail;LINE_NOTE pCur;/*当前行的指针*/
20、CHAR_NOTE pCChar;/*点前字符指针*/int Caretx;int Lines;其中 pCur 指向当前接受操作的一行,pCChar 指向当前行中接受操作的一个字符,若为NULL,则指向该行的最末。SeekChar(), NextChar(), PreChar(), SeekLine(), NextLine(), PreLine()等函数都是设定 pCChar 和 pLine 的函数。一些插入、删除的函数要求在之前将pCur 和 pCChar 设置好。EDITOR.C函数名称参数声明功能介绍void DisplayAll(int Lines)显示当前页的模块void KeyUp
21、()光标键控制模块void KeyDown()void KeyLeft()void KeyRight()void KeyEnter()回车换行控制模块void KeyEsc()ESC 键控制模块void KeyCtrl_Y()删除一行(Ctrl-Y)控制模块void KeyPagedown()翻页控制模块void KeyPageup()void KeyF3()快控制模块void KeyF4()void KeyF5()void KeyBackspace()回退键控制模块void KeyDelete()删除键控制模块void KeyHome()将光标移到行首void KeyEnd()将光标移到行末
22、void KeyCtrl_Z()Undo 模块int QuitBox()退出询问模块int SaveBox()保存文件对话框void CheckXY()检查坐标函数void AddChar(char c)添加一个字符模块void AddString(char *s)添加字符串模块void _EditorInit()编辑器初始化模块void Processor()编辑环境的主要处理模块int ScrollDown(int n)滚屏函数int ScrollUp(int n)void Gotoxy(int x, int y)移动光标函数void SetBlockStart()设置块的起始和终点模块v
23、oid SetBlockEnd()void MakeBlock()生成一个块int Load(char *Filename)读入一个文件BITMAP.HI. How come. 当我们在设计图形按钮和菜单功能的时候,首先考虑使用即时绘图来实现各种动态效果,然而即时绘图有很多缺憾:在程序中加入鼠标支持后,即时绘图会受鼠标的影响,具体就是鼠标指针也是位图,在绘图时可能鼠标指针会遮盖部分区域导致绘图函数不能正常工作,从而留下这些区域没有正常显示,除非经常刷新。绘图函数是通过一个一个像素画到屏幕上去的,可见效率是比较低的。 因此,我们需要有能够快速地把图片显示到屏幕上。通常有两种做法:1.直接写入屏幕
24、缓冲区,但使用了 Turbo C/C+的图形库之后就不行了(我们这个程序已经使用了图形库,再更改就太.) ,2.使用 Turbo C/C+提供的一些直接写屏的函数:getimage,putimage,imagesize。这些函数是能够实现动画效果的。但是我的想法是能够动态的生成菜单项,即根据菜单项中字符串的大小来决定菜单项的大小。于是就考虑自己来生成 Turbo C/C+使用的 Bitmap Buffer.II. . Crack it. 要直接生成 Bitmap Buffer,必然需要了解它的结构和各方面的细节。然而 Borland 公司从来就没有仔细的描述 getimage 函数所使用的图形
25、缓冲,只是给出前两个字分别是图片的宽和高。没办法了,破解吧,也好过过做个软件黑客的瘾,呵呵! 首先,做个程序将 16 种色素分别画到屏幕上(原为竖立的,现将它横过来便于显示): 将它用 getimage 保存到一块内存区域中,并且一个字节一个字节地显示出来:00000f00图片的宽(width)和高(height)00000000Palette 0, (默认为)BLACK00000080Palette 1, BLUE00008000Palette 2, GREEN00008080Palette 3, CYAN00800000Palette 4, RED00800080Palette 5, MA
26、GENTA00808000Palette 6, BROWN00808080Palette 7, LIGHTGRAY80000000Palette 8, DARKGRAY80000080Palette 9, LIGHTBLUE80008000Palette 10, LIGHTGREEN80008080Palette 11, LIGHTCYAN80800000Palette 12, LIGHTRED80800080Palette 13, LIGHTMAGENTA80808000Palette 14, YELLOW80808080Palette 15, WHITE0000 结束字 明白了吗?Turb
27、o C/C+定义了 16 种调色板颜色通过四个字节来表示,哪种颜色使用哪些字节一目了然吧!这些是通过一条竖直的 16 色线得到的,那么画一条横线的情况会是怎么样呢?好,首先画一条 8 个像素的蓝色横线: 再次用 getimage 的方法将缓冲区的字节都显示出来:07000000同上(但这次宽是 7+1 个像素,高为 1 个像素)000000FF看到了吧,对比上文,蓝色像素只同第四个字节相关哦0000 通过以上的例子,我们已经对 Turbo C/C+的图形缓冲区有了初步的了解,接下来.嗯.当然是更深入的研究,呵呵,我们要从一个井底之蛙变成一只活蹦乱跳的青蛙哦。OK,Lets go! 通过再次的试
28、验,我们将蓝色横线伸长为 16 个像素(或者其它大于 8 个像素也可,主要用于验证) ,我们会发现缓冲区变为:0F000000宽为 15+1 个像素000000000000FFFF奇怪吧,为什么呢0000 呵呵,这就是 Borland 公司的大师们设下的陷阱哦,一不小心就会迷失方向。其实那是相当容易的一个问题.那就是.,等一下,别急,让我们来具体探讨一番: 首先,在图形缓冲区中,像素信息是一行一行记载的,每一行又由许多组数据组成,每一组数据由四个字节组成,并且一组数据可以保存 8 个像素。那么,每四个字节又是如何保存 8 个像素的信息的呢?从上文可以知道,每一种调色板颜色在这四个字节中对应特定
29、的几个字节,而且一组数据中的第一个像素在对应字节上的第一位设为 1,第二个像素在第二位设为 1,.,以此类推。若还搞不明白,请看下面的图示: 00第一个字节 00第二个字节 00第三个字节 FF第四个字节 第四个字节全赋值为 1 说明横向连续画 8 个蓝点。如果有颜色不相同的像素彼此交错呢?呵呵,很简单,也是按照这个规律,第几个像素就在其对应字节的第几位上设为 1。 其次,各组像素信息设置好以后,需要将每组的四个字节交错排列,也就是先第一组的第一个字节,第二组的第一个字节,.,第一组的第二个字节,第二组的第二个字节,.,第一组的第三个字节,第二组的第三个字节,.,以此类推。 再次,当一行信息处
30、理完成后,不管其是否有多余,都重新建立新的一行。总之,缓冲区的每一行都是互不相关的。 至此,Turbo C/C+的图形缓冲区中像素信息在横向和纵向上的表示方法,我们都已经搞清楚了。现在,我想大家都有点摩拳擦掌了吧,让我们来小试身手。下面是一张简单的图片(分辨率是 165):0f000400注意宽和高分别为原图片减 10efb0efb0efbffff7efb7efb7efbffff782078207820ffff7efb7efb7efbffff0efb0efb0efbffff0000 这个例子能充分理解了吗(先用 2 进制编码,再转成 16 进制)?好,我们继续我们的征程.III. First
31、Use the Power . 通过上面的“潜心研究”之后,我就开始动手编了一系列的函数来处理 Turbo C/C+的图形缓冲区,还有个函数直接将 Windows 的 BMP 文件(这个格式最简单嘛)转成图形缓冲区的格式,以便直接调用 putimage 将其显示在屏幕上,以下是一些函数的说明。1.1. void far *LoadImage(char *pszFileName); 将文件名为 pszFileName 的 16 色 BMP 文件装载到图形缓冲区,返回值为图形缓冲区的指针地址。注意:ceil(宽度/8)*4*高度6 的大小要求不能超过 64KB。2.2. void SetPalet
32、te(FILE *pFile); 根据 16 色 BMP 文件的调色板来设置 VGAHI 模式下的调色板,pFile 为文件句柄的指针。3.3. void ConvertLine(BYTE *pbBMPLine, BYTE *pbLine, BYTE bBMPLineSize, BYTE bLineSize); 将一行 BMP 像素信息转成图形缓冲格式。 (1)pbBMPLine 为 BMP 文件一行数据的指针; (2)pbLine 为该行图形缓冲区的指针; (3)bBMPLineSize 为 BMP 文件该行数据的字节数; (4)bLineSize 为该行图形缓冲区的字节数。4.4. voi
33、d ConvertPixels(BYTE *pbBMPGroupInfo, BYTE *pbGroupInfo, BYTE bBMPGroupSize); 将一行中的一组 BMP 像素信息(8 个像素)转换成图形缓冲格式。 (1)pbBMPGroupInfo 为 BMP 文件该行中一组像素数据的指针; (2)pbGroupInfo 为该组图形缓冲区的指针; (3)bBMPGroupSize 为 BMP 文件该组数据的字节数。 (由于 BMP 文件最后一组像素是实际的字节数,即 2 个像素每字节,然而图形缓冲区无论一组有多少像素(小于等于 8个)都是四个字节,故要设定 BMP 文件在该组像素数据
34、的字节数。 )5.5. void far *CreateBuffer(WORD wWidth, WORD wHeight, BYTE bBkColor); 根据给定的宽度(wWidth) ,高度(wHeight)来创建一个图形缓冲区,背景色是bBkColor 所指定的颜色。注意:ceil(宽度/8)*4*高度6 的大小要求不能超过 64KB。IV. Future Improvement . 以后可以针对 Turbo C/C+的图形缓冲区,编写一系列的绘图函数,如画点,画线,画圆等等,有了这些函数,我们就可以动态地修改缓冲区,即时地改变缓冲区的内容,以便能够用 putimage 轻而易举地直接把
35、改变的画面显示到屏幕上。相信这样做还是有一定的应用价值的,呵呵,只是现在 Windows 如日中天(托胎于 Dos,却又大义灭亲) ,而 Dos已经无人问津了啊!WINFUNC.HI. Design Purpose . 在“遥远”的过去,Dos 下的编辑器很少有漂亮的图形界面。而现在,我们习惯了Windows 下花哨绚丽的界面,回过头来制作 Dos 下的文本编辑器,不来点图形化的见面,难免有点对不起我们的视网膜,至少是有点不习惯吧!于是,我们决定制作一个在Turbo C/C+的图形模式 VGAHI(640480 16 色模式)下的中文图形编辑器。 时下,流行模块化、面向对象化的程序设计方法,但
36、我们是用 C 语言来编写这个软件,就不可能大量地使用 C+的面向对象的要素。因此,我就只是设计了这个头文件,里面包含了,窗体,按钮,菜单的结构,以及对这些对象操作的一系列函数。II. . The Data Structure . 由于我使用了一些面向对象的思想,因此也不免要建立包含这些对象具体属性的结构。下面是我建立的数据结构以及它们的介绍: 1.窗体结构struct WindowWORD wX;左上角 X 坐标WORD wY;左上角 Y 坐标WORD wWidth; 宽度WORD wHeight;高度BYTE bColor; 前景色BYTE bBackColor; 背景色BYTE bTopC
37、olor;上边框颜色BYTE bBottomColor;下边框颜色BYTE bLeftColor; 左边框颜色BYTE bRightColor;右边框颜色;typedef struct Window WINDOW;typedef struct Window * PWINDOW; 2.按钮结构struct Buttonchar *pszTitle;名称WORD wX;左上角 X 坐标WORD wY;左上角 Y 坐标WORD wWidth;宽度WORD wHeight;高度BYTE bColor;前景色BYTE bBorderColor;边框颜色BYTE bBackColor;背景色BYTE bM
38、ouseOver;判断鼠标是否在按钮上struct Button *pBack;上一个按钮指针struct Button *pNext;下一个按钮指针struct Menu *pMenu; 对应的菜单指针;typedef struct Button BUTTON;typedef struct Button * PBUTTON; 按钮数据结构示意图: 按钮 1按钮 2按钮 3 . 按钮 N 3.菜单项结构struct MenuItemchar *pszTitle;名称void far (*pFunction)();包含的指向函数的指针struct MenuItem *pNext;下一个菜单项指针
39、;typedef struct MenuItem MENUITEM;typedef struct MenuItem * PMENUITEM; 4.菜单样式结构struct MenuStyleBYTE bColor;前景色BYTE bBorderColor;边框颜色BYTE bBackColor;背景色BYTE bItemColor;菜单项颜色;typedef struct MenuStyle MENUSTYLE;typedef struct MenuStyle * PMENUSTYLE; 5.菜单结构struct MenuWORD wWidth;宽度WORD wHeight;高度BYTE bN
40、o;当前指向第几个菜单项BYTE bNum;菜单项的数量BYTE bShown;判断菜单是否被显示struct MenuStyle *pStyle;对应的菜单样式指针struct MenuItem *pFirst;指向第一个菜单项void far *pCovered;菜单所覆盖的屏幕缓冲的指针void far *pLightBar;菜单项亮条图形缓冲的指针;typedef struct Menu MENU;typedef struct Menu * PMENU; 菜单数据结构示意图: 菜单 1菜单项 1菜单项 2 . 菜单项 N 菜单样式 菜单 2 . (菜单样式可以为多个菜单共享) II.
41、The Functions . 建立了数据结构之后,就着手开始大刀阔斧地进行编写函数的最后攻坚战了!以下是一系列的函数: 1.窗体函数void CreateWindow(char *pszTitle, PWINDOW pWindow, int hasStatusBar);根据给定的窗体标题,定义好的窗体结构来创建一个窗体,并显示在屏幕上。 (1)pszTitle 为窗体的标题; (2)pWindow 为窗体结构的指针; (3)hasStatusBar 决定窗体是否带有状态栏。void *CopyWindow(PWINDOW pWindow);将所给窗体所将要覆盖的屏幕区域保存到一个图形缓冲区,
42、pWindow 为所给窗体的指针,返回值为指向该图形缓冲区的指针。 void HideWindow(PWINDOW pWindow, void *pCovered);将显示的窗体隐藏起来。 (1)pWindow 为所要隐藏的窗体; (2)pCovered 为预先保存的屏幕区域。 2.按钮函数void CreateButton(PBUTTON pButton);根据定义好的按钮结构来创建一个按钮,并显示在屏幕上,pButton 为按钮结构的指针。PBUTTON AddButton(char *pszTitle, PBUTTON pButton, PMENU pMenu, WORD x, WORD
43、 y, BYTE bColor, BYTE bBorderColor, BYTE bBackColor);增加一个按钮在一个按钮链表(双向链表)中。 (1)pszTitle 为所加按钮的名称; (2)pButton 为按钮链表中的前一个按钮; (3)pMenu 为所加按钮所对应的菜单的指针; (4)x 为所加按钮左上角的 X 坐标; (5)y 为所加按钮左上角的 Y 坐标; (6)bColor 为所加按钮的前景色; (7)bBorderColor 为所加按钮的边框颜色; (8)bBackColor 为所加按钮的背景色;函数返回值为所增加的按钮的指针。PBUTTON SearchButton(c
44、har *pszTitle, PBUTTON pButton);根据给定的字符串,在按钮链表中搜索所需的按钮。 (1)pszTitle 为要搜索按钮的名称; (2)pButton 为按钮链表中任意一个按钮皆可。函数返回值为所需按钮的指针。void SetButtonUp(PBUTTON pButton);将 pButton 所指向的按钮设置为按钮浮起状。void SetButtonDown(PBUTTON pButton);将 pButton 所指向的按钮设置为按钮按下状。void SetButtonBack(PBUTTON pButton);将 pButton 所指向的按钮设置为原状。PBU
45、TTON ChooseButton(char *pszTitle, PBUTTON pButton, PBUTTON pBtnHead);根据给定的字符串,将按钮链表中的指定的按钮设置为浮起状,并将对应的菜单都显示出来(这是用来实现菜单功能的函数) 。 (1)pszTitle 为要搜索按钮的名称; (2)pButton 为当前已经选定的按钮(需要将其恢复原状用) ,否则置为 NULL; (3)pBtnHead 为按钮链表中任意一个按钮的指针作为头指针;函数返回值为新选择的按钮指针。PBUTTON GoButtonLeft(PBUTTON pButton);将按钮和菜单选择向左移动,pButto
46、n 为当前显示的按钮(这也是用来实现菜单功能的函数) 。PBUTTON GoButtonRight(PBUTTON pButton);将按钮和菜单选择向右移动,pButton 为当前显示的按钮(这也是用来实现菜单功能的函数) 。 3.菜单函数void DisplayMenu(PMENU pMenu, PBUTTON pButton);显示所指定的菜单。 (1)pMenu 为菜单的指针; (2)pButton 为对应菜单的按钮的指针(用来决定菜单的坐标) 。void HideMenu(PMENU pMenu, PBUTTON pButton);隐藏所指定的菜单。 (1)pMenu 为菜单的指针;
47、 (2)pButton 为对应菜单的按钮的指针(用来决定菜单的坐标) 。PMENUITEM AddMenuItem(char *pszTitle, PMENU pMenu, void far (*pFunction)();根据给定字符串作为菜单项名,增加一项菜单项。 (1)pszTitle 为菜单项名; (2)pMenu 为菜单项所在的菜单的指针; (3)pFunction 为函数的指针,用以实现菜单项的功能。函数返回值为新增加的菜单项的指针。void SelectMenu(PMENU pMenu, PBUTTON pButton, int iNo);选择菜单的某一菜单项,即将光条移到该菜单项
48、。 (1)pMenu 为菜单项所在菜单的指针; (2)pButton 为菜单对应的按钮的指针(用以给出菜单的坐标) ; (3)iNo 决定第几个菜单项。void UnSelectMenu(PMENU pMenu, PBUTTON pButton, int iNo);取消菜单项的选择,除去光条,各参数同上。void GoMenuUp(PMENU pMenu, PBUTTON pButton);将菜单的光条向上移动。 (1)pMenu 为所在菜单的指针; (2)pButton 为菜单对应的按钮的指针(用以给出菜单的坐标) 。void GoMenuDown(PMENU pMenu, PBUTTON
49、pButton);将菜单的光条向下移动,各参数同上。void ClickMenu(PMENU pMenu, PBUTTON pButton);实现当前光条所在菜单项的功能(菜单项结构所含的函数) ,各参数同上。III. Apply The Header . 以上将结构和函数都一一给大家“观赏”了一番,不来点实际的总是不完满的,对吗?下面,我为编辑器所制作的界面(face.c)就是这些的实际应用: 1.各常量的定义 由于界面结合了键盘操作,所以定义了一些键盘键码。 2.全局变量的定义(1)MainWin 为编辑器的主窗体;(2)AboutWin 为关于窗体;(3)MenuStyle 为菜单样式;
50、(4)MenuFile,MenuEdit,MenuSearch 为各菜单;(5)pBtnHead 为按钮链表的头指针;(6)pCurrentBtn 代表当前选择的按钮;(7)pCurrentMenu 代表当前显示的菜单。 3.创建编辑器的界面(1)void SetMenus(void)函数用于建立各菜单。 使用 AddMenuItem 函数来添加各菜单项,具体使用参照前面的函数说明。(2)void SetButtons(void)函数用于建立按钮链表。 使用 AddButton 函数将所要添加的按钮组成一个双向链表,便于按钮的操作。(3)int InitEditorInterface(void
51、)函数用于启动编辑器的界面。 4.界面的操作与管理 原本还加入了鼠标的支持(mouse.h) ,由于 Windows 2000 下 DOS 图形模式下,鼠标指针不能正常显示,而且也没有比较好的解决方法(还有就是鼠标的操作也比较麻烦,这也是很重要的一条啊,呵呵) 。因此,界面的操作仅限于键盘操作。 键盘的操作应用了消息的循环方法,通过 kbhit()检测是否有按键消息,若有则,使用分支结构来处理各个消息(按键健码) 。 5.主要就是这些了.GOUTPUT.H功能介绍:参数说明:void InitialzeGraph(void);初始化整个图形输出函数库void FinishMission(voi
52、d);图形输出函数库的析构函数char far *ObtainAddress(void);获得 ROM 中 ASCII 码的地址void DisableCursor(void);禁止光标的显示void EnableCursor(void);允许表表的显示void ShowCursor(unsigned int x,unsigned int y);x,y 分别为光标左上角的 x 和 y 坐标显示光标void RecoverCursor(unsigned int x,unsigned int y);x,y 分别为光标左上角的 x 和 y 坐标恢复光标显示位置的图像void interrupt fa
53、r CursorHandler();显示光标的时间中段句柄的函数int Locate(unsigned int x,unsigned int y);x,y 分别为光标左上角的 x 和 y 坐标坐标定位int CursorLeft(void);光标左移int CursorRight(void);光标右移int CursorUp(void);光标上移int CursorDown(void);光标下移unsigned int GetScreenX(void);获取光标 x 轴位置unsigned int GetScreenY(void);获取光标 y 轴位置void SetSpaceLine(uns
54、igned int n);n 为行数清第 n 行void SetSpaceClientLine(unsigned int n);n 为列数清当前行第 n 列后的所有字符void ScrollWindowUp(unsigned int n);n 为行数显示区域上滚到第 n 行void ScrollWindowDown(unsigned int n);n 为行数从第 n 行后显示区域下滚void GPutc(unsigned char s1,unsigned char s2);字符的第一个内码,若字符为 ASCII 则 s1位字符的 ASCII码,s2=0;若字符为汉字则 s1,s2分别为汉字的区
55、位码显示字符(包括 ASCII 和汉字)void GetHZ(char incode,char bytes); incode 汉字的内码数组(前两个字节有用)bytes 返回汉字字模的数组获取汉字字模void CloseHZK();关闭汉字字模库文件void OpenHZK(void);打开汉字字模库文件void PutASCColor(unsigned int x0,unsigned int y0, unsigned char s,unsigned int color,unsigned int bkcolor); x0,y0 位字符的坐标,s 为字符的 ASCII 码,color,bkcol
56、or 为字符的前景色和背景色在特定位置用特定颜色显示ASCII 字符void PutCNColor(unsigned int x0,unsigned int y0, unsigned char *s,unsigned int color,unsigned int bkcolor); x0,y0 位字符的坐标,s 为汉字内码的指针,color,bkcolor 分别为字符的前景色和背景色在特定位置用特定颜色显示汉字字符void GPuts(unsigned char *s);字符串的指针显示字符串void GPutsColor(unsigned int x0,unsigned int y0,uns
57、igned char *s,unsigned int color,unsigned int bkcolor);x0,y0 位字符的坐标,s 为字符串的指针,color,bkcolor 分别为字符的前景色和背景色在特定位置用特定颜色显示字符串IMD.HBYTE GetColor(BYTE data, BYTE forecolor, BYTE backcolor, BYTE i);void Bar(int x,int y,int w,int h,int bkcolor);清一矩形int LIMD(BYTE *file,int i);装入汉字输入法 IMD 文件WORD GetInputWord(B
58、YTE *buf);取用户输入的汉字或 ASCII 字符void GetWord(BYTE *,BYTE *);int IsInTable(BYTE c);void ShowCodeMsg(BYTE *s); 在提示行显示汉字编码字符void SetIMD(int i); 设置当前所用的汉字输入方法void SetWordMode() ; 设置全半角(热键为 Ctrl+F9)void ShowCwordMsg(BYTE *s); 在提示显示输入的汉字void ClearShowCword(); 清显示输入重码汉字提示区void ClearShowCode(); 清显示编码提示区WORD Ini
59、tializeIMD(void); 初始化函数void IMD(void);析构函数BYTE GetErrorCode()取错误代码功能函数的算法说明功能函数的算法说明(部分部分)AppendChar() 在末尾追加一个字符在末尾追加一个字符执行该操作时,主要有两种情况:1 pEnd 不为空。pEnd-pNext=pNewChar;2.pEnd 为空。说明该行没有节点,这是只要添加一个节点即可。void interrupt far CursorHandler()显示光标的时间中显示光标的时间中段句柄的函数段句柄的函数本函数在图形显示函数初始化过程中被设置成时间中段程序。本函数有一个计算本函数执
60、行次数的全局变量 HandlerTimes。时间中段每秒钟执行 18.5 次,每执行一次时间中段 HandlerTimes 就加一,当 HandlerTimes 的值为 3 时,就执行一次函数中显示光标的函数 ShowCursor()或恢复光标图像的函数 RecoverCursor(),于是每经过大约 1/3 秒的时间光标就闪烁一次。而程序中是如何确定要显示还是要恢复光标呢?程序模块中有一个全局变量 flag 他被初始化为 0,当 flag 为 0 并且光标的位置不超出显示区域时,就调用显示光标的函数 ShowCursor(),然后把 flag 设为 1。当 flag 为 1 并且光标的位置不
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年腰椎间盘突出预防与康复锻炼讲座
- 2026江苏盐城市大丰兴丰工程建设有限公司招聘劳务派遣人员1人备考题库附答案详解ab卷
- 2026年火锅店成本控制与菜品定价
- 2026年药品物流企业仓储运输管理制度与应急预案
- 2026内蒙古呼伦贝尔市满洲里市事业单位招聘29人考试备考试题及答案解析
- 2026年上半年江西省城乡规划市政设计研究总院有限公司社会招聘6人考试参考题库及答案解析
- 市政给水管网开挖施工方案
- 2026中国移动铁通易门支撑服务中心招聘1人笔试备考试题及答案解析
- 小学生抗挫折能力2025
- 2026广东惠州市惠城区中医医院第二批编外人员招聘7人考试模拟试题及答案解析
- 2026重庆联合产权交易所集团股份有限公司招聘13人考试备考试题及答案解析
- 2026中国文创产品市场消费趋势与商业模式创新研究报告
- 2026中考语文试题分类汇编《作文》练习题
- 2026年辽宁省二级建造师继续教育复习真题AB卷附答案详解
- 2025年冀人版三年级科学下册全套测试卷新版
- 带状疱疹临床路径完整版
- 智慧工地方案施工方案(3篇)
- 北京2025年国家艺术基金管理中心招聘应届毕业生笔试历年参考题库附带答案详解(5卷)
- 《安全预评价提供基础资料清单》
- 15.球的运动(课件)2025-2026学年人教鄂教版三年级科学下册
- 2026年教案合集2026年春人教版八年级下册英语Unit 1~Unit 8全册教案新版
评论
0/150
提交评论