1、 高级编程技术介绍如何利用 TC 系统所提供的相关函数实现菜单设计、图形绘制、动画的播放、乐曲的演奏、汉字的显示、图片的显现等技术,在讲述时,以问题-解答的方式来逐渐阐明。1 文本的屏幕输出和键盘输入 . 11.1 文本的屏幕输出.11.2 键盘输入.81.3 问题实现.11 1.4 高级应用菜单实现 .14实验一.232 图形显示方式和鼠标输入.232.1 图形显示.232.2 鼠标的使用.522.3 问题实现.58实验二.623 屏幕图象与动画技术.633.1 一个简单的实现方法633.2 利用动态开辟图视口的方法.663.3 利用屏幕图象存储再放的方法.673.4 利用页交替的方法.70
2、3.5 问题实现.71实验三.744 中断技术 744.1 编写自己的中断程序.764.2 问题实现784.3 其它应用硬中断演示秒表程序 .84实验四.875 发声技术 875.1 声音函数.875.2 计算机乐谱.885.3 问题实现.89实验五.936 汉字显示技术 936.1 汉字编码.936.2 问题实现.95实验六.97使用过 Windows 系统的用户都感受到了图形用户界面的直观和高效。所有 Windows 系统的应用程序都拥有相同或相似的基本外观,包括窗口、菜单、工具条、状态栏等。用户只要掌握其中一个,就不难学会其它软件,从而降低了学习成本和难度。而且 Windows 是一个多
3、任务的操作环境,它允许用户同时运行多个应用程序,或在一个程序中同时做几件事情。例如,我们可以边欣赏 MP3 的音乐边 IE 冲浪,可以在运行 WORD 时同时编辑多个文档等。用户直接通过鼠标或键盘来使用应用程序,或在不同的应用程序之间进行切换,非常方便。这些都是单任务、命令行界面的 DOS 操作系统所无法比拟的。TC2.0 或 TC3.0 均是在 DOS环境下运行的 C 系统。不过,无论采用 TC,还是 VC、BC ,所产生的 C 可执行程序都是基于 DOS 系统的。C 语言发展如此迅速,而且成为最受欢迎的语言之一,主要因为它具有强大的功能。C是一种“中”级语言,它把高级语言的基本结构和语句与
4、低级语言的实用性结合起来。C 语言可以对位、字节和地址进行操作,而这三者是计算机最基本的工作单元。C 语言具有各种各样的数据类型,并引入了指针概念,可使程序效率更高。另外 C 语言也具有强大的图形功能,支持多种显示器和驱动器。而且计算功能、逻辑判断功能也比较强大,可以实现决策目的。C 系统提供了大量的功能各异的标准库函数,减轻了编程的负担。所以要用 C 语言实现具有类 Windows 系统应用程序界面特征的、或更生动复杂的 DOS 系统的程序,就必须掌握更高级的编程技术。这些技术与微机的硬件密切联系,除了在第一章介绍的内容外,更深入的知识将在接口和汇编这门后期课程中学习。1 文本的屏幕输出和键
5、盘输入 问题的提出 编制一个程序,将屏幕垂直平分成两个窗口,左边窗口为蓝色背景,白色前景,右边窗口为绿色背景,红色前景。两个窗口都设计为文本输入,即在窗口中可以输入文字,在窗口屏幕中显示出来。使用 tab 键在左右两个窗口中切换,每个窗口都有光标,活动窗口光标进行闪烁。分析 在这个问题中我们遇到了在初学 C 时不曾接触到的新概念,如文本窗口、前景色、背景色,以及围绕它们要解决的新问题:(1) 如何在屏幕中开文本输入的窗口?(2) 如何设置窗口的前景色、背景色或闪烁等显示属性?(3) 如何通过按键来控制窗口的切换?解答 要解决这一编程问题,要求有两方面的学习过程:一是对于分析中的前两个问题,要求
6、大家了解有关文本的屏幕输出的知识;二是对于第 3 个问题,要求对键盘的输入有所了解。下面先就这两个方面的内容做一介绍。1.1 文本的屏幕输出显示器的屏幕显示方式有两种:文本方式和图形方式。文本方式就是显示文本的模式,它的显示单位是字符而不是图形方式下的象素,因而在屏幕上显示字符的位置坐标就用行和列表示。Turbo C 的字符屏幕函数主要包括文本窗口大小的设定、窗口颜色的设置、窗口文本的清除和输入输出等函数。这些函数的有关信息(如宏定义等 )均包含在 conio.h 头文件中,因此在用户程序中使用这些函数时,必须用 include 将 conio.h 包含进程序。1) 文本窗口的定义Turbo
7、C 默认定义的文本窗口为整个屏幕,共有 80 列 25 行的文本单元。如图 3-1 所示,规定整个屏幕的左上角坐标为(1,1),右下角坐标为(80,25),并规定沿水平方向为 X1轴,方向朝右;沿垂直方向为 Y 轴,方向朝下。每个单元包括一个字符和一个属性,字符即 ASCII 码字符,属性规定该字符的颜色和强度。除了这种默认的 80 列 25 行的文本显示方式外,还可由用户通过函数:void textmode(int newmode);来显式地设置 Turbo C 支持的 5 种文本显示方式。该函数将清除屏幕,以整个屏幕为当前窗口,并移光标到屏幕左上角。newmode 参数的取值见表 3-1,
8、既可以用表中指出的方式代码,又可以用符号常量。LASTMODE 方式指上一次设置的文本显示方式,它常用于在图形方式到文本方式的切换。(1 列,1 行)第一列第一行第 25 行图 3-1 屏幕文本显示坐标表 3-1 文本显示方式第 80 列(80 列,25 行)方式0123符号常量BW40C40BW80C80显示列u34892X 数和颜色4025 黑白显示4025 彩色显示8025 黑白显示8025 彩色显示7 MONO-1 LASTMODE8025 单色显示上一次的显示方式Turbo C 也可以让用户根据自己的需要重新设定显示窗口,也就是说,通过使用窗口设置函数 window() 定义屏幕上的
9、一个矩形域作为窗口。window() 函数的函数原型为:void window(int left, int top, int right, int bottom);函数中形式参数(int left ,int top)是窗口左上角的坐标,( int right,int bottom)是窗口的右下角坐标,其中(left,top)和(right ,bottom )是相对于整个屏幕而言的。例如,要定义一个窗口左上角在屏幕(20,5)处,大小为 30 列 15 行的窗口可写成:window(20, 5, 50, 25);若 window()函数中的坐标超过了屏幕坐标的界限,则窗口的定义就失去了意义,也就
10、是说定义将不起作用,但程序编译链接时并不出错。窗口定义之后,用有关窗口的输入输出函数就可以只在此窗口内进行操作而不超出窗口的边界。另外,一个屏幕可以定义多个窗口,但现行窗口只能有一个(因为 DOS 为单任务操作系统)。当需要用另一窗口时,可将定义该窗口的 window()函数再调用一次, 此时该窗口便成为现行窗口了。2) 文本窗口颜色和其它属性的设置文本窗口颜色的设置包括背景颜色的设置和字符颜色(既前景色)的设置,使用的函数及其原型为:2设置背景颜色函数:void textbackground(int color);设置字符颜色函数:void textcolor(int color);有关颜色
11、的定义见表 3-2。表中的符号常数与相应的数值等价,二者可以互换。例如设定兰色背景可以使用 textbackground(1),也可以使用 textbackground(BLUE) ,两者没有任何区别,只不过后者比较容易记忆,一看就知道是兰色。表 3-2 颜色表符号常数BLACKBLUEGREENCYANREDMAGENTABROWNLIGHTGRAY 7DARKGRAY 8LIGHTBLUELIGHTGREENLIGHTCYANLIGHTREDLIGHTMAGENTA YELLOWWHITE数值0123456910111213 1415含义黑蓝绿青红洋红棕淡灰深灰淡蓝淡绿淡青淡红淡洋红黄白背
12、景或背景前景、背景色前景、背景色前景、背景色前景、背景色前景、背景色前景、背景色前景、背景色前景、背景色用于前景色用于前景色用于前景色用于前景色用于前景色用于前景色用于前景色用于前景色BLINK 128 闪烁 用于前景色Turbo C 另外还提供了一个函数,可以同时设置文本的字符和背景颜色,这个函数是文本属性设置函数:void textattr(int attr);参数 attr 的值表示颜色形式编码的信息,每一位代表的含义如下:字节低四位 cccc 设置字符颜色, 46 三位 bbb 设置背景颜色,第 7 位 B 设置字符是否闪烁。假如要设置一个兰底黄字,定义方法如下:textattr(YE
13、LLOW+(BLUE#include int main()int i; textbackground(0); /* 设置屏幕背景色,待 clrscr 后起作用 */clrscr();for(i=1; imain()int i;char ch4*8*2;textmode(C80);/* 定义 ch 字符串数组作为缓存区 */textbackground(BLUE);textcolor(RED);clrscr();gotoxy(10,10);cprintf(“L:load“);gotoxy(10,11);cprintf(“S:save“);gotoxy(10,12);cprintf(“D:dele
14、te“);gotoxy(10,13);cprintf(“E:exitrn“);cprintf(“Press any key to continue“);getch();gettext(10,10,18,13,ch); /*存矩形区文存到 ch 缓存区 */clrscr();textbackground(1);textcolor(3);window(20,9,34,14);clrscr();/* 开一个窗口 */cprintf(“1.r n2.rn3.rn4.rn“);/* 纵向写 1,2,3,4 */movetext(20,9,34,14,40,10); /*将矩形区文本复制到另一区域 */p
15、uts(“hit any key“);getch();clrscr();cprintf(“press any key to put text“);getch();clrscr();puttext(23,10,31,13,ch); /* 将 ch 缓存区所存文本在屏上显示 */getch();5) 状态查询函数有时需要知道当前屏幕的显示方式,当前窗口的坐标、当前光标的位置,文本的显示6属性等,Turbo C 提供了一些函数得到屏幕文本显示有关信息的函数:void gettextinfo(struct text_info *f);这里的 text_info 是在 conio.h 头文件中定义的一个
16、结构,该结构的定义是Struct text_info(unsigned char winleft;unsigned char wintop;unsigned char winright; unsigned char winbottom; /* 窗口左上角 x 坐标 */* 窗口左上角 y 坐标 */* 窗口右下角 x 坐标 */* 窗口右下角 y 坐标 */unsigned char attribute;unsigned char normattr; unsigned char currmode;unsigned char screenheight;/* 文本属性/* 通常属性/* 当前文本方
17、式/* 屏高*/ */ */ */ unsigned char screenwidth; /* 屏宽 */ ;unsigned char curx;unsigned char cury;/* 当前光标的 x 值/* 当前光标的 y 值*/*/例程 3-3 :下面的程序将屏幕设置成 80 列彩色文本方式,并开了一个 window(1,5,70,20)的窗口,在窗口中显示了 current information of window,然后用 gettextinfo 函数得到当前窗口的信息,后面的 cprintf()函数将分别显示出结构 text_info 各分量的数值来,即:current inf
18、ormation of window Left corner of window is l,5 Right corner of window is 70,20 Text window attributeis 29 Text window normal attribute is 29 Current video mode is 3 window height andwidth is 25,80 Row cursor pos is 2,Column pos is 1/*-例程 3-3-*/#include main()struct text_info current;textmode(C80);t
19、extbackground(1);textcolor(13);window(1,5,70,20);clrscr();cputs(“Current information of windowrn“);gettextinfo(cprintf(“Left corner of window is %d,%d“,current.winleft,current.wintop);cprintf(“Right corner of window is %d,%d“,current.winright,current.winbottom);cprintf(“Text window attribute is%d“,
20、current.attribute);cprintf(“Text window normal attribute“,current.normattr);7cprintf(“Current video mode is%d“,current.currmode);cprintf(“Window height and width is%d,%d“,current.screenheight,current.screenwidth);cprintf(“Row cursor pos is %d,Column pos is %d“, current.cury,current.curx);getch();1.2
21、 键盘输入当我们按下键盘上某键时,系统如何知道某键被按下呢?它的奥妙在于计算机键盘是一个智能化的键盘,在键盘内有一个微处理器,它用来扫描和检测每个键的按下和拾起状态。然后以程序中断的方式(INT 9)与主机通信。ROM 中 BIOS 内的键盘中断处理程序,会将一个字节的按键扫描码(扫描码的 06 位标识了每个键在键盘上的位置,最高位标识按键的状态,0 对应该键是被按下;1 对应松开。它并不能区别大小写字母,而且一些特殊键如PrintScreen 等不产生扫描码直接引起中断调用)翻译成对应的 ASCII 码。由于 ASCII 码仅有 256 个(2 8),它不能将 PC 键盘上的键全部包括,因此
22、有些控制键如CTRL,ALT,END ,HOME,DEL 等用扩充的 ASCII 码表示,扩充码用两个字节的数表示。第一个字节是 0,第二个字节是 0255 的数,键盘中断处理程序将把转换后的扩充码存放在Ax 寄存器中,存放格式如表 3-3 所示。对字符键,其扩充码就是其 ASCII 码。表 3-3 键盘扫描码键名 AH AL字符键 扩充码=ASCII 码 ASCII 码功能键/组合键 扩充码 0是否有键按下,何键按下,简单的应用中可采用两种办法:一是直接使用 Turbo C 提供的键盘操作函数 bioskey()来识别,二是通过第一章 1.2.4.3 节介绍的 int86() 函数,调用 B
23、IOS的 INT 16H,功能号为 0 的中断。它将按键的扫描码存放在 Ax 寄存器的高字节中。函数 bioskey()的原型为:int bioskey(int cmd);它在 bios.h 头文件中进行了说明,参数 cmd 用来确定 bioskey()如何操作:cmd 操作012返回按健的键值,该值是 2 个字节的整型数。若没有键按下,则该函数一直等待,直到有键按下。当按下时,若返回值的低 8 位为非零,则表示为普通键,其值代表该键的 ASCII 码。若返回值的低 8 位为 0,则高 8 位表示为扩展的 ASCII码,表示按下的是特殊功能键。查询是否有键按下。若返回非 0 值,则表示有键按下
24、,若为 0 表示没键按下。将返回一些控制键是否被按过,按过的状态由该函数返回的低 8 位的各位值来表示:字节位012对应的 16 进制数0x010x020x04含义右边的 shift 键被按下左边的 shift 键被按下Ctrl 键被按下8345670x080x100x200x400x80Alt 键被按下Scroll Lock 已打开Num 已打开Caps Lock 已打开Inset 已打开当某位为 l 时,表示相应的键已按,或相应的控制功能已有效,如选参数 cmd 为 2,若 key 值为 0x09,则表示右边的 shift 键被按,同时又按了 Alt 键。函数 bioskey()的原型为:
25、int int86(int intr_num,union REGS *inregs,union REGS *outregs);这个函数在 bios.h 头文件中进行了说明,它的第一个参数 intr_num 表示 BIOS 调用类型号,相当于 int n 调用的中断类型号 n,第二个参数表示是指向联合类型 REGS 的指针,它用于接收调用的功能号及其它一些指定的入口参数,以便传给相应的寄存器,第三个参数也是一个指向联合类型 REGS 的指针,它用于接收功能调用后的返回值,即出口参数,如调用的结果,状态信息,这些值从相关寄存器中得到。例程 3-4:第二章扫雷游戏中,我们定义上,下,左,右键用来移动
26、雷区光标的位置,回车或者空格键用来挖开光标当前指向的雷区方块,F 和 f 标记当前光标指向的方块有地雷,Q 和 q在光标指向方块打问号,表示可能有地雷,A 和 a 用来自动挖开光标周围的方块,ESC 退出游戏。在实现时,我们调用 bioskey(0)来获得按键值,然后经过判断转入相应的处理。下面让我们再来回顾一下 2.2.3.4 节中的扫雷游戏源程序片段,其中 key.c 文件仅有一个函数getKey(),它用 biosky(0) 读取键盘输入,读到一个有用键(上,下,左,右键、回车或者空格键、F、f、Q、q、A、a 、ESC )时返回该键值。/*key.c扫雷游戏的按键获取*/#includ
27、e /*define key-value*/#define ENTER 0x1c0d#define UP 0x4800#define DOWN 0x5000#define LEFT 0x4b00#define RIGHT 0x4d00#define ESC 0x011b#define SPACE 0x3920#define LOWERF 0x2166#define UPPERF 0x2146#define LOWERA 0x1e61#define UPPERA 0x1e41#define LOWERQ 0x1071#define UPPERQ 0x10519int getKey(void)wh
28、ile(1)int key=bioskey(0);switch(key) case ENTER: case UP: case DOWN: case LEFT: case RIGHT: case ESC: case SPACE: case LOWERF: case UPPERF: case LOWERA: case UPPERA: case LOWERQ: case UPPERQ: return key; /*-End of key.c-*/例程 3-5 :本程序仅仅演示了通过 int86()获取按键的扫描码。在此注意扫描码和 bioskey()返回的码值是不同的。#include #inclu
29、de /* define Keys scan code */#define Key_ESC 1#define Key_A 30int getKeySCode();main()int acount=0, ky;doky= int getKeySCode();switch(ky)/* 定义各键的扫描码 */* 得到按键的扫描码 */case Key_A: /* A and a key */+account; break;case Key_ESC:printf(“nEnd the program”); exit(0);10default:break;printf(“nDuring the progr
30、am, you press A and a %d times”,acount);/* read char on key,return scan code */int getKeySCode() /* 读键函数 */union REGS rg;rg.h.ah=0;int86(0x16,return rg.h.ah;1.3 问题实现在了解了上两小节的内容后,你就可以解决我们最初提出的问题了(见例程 3-6)。图 3-2 3.1 节问题实现后程序运行界面我们的设计思想是首先用文本窗口函数 window (int x1, int y1, int x2, int y2)画出两个窗口,用 textcolo
31、r (int color),textbackground (int color),clrscr (void)等进行窗口属性的设置。用 tab 键进行两个窗口间的循环切换,在每次切换前先调用 gettext (int left, int top, int right, int bottom, void * buf)函数把当前矩形窗口上的字符拷贝到由 buf 所指向的内存中,在切换到另一个窗口后调用 puttext (int left, int top, int right, int bottom, void * buf)把先前存储在该窗口buf 所指向的内存中的字符拷贝到当前窗口中,并用 got
32、oxy (int x, int y) 把光标移到原先所在位置,因此可以接着先前的文本继续编辑。程序中运用一个临时变量 turn 的值 0 和 1 来进行两个窗口间的循环切换,当值为 1 时调用 draw_left_win()函数重绘左边窗口,当值为 0 时调用 draw_right_win()函数重绘右边窗口。程序用 bioskey(0)来读取键盘输入的文本并存在内存中,然后用 putch(key)输出。程序运行(已再次切换到左窗口,光标在问号后闪烁)的界面如图 3-2 所示。在这个程序中我们调用了 process.h 中的 void exit(int status)函数,它清除和关闭所有打开
33、的文件,写出任何缓冲输出,并终止程序。参数为 0,则认为程序正常终止;若为非零值,则说明存在执行错误。/*例程 3-6*/11#include #include #include /*切换时保存左窗口文本*/char leftbuf40*25*2;/*切换时保存右窗口文本*/char rightbuf40*25*2;/*切换时保存左窗口当前坐标*/int leftx, lefty; /*切换时保存右窗口当前坐标*/int rightx, righty; /*重绘左边窗口*/void draw_left_win();/*重绘右边窗口*/void draw_right_win();int main
34、()int key; int turn;textmode(C80);textbackground(0);textcolor(WHITE);clrscr();gotoxy(60,1);cprintf(“Press Esc to Quit“);window(41,2,79,24);/*右边窗口为绿色背景,红色前景 */textbackground(2);textcolor(4);clrscr();gettext(41,2,79,24, rightbuf);window(2,2,40,24); /*左边窗口为蓝色背景,白色前景*/textbackground(1);textcolor(15);clr
35、scr();gettext(2,2,40,24, leftbuf);turn = 0; /*初始激活左窗口*/for(;) key=bioskey(0);12if(key = 0x11b) exit(0); key=key /*获取窗口输入的文本的 ASCII 码值*/if(key = t) if(turn = 0) /*切换到左窗口*/ gettext(2,2,40,24, leftbuf); leftx = wherex(); lefty = wherey(); draw_right_win(); turn = 1; else if(turn = 1) /*切换到右窗口*/ gettext
36、(41,2,79,24, rightbuf);rightx = wherex(); righty = wherey(); draw_left_win(); turn = 0; else putch(key); /*当前光标处显示新输入的文本字符*/ void draw_right_win()window(41,2,79,24);textbackground(2);textcolor(4);clrscr();puttext(41,2,79,24, rightbuf);gotoxy(rightx, righty);void draw_left_win()window(2,2,40,24);text
37、background(1);textcolor(15);clrscr();puttext(2,2,40,24, leftbuf);13gotoxy(leftx, lefty);1.4 高级应用菜单实现1.4.1 一个弹出式菜单这个程序(例程 3-7)是一个文本方式下的菜单程序,它生成一个弹出式菜单,如图 3-3所示。程序运行时,首先弹出一个带洋红色框的蓝底菜单,并有一红色光条压在第一项上,当按 E 键时,程序回到系统,压 Down 键时,光条移到第二项,压 A 时,则列出当前日录下的各文件目录,再压任意键后则又弹出菜单,当压 B 键时,则列出目录,当屏满后,暂停,按键后,又继续列出,它实际上就
38、是执行 dir /p 命令,当按回车键后,又出现菜单,当按 C 键后,便执行 dir /w 的 dos 命令,以宽行格式列出目录,按回车键后又回到菜单用 UP键可使光条上移。图 3-3 弹出式菜单程序开始时,首先用 do 循环反复运行下面的程序,直到按 E 键后为止,window(7,8,19,15)定义了一个用洋红色填充的窗口,接着又定义一个蓝色窗口,它套在洋红色窗口内,因而形成一个带洋红色粗边框的蓝色窗口,在窗口内写上各菜单项,接着又调用光条上移函数 upbar(y1),使红色光条压在第一菜单项上,下面的 do 循环则用来构成一个反复检查按键,并转去执行相应的功能操作,do 循环内的第一个
39、 switch(ky) 语句用来判断按的是何键,按键值赋给 y 的相应值,并使 ky=key_enter,以结束 do 循环,跟着第二个 switch(y)语句则按 y 值转去执行相应的菜单项功能。只有当菜单项功能键是 E 时,才使得外层的 do 循环结束而回到系统。upbar(int y)函数是产生一个上移光条 (用 gettext()函数),实际上它第一次被调用时,则用gettext(i,y,i,y,char ch;textbackground(0);clrscr();do textmode(C80);textbackground(13);textcolor(RED);window(7,8
40、,19,15);/* 开一个窗口 */clrscr();textbackground(1);textcolor(RED);window(8,9,18,14);/* 再开一个当前窗口,套在上一个窗口之中*/clrscr();gotoxy(3,3);cprintf(“E:exitrn“);gotoxy(3,4);cprintf(“A:dirrn“);gotoxy(3,5);/* 窗口中写上红色的菜单项 */ 15cprintf(“B:dir/prn“);gotoxy(3,6);cprintf(“C:dir/wrn“);y=10;upbar(y-1);do ky=bioskey(0); switch
41、(ky) /* 调用光条上移函数 */* 得到按键的键值 */case Key_A: case Key_a:/* A and a key */ y=12; ky=Key_ENTER; break; case Key_B:case Key_b:/* B and b key */ y=13; ky=Key_ENTER; break; case Key_C: case Key_c:/* C and c key */ y=14; ky=Key_ENTER; break; case Key_E:case Key_e:/* E and e key */ y=11; ky=Key_ENTER; break;
42、 case Key_DOWN:/* Cursor down key */ if ( y10) downbar(y);y-; break; while (ky !=Key_ENTER ); /* Enter key */textcolor(WHITE);switch(y) case 11: ch=%; /* 返回系统 */break; case 12: system(“dir“);getch(); /* 列目录后等待按键 */break; case 13: system(“dir /p“); getch(); /* 列目录屏满后暂停,按任意键继续 */break; case 14: system
43、(“dir /w“); getch(); /* 用宽行格式列目录 */break; if(ch=%)break; while(1);clrscr(); /* 清屏 */ 17/* read bar down */upbar(int y) /* 光条上移函数 */int i;typedef struct texel_struct unsigned char ch;unsigned char attr; texel;texel t;for(i=9;i#include 19#include #define Key_DOWN 0x5000#define Key_UP 0x4800#define Key
44、_ESC 0x011b#define Key_ALT_F 0x2100#define Key_ALT_X 0x2d00#define Key_ENTER 0x1c0dvoid box(int startx,int starty,int high,int width);main()int i,key,x,y,l;char *menu = “File“,“Edit“,“Run“,“Option“,“Help“,“Setup“,“Zoom“,“Menu“;/* 主菜单各项 */char *red = “F“,“E“,“R“,“O“,“H“,“S“,“Z“,“M“ ; /* 加上红色热键 */char
45、 *f = “Load file“, “Save file“, “Print“, “Modify “, “Quit A1t_x“;/* File 项的子菜单 */char buf16*10*2,buf116*2; /* 定义保存文本的缓冲区 */while(1) textbackground(BLUE);clrscr();textmode(C80);window(1,1,80,1);/* 定义显示主菜单的窗口 */textbackground(LIGHTGRAY);textcolor(BLACK);clrscr();gotoxy(5,1);for(i=0,l=0;imain()int grap
46、hdriver=DETECT;int graphmode;initgraph( /* 设置成低分辨模式 */break; case EGA:graphmode=0; /* 设置成低分辨模式 */break; case VGA:graphmode=1; /* 设置成中分辨模式 */break; case 2:printf(“nGraphics adapter not installed”);exit(1);default:printf(“nGraphics adapter is not CGA,EGA,or VGA”);initgraph(调用 detectgraph 时,该函数将把检测到的适配
47、器类型赋予 graphdriver,再把该类型适配器支持的最高分辨率模式赋给 graphmode 。3) 清屏和恢复显示方式的函数画图前一般需清除屏幕,使得屏幕如同一张白纸,以画最新最美的图画,因而必须使用清屏函数。清屏函数的原型是:void far cleardevice(void);该函数作用范围为整个屏幕,如果用函数 setviewport 定义一个图视窗口,则可用清除图视口函数,它仅清除图视口区域内的内容,该函数的说明原型是:void far clearviewport(void);当画图程序结束,回到文本方式时,要关闭图形系统,回到文本方式,该函数的说明原型是:void far cl
48、osegraph(void);由于进入 C 环境进行编程时,即进入文本方式,因而为了在画图程序结束后恢复原来的最初状况,一般在画图程序结束前调用该函数,使其恢复到文本方式。为了不关闭图形系统,使相应适配器的驱动程序和字符集(字库 )仍驻留在内存,但又回到原来所设置的模式,则可用恢复工作模式函数,它也同时进行清屏操作,它的说明原型是:void far restorecrtmode(void);该函数常和另一设置图形工作模式函数 setgraphmode 交互使用,使得显示器工作方式在图形和文本方式之间来回切换,这在编制菜单程序和说明程序时很有用处。2.1.3 基本绘图函数图形由点、线、面组成,Turbo C 提供了一些函数,以完成这些操作,而所谓面则可由对封闭图形填上颜色来实现。当图形系统初始化后,在此阶段将要进行的画图操作均采用缺省值作为参数的当前值,如画图屏幕为全屏,当前开始画图坐标为(0,0)(又称当前画笔位置,虽然这个笔是无形的),又如采用画图的背景颜色和前景颜色、图形的填充方式,以及可以采用的字符集(字库)等均为缺省值。1) 画点函数void far putpixel(int x,int y,int color);该函数表示在指定的 x,y 位置画一点,点的显示颜色由设置的 color 值决定,关于颜28色的设置,将在设置颜色函数中介绍。in