《高级程序设计技术》课件第6章.ppt

上传人(卖家):momomo 文档编号:8223389 上传时间:2025-01-13 格式:PPT 页数:64 大小:363KB
下载 相关 举报
《高级程序设计技术》课件第6章.ppt_第1页
第1页 / 共64页
《高级程序设计技术》课件第6章.ppt_第2页
第2页 / 共64页
《高级程序设计技术》课件第6章.ppt_第3页
第3页 / 共64页
《高级程序设计技术》课件第6章.ppt_第4页
第4页 / 共64页
《高级程序设计技术》课件第6章.ppt_第5页
第5页 / 共64页
点击查看更多>>
资源描述

1、第第6章章 键盘与鼠标操作键盘与鼠标操作6.1 键盘6.2 鼠标实验6 6.1 键键 盘盘6.1.1 键盘编码键盘编码键盘内有一个微处理器,专门用来扫描和检测每个键的按下和抬起状态。当检测到某键被按下或松开时,产生一个中断信号,然后输出一个字节的扫描码给系统。键盘上的每个键都对应一个扫描码,根据扫描码就能唯一地确定哪一个键改变了状态。扫描码的低7位标示了每个键在键盘上的位置,最高位标示了对应该键是被按下(0)还是松开(1)。一些特殊键如Print-Screen等将不产生扫描码,而是直接引起中断调用。扫描码仅能区别键的位置和键的按下与松开,并不能区别大小写字母。每当按下或松开某键时,便产生INT

2、9中断,以调用BIOS中的键盘中断处理程序,它的作用是将得到的扫描码翻译成对应的ASCII码,至于是大写字符还是小写字符,或上字符还是下字符,则参照Caps Lock键和Shift键的状态来进行转换。由于ASCII码仅能有256个,不能将PC键盘上的键全部包括,因此将有些控制键如Ctrl、Alt、End、Home、Del等用扩充的ASCII码表示。扩充的ASCII码用两个字节来表示,低字节是0,高字节是0255的数。键盘中断处理程序将把转换后的扩充码存放在AX寄存器中。6.1.2 键盘操作函数键盘操作函数如何判断哪个键被按下,一般有两种方法:方法一是使用TC提供的键盘操作函数bioskey()

3、来识别;方法二是使用中断函数int86()来实现。这两个函数都包含在bios.h中。函数原型:int bioskey(int cmd);功能:使用BIOS服务的键盘接口,其中参数cmd的取值及意义如下:0:若没有键按下,该函数返回0,并一直等待;若有键按下,则从缓冲区中取走该键,并返回一个16位(两个字节)的编码。此时,若返回值的低8位为非零值,则表示为普通键,其值代表该键的ASCII码;若返回值的低8位为0,则高8位表示为扩展的ASCII码,表示按下的是特殊功能键。1:查看是否有键可读。如有,则返回一个非0的16位值,该值就是键的编码,但不将该键从缓冲区取走;若无键可读,返回0。2:返回键盘

4、状态字节。键盘状态字节各位的含义如表6.1所示。表表6.1 键盘状态字节各位的含义键盘状态字节各位的含义当某位为1时,表示相应的键已经被按下或功能已被打开。如果调用key=bioskey(2);返回0 x41,则表示右Shift键被按下,同时,大写字母Caps Lock键的状态被打开。【程序程序6.1】键盘操作示例。#include#include#define RIGHT 0 x01#define LEFT0 x02#define CTRL 0 x04#define ALT 0 x08 main(void)int key,modifiers;while(bioskey(1)=0);/*ues

5、 1 returns 0 until a key is pressed*/key=bioskey(0);/*use 0 returns the key that is waiting*/modifiers=bioskey(2);/*use 2 to determine if special keys were used*/if(modifiers)printf();if(modifiers&RIGHT)printf(RIGHT);if(modifiers&LEFT)printf(LEFT);if(modifiers&CTRL)printf(CTRL);if(modifiers&ALT)prin

6、tf(ALT);printf();if(isalnum(key&0 xFF)/*print out the character read*/printf(%cn,key);else printf(%#02xn,key);return 0;int86()的使用参见6.2.1。6.1.3 键盘操作综合实例键盘操作综合实例 程序6.2是一个用键盘绘图的简单程序,定义了几个特殊键:V”:画笔提起。W”:开始画图。R”:开始擦图。S”:当前图形存入文件。E”:调出已有文件。C”:画圆。程序一运行,屏幕上出现一个黄色的边框来设定画图的区域,区域中间出现提起的画笔符号。当按下“”键时,画笔符号变为,此时可移

7、动方向键(上、下、左、右、左上、左下、右上、右下)来画图;当按下“R”键时,画笔符号变为,此时可移动方向键来擦图;在画图过程中,按下“C”键,可画出一个半径为20个像素点的圆;当结束画图时,按下“S”键,将画好的图形存盘;按下“E”键可调出已有的图形进行编辑。【程序程序6.2】用键盘操作绘图。#include graphics.h#include stdio.h#include fcntl.h#include stdlib.hmain()void save(),load();void*wg,*rg,*vg,*fy;int driver,mode;int c=RED;int x=320,y=22

8、5;int x1,y1,x2,y2;int k,k1,k2;/*initialize grapher*/detectgraph(&driver,&mode);initgraph(&driver,&mode,);/*write the pen*/bar(200,10,206,16);line(203,7,200,10);line(203,7,206,10);line(243,7,240,16);line(243,7,246,16);line(283,7,280,10);line(283,7,286,10);line(283,7,283,16);/*save the pen*/wg=malloc(

9、imagesize(200,7,206,16);rg=malloc(imagesize(240,7,246,16);vg=malloc(imagesize(280,7,286,16);fy=malloc(imagesize(200,7,206,16);getimage(200,7,206,16,wg);getimage(240,7,246,16,rg);getimage(280,7,286,16,vg);cleardevice();/*write the box*/setcolor(YELLOW);rectangle(4,19,637,447);x1=x-3;y1=y+1;x2=x+3;y2=

10、y+10;getimage(x1,y1,x2,y2,fy);putimage(x1,y1,vg,XOR_PUT);/*receive the command*/for(;)while(bioskey(1)=0);k=bioskey(0);putimage(x1,y1,fy,AND_PUT);if(k&0 x00ff)|0 x00)=0)k1=k&0 xff?0:k8;/*k1 is the specialkey value*/elsek2=k&0 x00ff;/*k2 is the non-specialkey value*/if(k&0 x00ff)|0 x00)=0)/*Special k

11、ey*/switch(k1)case 45:restorecrtmode();exit(0);case 72:if(y20)y=y-1;break;case 75:if(x5)x=x-1;break;case 77:if(x636)x=x+1;break;case 80:if(y5)&(y20)x=x-1;y=y-1;break;case 79:if(x5)&(y446)x=x-1;y=y+1;break;case 73:if(x20)x=x+1;y=y-1;break;case 81:if(x636)&(y446)x=x+1;y=y+1;break;x1=x-3;y1=y+1;x2=x+3;

12、y2=y+10;getimage(x1,y1,x2,y2,fy);/*non-special key*/switch(k2)case 118:/*v*/case 86:/*V*/putimage(x1,y1,vg,OR_PUT);break;case 119:/*w*/case 87:/*W*/putimage(x1,y1,wg,OR_PUT);putpixel(x,y,c);break;case 114:/*r*/case 82:/*R*/putimage(x1,y1,rg,OR_PUT);putpixel(x,y,BLACK);break;case 115:/*s*/case 83:/*S

13、*/save(pic.dat);break;case 101:/*e*/case 69:/*E*/load(pic.dat);break;case 99:/*c*/case 67:/*C*/setcolor(RED);circle(x,y,20);break;default:continue;/*function for screen picture save*/void save(char*fname)FILE*fp;int i;register long j;char far*ptr;fp=fopen(fname,wb);for(i=0;i4;i+)outportb(0 x3CE,4);o

14、utportb(0 x3CF,i);ptr=(char far*)0 xA0000000L;for(j=0;j38400L;j+)putc(*ptr,fp);ptr+;fclose(fp);outportb(0 x3CF,0);/*function for screen picture display*/void load(char*fname)FILE*fp;register int i;int k4=1;register long j;char far*ptr;fp=fopen(fname,rb);for(i=0;i4;i+)outportb(0 x3C4,2);outportb(0 x3

15、C5,k4);ptr=(char far*)0 xA0000000L;for(j=0;j38400L;j+)*ptr=getc(fp);ptr+;k4*=2;fclose(fp);outportb(0 x3C5,0 xF);6.2 鼠鼠 标标6.2.1 鼠标的工作原理鼠标的工作原理1.鼠标简介鼠标简介鼠标主要有两种:机械式和光电式。机械式鼠标主要是使用一个转动球,传感器将转动球的转动变成光标的方向信息。光电式鼠标使用两个发光二极管(LED)和两个光电晶体管来检测移动。两个LED一个发红光,一个发紫光。光电鼠标用一个特殊的焊盘来改变LED的光强,这个焊盘有两个方向线,当鼠标向一个方向移动时,吸收

16、红光;向另一个方向移动时,吸收紫光。光间断的颜色和数目决定了鼠标器的方向和距离。鼠标系统实际上由两个主要元素组成:鼠标硬件机制和称做鼠标驱动程序的内存驻留程序。鼠标硬件机制的工作原理如上所述。鼠标驱动程序提供与鼠标通信所需的全部低级支持。此外,它还自动维持鼠标光标位置并判断是否按下了某个键。一旦装入驱动程序,鼠标就可以被随后执行的任意程序使用。DOS操作系统和Turbo C 2.0并不支持鼠标器的操作,因而要使用鼠标器,必须首先安装相应的驱动程序。有以下两种安装方法:(1)在CONFIG.SYS文件中加入一行信息:DEVICE=MOUSE.SYS,使得系统在启动时将相应的驱动程序也装入内存;(

17、2)直接运行文件,使其驻留内存。鼠标的各种操作都是由鼠标驱动程序来管理的。每当移动或按下鼠标的任意键,就将产生一次INT 33H中断,鼠标驱动程序将按照中断时的入口参数,调用不同的处理程序来完成中断服务。2.中断中断鼠标是一种外设,CPU通过中断对它进行管理。鼠标的中断号是33H,通过软中断指令INT 即可管理鼠标。C语言中提供了几个函数方便我们使用中断,这些函数包含在头文件“dos.h”中。中断函数主要有int86()、int86x()、intdos()、geninterrupt()。我们主要介绍int86(),其余请查看dos.h。函数原型:int int86(int intno,unio

18、n REGS*inregs,union REGS*outregs);参数含义:执行intno号中断,用户定义的寄存器值存于结构inregs中,执行完后将返回的寄存器值存于结构outregs中。一般后两个参数使用同一个寄存器。union REGS定义了CPU中的各个寄存器,具体如下:struct WORDREGS unsigned int ax,bx,cx,dx,si,di,cflag,flags;struct BYTEREGS unsigned char al,ah,bl,bh,cl,ch,dl,dh;union REGS struct WORDREGS x;struct BYTEREGS h

19、;可以通过PC中断33H访问鼠标和鼠标驱动程序的各种功能。所选择的特定函数依赖于中断时AX寄存器的值。三个其他寄存器(BX、CX和DX)用于把各种参数传送给鼠标例程。同样,鼠标函数使用这四个寄存器把鼠标的位置和按钮的状态返回给调用函数。鼠标驱动程序提供了三十多个功能调用,通过选取不同的入口参数,可实现不同的功能调用。表6.2列出了常用的功能调用及参数。完整的鼠标功能调用可参见附录E。表表6.2 鼠标驱动程序常用功能码及参数说明鼠标驱动程序常用功能码及参数说明6.2.2 鼠标操作鼠标操作(1)鼠标的初始化:InitMouse()union REGS regs;regs.x.ax=0;/*功能码为

20、0表示鼠标复位*/int86(0 x33,®s,®s);/*调用中断管理鼠标*/if(regs.x.ax=0)return 0;/*鼠标安装失败*/else return 1;/*鼠标安装成功*/(2)鼠标光标的显示:void ShowCur()union REGS regs;if(!visual)regs.x.ax=1;int86(0 x33,®s,®s);visual=true;(3)鼠标光标的隐藏:void HideCur()union REGS regs;if(visual)regs.x.ax=2;int86(0 x33,®s,®s);visual=

21、false;在鼠标驱动程序中,鼠标的显示状态用0值表示,隐藏用负值表示,每调用一次显示功能则该值加1,每调用一次隐藏功能则该值减1。这样,在多次调用了驱动程序的隐藏鼠标光标功能后,再调用显示鼠标光标功能时,将不能正常显示鼠标光标。此时需要加入一个全局visual布尔型变量,来取代驱动程序中的数值。(4)读取按钮状态和光标位置:void GetStatus(int*x,int*y,int*status)union REGS regs;regs.x.ax=3;int86(0 x33,®s,®s);*x=regs.x.cx;*y=regs.x.dx;*status=regs.x.bx;其

22、中:x,y为光标位置;status&1表示左键状态:1为按下,0为未按;status&2表示右键状态:1为按下,0为未按;status&4表示中键状态:1为按下,0为未按。对于循环检测时的抖动现象,可增加一些空循环或延时来清除剩余的按键信号。例如:下面程序段中,当鼠标移动时画线到当前的鼠标位置,当按左键时定义画线的启始位置,按右键时结束作图。int working=true;int x,y,status;while(working)GetStatus(&x,&y,&status);if(status&1)/*左键按下*/moveto(x,y);/*移动光标到当前鼠标位置*/else if(st

23、atus&2)/*右键按下,退出*/working=false;else/*没有键按下*/Lineto(x,y);/*从最后一次按下的位置到该位置画线*/Delay(20);/*延迟20ms防止抖动现象*/(5)移动鼠标光标(设置光标位置):void MoveMouse(int x,int y)REGS regs;regs.x.ax=4;regs.x.cx=x;regs.x.dx=y;int86(0 x33,®s,®s);(6)设置鼠标光标的移动范围:SetMouseArea(int x0,int y0,int x1,int y1)union REGS regs;regs.x.ax

24、=7;regs.x.cx=x0;regs.x.dx=x1;int86(0 x33,®s;®s);regs.x.ax=8;regs.x.cx=y0;regs.x.dx=y1;int86(0 x33,®s,®s);(7)设置鼠标的光标形状:设置鼠标光标需要三方面信息:鼠标的外边界:88点阵,16个整数;鼠标的内边界:88点阵,16个整数;鼠标热点的相对坐标:int x,y。其中外边界和内边界连续存放在有32个元素的整型数组中。void SetCurs(unsigned masks32,int x,int y)union REGS regs;struct SREGS sreg

25、s;regs.x.ax=9;regs.x.bx=x;regs.x.cx=y;/*hot spot*/regs.x.dx=(unsigned)masks;segread(&sregs);int86(0 x33,®s,®s);一些不同形状的光标数据如下:usigned mouse=0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 x0000,0 x0000,0 x0000,0 x

26、0000,0 x0000,0 x0000,0 x1000,0 x13c0,0 x3ff0,0 x7ff8,0 xfff8,0 xfff8,0 x0824,0 x0822,0 x1ce2,0 x0000;usigned emptyhand=0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 xffff,0 x0c00,0 x1200,0 x1200,0 x1200,0 x13fe,0 x1249,0 x12

27、49,0 x1249,0 x7249,0 x9001,0 x9001,0 x9001,0 x8001,0 x8001,0 x4002,0 x3ffc;usigned fullarrow=0 x3fff,0 x1fff,0 x0fff,0 x07ff,0 x03ff,0 x01ff,0 x00ff,0 x007f,0 x003f,0 x00ff,0 x01ff,0 x10ff,0 x30ff,0 xf87f,0 xf87f,0 xfc3f,0 x0000,0 x4000,0 x6000,0 x7000,0 x7800,0 x7c00,0 x7e00,0 x7f00,0 x7f80,0 x7e00

28、,0 x7c00,0 x4600,0 x0600,0 x0300,0 x0300,0 x0180;usigned fullhand=0 xf3ff,0 xe1ff,0 xe1ff,0 xe1ff,0 xe001,0 xe000,0 xe000,0 xe000,0 x8000,0 x0000,0 x0000,0 x0000,0 x0000,0 x0000,0 x8001,0 xc003,0 x0c00,0 x1200,0 x1200,0 x1200,0 x13fe,0 x1249,0 x1249,0 x1249,0 x7249,0 x9001,0 x9001,0 x9001,0 x8001,0

29、x8001,0 x4002,0 x3ffc;注意:(1)在DOS、Windows 98下需确保已经装载了mouse.sys,或已运行了。(2)用TC 2.0在Windows 2000、Windows XP下不会显示鼠标,但鼠标确实存在,用户可以得到它的位置和事件。要想显示鼠标,只有自己绘图了。6.2.3 鼠标操作综合实例鼠标操作综合实例【程序程序6.3】鼠标操作。#include#include#include#include/*鼠标信息宏定义*/#define WAITING 0 xff00#define LEFTPRESS 0 xff01#define LEFTCLICK 0 xff10#

30、define LEFTDRAG 0 xff19#define RIGHTPRESS 0 xff02#define RIGHTCLICK 0 xff20#define RIGHTDRAG 0 xff2a#define MIDDLEPRESS 0 xff04#define MIDDLECLICK 0 xff40#define MIDDLEDRAG 0 xff4c#define MOUSEMOVE 0 xff08 int Keystate;int MouseExist;int MouseButton;int MouseX;int MouseY;int up1616,down1616,mouse_dr

31、aw1616,pixel_save1616;void MouseMath()/*计算鼠标的样子*/int i,j,jj,k;long UpNum16=0 x3fff,0 x1fff,0 x0fff,0 x07ff,0 x03ff,0 x01ff,0 x00ff,0 x007f,0 x003f,0 x00ff,0 x01ff,0 x10ff,0 x30ff,0 xf87f,0 xf87f,0 xfc3f ;long DownNum16=0 x0000,0 x7c00,0 x6000,0 x7000,0 x7800,0 x7c00,0 x7e00,0 x7f00,0 x7f80,0 x7e00,0

32、 x7c00,0 x4600,0 x0600,0 x0300,0 x0300,0 x0180 ;for(i=0;i=0;k-)upik=0;for(k=jj;k=0;k-)downik=0;for(k=0;k16;k+)/*四种组合方式*/if(upik=0&downik=0)mouse_drawik=1;else if(upik=0&downik=1)mouse_drawik=2;else if(upik=1&downik=0)mouse_drawik=3;else mouse_drawik=4;mouse_draw12=4;/*特殊点*/*鼠标光标显示*/void MouseOn(int

33、x,int y)int i,j;int color;for(i=0;i16;i+)/*画鼠标*/for(j=0;j16;j+)pixel_saveij=getpixel(x+j,y+i);/*保存原来的颜色*/if(mouse_drawij=1)putpixel(x+j,y+i,0);else if(mouse_drawij=2)putpixel(x+j,y+i,15);/*隐藏鼠标*/void MouseOff()int i,j,x,y,color;x=MouseX;y=MouseY;for(i=0;i16;i+)/*原位置异或消去*/for(j=0;j16;j+)if(mouse_draw

34、ij=3|mouse_drawij=4)continue;color=getpixel(x+j,y+i);putpixel(x+j,y+i,colorcolor);putpixel(x+j,y+i,pixel_saveij);/*鼠标是否加载。MouseExist:1=加载;0=未加载 MouseButton:鼠标按键数目*/void MouseLoad()_AX=0 x00;geninterrupt(0 x33);MouseExist=_AX;MouseButton=_BX;/*鼠标状态值初始化*/void MouseReset()_AX=0 x00;geninterrupt(0 x33);

35、/*设置鼠标左、右边界。lx:左边界;gx:右边界*/void MouseSetX(int lx,int rx)_CX=lx;_DX=rx;_AX=0 x07;geninterrupt(0 x33);/*设置鼠标上、下边界。uy:上边界;dy:下边界*/void MouseSetY(int uy,int dy)_CX=uy;_DX=dy;_AX=0 x08;geninterrupt(0 x33);/*设置鼠标当前位置。X:横向坐标;y:纵向坐标*/void MouseSetXY(int x,int y)_CX=x;_DX=y;_AX=0 x04;geninterrupt(0 x33);/*设置

36、鼠标速度(缺省值:vx=8,vy=1)值越大速度越慢*/void MouseSpeed(int vx,int vy)_CX=vx;_DX=vy;_AX=0 x0f;geninterrupt(0 x33);/*获取鼠标按下键的信息*/*是否按下左键。返回值:1=按下 0=释放*/int LeftPress()_AX=0 x03;geninterrupt(0 x33);return(_BX&1);/*是否按下中键。返回值同上*/int MiddlePress()_AX=0 x03;geninterrupt(0 x33);return(_BX&4);/*是否按下右键。返回值同上*/int Right

37、Press()_AX=0 x03;geninterrupt(0 x33);return(_BX&2);/*获取鼠标当前位置*/void MouseGetXY()_AX=0 x03;geninterrupt(0 x33);MouseX=_CX;MouseY=_DX;int MouseStatus()/*鼠标按键情况*/int x,y,status,press=0,i,j,color;status=0;/*默认鼠标没有移动*/x=MouseX;y=MouseY;while(x=MouseX&y=MouseY&status=0&press=0)if(LeftPress()&RightPress()p

38、ress=1;else if(LeftPress()press=2;else if(RightPress()press=3;MouseGetXY();if(MouseX!=x|MouseY!=y)status=1;if(status)/*移动情况下重新显示鼠标*/for(i=0;i16;i+)/*原位置异或消去*/for(j=0;j16;j+)if(mouse_drawij=3|mouse_drawij=4)continue;color=getpixel(x+j,y+i);putpixel(x+j,y+i,colorcolor);putpixel(x+j,y+i,pixel_saveij);M

39、ouseOn(MouseX,MouseY);/*新位置显示*/if(press!=0)return press;/*有按键的情况*/return 0;/*只移动的情况*/void main()int gd=DETECT,gm;initgraph(&gd,&gm,c:tc);MouseMath();/*计算鼠标形状,开始必须使用,后面就不用了*/MouseSetY(0,479);MousSetX(0,639);MouseSetXY(100,100);outtextxy(400,400,Author:milo_zy);outtextxy(370,420,welcome to );settextst

40、yle(0,0,4);outtextxy(100,200,XP Mouse Demo);MouseOn(MouseX,MouseY);/*第一次显示鼠标*/while(!kbhit()switch(MouseStatus()case 1:MouseOff();/*双键按下画黄点*/putpixel(MouseX,MouseY,YELLOW);MouseGetXY();MouseOn(MouseX,MouseY);break;case 2:/*左键按下画红点*/MouseOff();putpixel(MouseX,MouseY,RED);MouseGetXY();MouseOn(MouseX,MouseY);break;case 3:/*右键按下画绿点*/MouseOff();putpixel(MouseX,MouseY,GREEN);MouseGetXY();MouseOn(MouseX,MouseY);break;default:break;getch();closegraph();实实 验验 61.编写一个打字游戏,随机产生一些字母从屏幕上边下落,用户输入准确的字母时,由屏幕下方发出一个箭头,击毁该字母。2.绘制一个类似TC界面的菜单,能用键盘进行简单响应。3.编写用鼠标绘制自由图形的程序。4.结合图形用户界面,用C语言编写一个图形方式下的学生管理系统。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 大学
版权提示 | 免责声明

1,本文(《高级程序设计技术》课件第6章.ppt)为本站会员(momomo)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!


侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|