/*这个程序是一个模仿windows画板的小程序,是16色的。由于最近时间比较紧,有些功能还没有完成(比如橡皮檫等),程序写得比较长,所以分成两部分*/
/********************模仿windows画板程序********************* 作者:平倭将军 版本:1.0 ************************************************************/ #include<stdio.h> #include<dos.h> #include<conio.h> #include<graphics.h> #include<stdlib.h> #include<alloc.h> #include<time.h> #include<bios.h> #include<string.h> #define PGET {p->x=i;p->y=j;p=p->next;} //给一个点的坐标赋值后指针指向下一个点 #define WT p->color=WHITE; //把一个点的颜色赋为白色 #define BK p->color=BLACK; //把一个点的颜色赋为黑色 #define GW {WT PGET} #define GB {BK PGET} #define GETXY {_AX=3;geninterrupt(0x33);Cp_x=_CX;Cp_y=_DX;} //检测鼠标位置,并把坐标记录下来 #define PIC_WIN 1 //作图区窗口 #define PEN_WIN 30 //选择任意画画笔窗口 #define LINE_WIN 31 //选择双点画线窗口 #define RECTANGLE_WIN 32 //选择画矩形窗口 #define ELLIPSE_WIN 33 //选择画椭圆窗口 #define LINETO_WIN 34 //选择画线窗口 #define COLOR0_WIN 10 //以下是选择画笔各种颜色窗口(共16色) #define COLOR1_WIN 11 #define COLOR2_WIN 12 #define COLOR3_WIN 13 #define COLOR4_WIN 14 #define COLOR5_WIN 15 #define COLOR6_WIN 16 #define COLOR7_WIN 17 #define COLOR8_WIN 18 #define COLOR9_WIN 19 #define COLOR10_WIN 20 #define COLOR11_WIN 21 #define COLOR12_WIN 22 #define COLOR13_WIN 23 #define COLOR14_WIN 24 #define COLOR15_WIN 25
//记录一点坐标 typedef struct {int x; int y; }_pt; //窗口,lt表示左上角点坐标,rb表示右下,color为窗内颜色 //condition决定窗体的凹凸,can决定窗体的凹凸是否是可变(目前还没使用上这一功能) typedef struct {_pt lt,rb; char color; int condition; int can; } _win; //各窗体连接成为链表,方便绘制,调用等 typedef struct chain {_win win; int win_name; struct chain *next; }_headline; //记录一点坐标和点的颜色 typedef struct pnt {int x; int y; char color; struct pnt *next; } _point;
//函数声明 void start(); void cpout(); _point *creat_cp(); void move_cp(); void put_cp(); void gettemp_cp(); int command(); void cpset(); //cp_x,y用于记录当前鼠标坐标,pre_x,y用于记录前一次鼠标坐标 //Image_x,y用于模式画图记录鼠标终点坐标 ,Thecolor用于记录画笔当前颜色 int Cp_x=320,Cp_y=240,Pre_x=320,Pre_y=240,Image_x,Image_y,Thecolor=BLACK; //start_x,y用于双点画线时记录起始点坐标 int Startx=-1,Starty; //pen_mode用于记录当前画笔模式 //pointx,y用于记录任意画起始坐标,Fam_x,y用于记录模式画图时的起始坐标 int Pen_mode=PEN_WIN,Pointx,Pointy,Fam_x,Fam_y; //以下各*_flag用于判断各绘画模式的启动于关闭 int Pen_flag=0,Rectangle_flag=0,Ellipse_flag=0,Lineto_flag=0; //以下四个变量用于暂存一个矩形范围内图象(切割成四份) void *Buf1,*Buf2,*Buf3,*Buf4; //三个指针分别记录三个链表头地址:鼠标样子,鼠标遮盖处的图象, _point *Cp_head,*Tempcp_head; //两个指针分别记录两个链表头地址:所有窗口,工作窗口 _headline *win_head,*work_win; //各工作窗口,设置成全局变量有利随时调用 _win Color_win,Pen_win,Line_win,Rectangle_win,Ellipse_win,Lineto_win;
//释放临时图象存储空间 void freeall() {free(Buf1); Buf1=NULL; free(Buf2); Buf2=NULL; free(Buf3); Buf3=NULL; free(Buf4); Buf4=NULL; } //设定鼠标移动范围与移动幅度 void cpset(int minx,int miny,int maxx,int maxy) {_CX=minx; _DX=maxx; _AX=7; geninterrupt(0x33); _CX=miny; _DX=maxy; _AX=8; geninterrupt(0x33); } //初始化鼠标样子,并把数据存储在一个链表中,然后返回链表头地址 _point *creat_cp() {int i,j,size; _point *head,*p,*q; head=(_point *)malloc(size=sizeof(_point)); p=head; for(i=0;i<=55;i++) {p->next=(_point *)malloc(size); q=p; p=p->next; } q->next=NULL; p=head; i=0; for(j=0;j<=2;j++) GB i++;//i=1 j=0;GB j=3;GB j=4;GB j=1;GW j=2;GW i++;//i=2 j=0;GB for(j=5;j<=7;j++) GB for(j=1;j<=4;j++) GW i++;//i=3 j=1;GB j=8;GB for(j=2;j<=7;j++) GW i++;//i=4 j=1;GB j=7;GB for(j=2;j<=6;j++) GW i++;//i=5 j=2;GB j=6;GB for(j=3;j<=5;j++) GW i++;//i=6 j=2;GB j=5;GB j=7;GB j=3;GW j=4;GW j=6;GW i++;//i=7 for(j=2;j<=8;j+=2) GB j=3;GW j=7;GW i++;//i=8 j=3;GB j=7;GB j=9;GB j=8;GW i++;//i=9 j=8;GB j=10;GB j=9;GW i++;//i=10 j=9;GB return head; }//end of creat_cp()
//输出存储在链表中的图象 void put_cp(int x,int y,_point *head) {int i; _point *p; p=head; for(i=0;p!=NULL;i++) {putpixel(x+p->x,y+p->y,p->color); p=p->next; } } //得到鼠标遮盖处的图象 void gettemp_cp(int x,int y,_point *head) {int i; _point *p; p=head; for(i=0;p!=NULL;i++) {p->color=getpixel(x+p->x,y+p->y); p=p->next; } } //恢复鼠标遮盖处图象并在新的地方显示鼠标,这样就实现了鼠标的移动 /*void move_cp() {put_cp(Pre_x,Pre_y,Tempcp_head); gettemp_cp(Cp_x,Cp_y,Tempcp_head); put_cp(Cp_x,Cp_y,Cp_head); Pre_x=Cp_x; Pre_y=Cp_y; }*/ //恢复鼠标遮盖处图象 void cp_off() { GETXY if(Cp_x!=Pre_x||Cp_y!=Pre_y) put_cp(Pre_x,Pre_y,Tempcp_head); } //恢复鼠标遮盖处图象并在新的地方显示鼠标,这样就实现了鼠标的移动 void cp_on() { GETXY gettemp_cp(Cp_x,Cp_y,Tempcp_head); put_cp(Cp_x,Cp_y,Cp_head); Pre_x=Cp_x; Pre_y=Cp_y; } /*void cpout() { if(Cp_x!=Pre_x||Cp_y!=Pre_y) move_cp(); }*/ //初始化各选择窗口内的图标 void win_mark() {int i,j; for(i=12;i<=16;i++) for(j=23;j<=32;j++) putpixel(i,j,BLUE); for(j=33;j<=37;j++) for(i=j-21;i<=49-j;i++) putpixel(i,j,j-29); setcolor(BLACK); moveto(35,24); lineto(42,37); lineto(28,37); lineto(28,34); lineto(33,34); lineto(35,24); setcolor(MAGENTA); rectangle(8,43,21,56); setcolor(BLUE); ellipse(34,50,0,360,7,5); setcolor(RED); line(8,63,21,76); } //初始化 void start() {Cp_head=creat_cp(); Tempcp_head=creat_cp(); gettemp_cp(320,240,Tempcp_head); put_cp(320,240,Cp_head); cpset(1,1,635,479); win_mark(); }
//绘制指定窗口 void draw_win(_win *p) {setfillstyle(SOLID_FILL,p->color); bar((p->lt).x,(p->lt).y,(p->rb).x,(p->rb).y); setcolor(WHITE*(p->condition)); line((p->lt).x,(p->lt).y,(p->rb).x,(p->lt).y); line((p->lt).x,(p->lt).y,(p->lt).x,(p->rb).y); setcolor(WHITE*!(p->condition)); line((p->rb).x,(p->rb).y,(p->rb).x,(p->lt).y); line((p->rb).x,(p->rb).y,(p->lt).x,(p->rb).y); setcolor(Thecolor); } //初始化各窗口的数据 void win_make() {int gd=DETECT,gm,size,i; _headline *head,*p,*q; _win main_win={{0,0},{640,480},LIGHTGRAY,1,0}, pic_win={{60,20},{629,419},WHITE,0} , title_win={{0,0},{640,19},LIGHTGRAY,1,0}, tool_win={{0,20},{59,419},LIGHTGRAY,1,0}, bottom_win={{60,430},{639,479},LIGHTGRAY,1,0}, pen_win={{5,20},{24,39},YELLOW,0,1}, line_win={{25,20},{44,39},YELLOW,1,1}, rectangle_win={{5,40},{24,59},YELLOW,1,1}, ellipse_win={{25,40},{44,59},YELLOW,1,1}, lineto_win={{5,60},{24,79},YELLOW,1,1}, color_win={{65,435},{164,454},LIGHTGRAY,0,0}, color0_win={{65,435},{74,444},BLACK,0,0}, color1_win={{75,435},{84,444},BLUE,0,0}, color2_win={{85,435},{94,444},GREEN,0,0}, color3_win={{95,435},{104,444},CYAN,0,0}, color4_win={{105,435},{114,444},RED,0,0}, color5_win={{115,435},{124,444},MAGENTA,0,0}, color6_win={{125,435},{134,444},BROWN,0,0}, color7_win={{135,435},{144,444},LIGHTGRAY}, color8_win={{65,445},{74,454},DARKGRAY,0,0}, color9_win={{75,445},{84,454},LIGHTBLUE,0,0}, color10_win={{85,445},{94,454},YELLOW,0,0}, color11_win={{95,445},{104,454},LIGHTCYAN,0,0}, color12_win={{105,445},{114,454},LIGHTRED,0,0}, color13_win={{115,445},{124,454},LIGHTMAGENTA,0,0}, color14_win={{125,445},{134,454},YELLOW,0,0}, color15_win={{135,445},{144,454},WHITE,0,0}, pencolor_win={{154,445},{164,454},BLACK,0,0}, zoom_win={{0,420},{59,479},WHITE,0,0}, roll_winx={{60,420},{629,429},LIGHTGRAY,0,0}, roll_winx1={{60,420},{69,429},LIGHTGRAY,1,0}, roll_winx2={{70,420},{559,429},LIGHTGRAY,1,0}, roll_winx3={{620,420},{629,429},LIGHTGRAY,1,0}, roll_winy={{630,20},{639,419},LIGHTGRAY,0,0}, roll_winy1={{630,20},{639,29},LIGHTGRAY,1,0}, roll_winy2={{630,30},{639,346},LIGHTGRAY,1,0}, roll_winy3={{630,410},{639,419},LIGHTGRAY,1,0}, point_win={{580,460},{629,469},LIGHTGRAY,0,0}, exit_win={{630,0},{639,9},BLUE,1,0}; initgraph(&gd,&gm,"d:\\tc30"); size=sizeof(_headline); Color_win=pencolor_win; Pen_win=pen_win; Line_win=line_win; Rectangle_win=rectangle_win; Ellipse_win=ellipse_win; Lineto_win=lineto_win; head=(_headline *)malloc(size); win_head=head; p=head; for(i=0;i<=38;i++) {p->next=(_headline *)malloc(size); q=p; p=p->next; } q->next=NULL; p=head; p->win=main_win;p->win_name=0;p=p->next; p->win=pic_win;p->win_name=PIC_WIN;p=p->next; p->win=title_win;p->win_name=0;p=p->next; p->win=tool_win;p->win_name=0;p=p->next; p->win=bottom_win;p->win_name=0;p=p->next; p->win=pen_win;p->win_name=PEN_WIN;p=p->next; p->win=line_win;p->win_name=LINE_WIN;p=p->next; p->win=rectangle_win;p->win_name=RECTANGLE_WIN;p=p->next; p->win=ellipse_win;p->win_name=ELLIPSE_WIN;p=p->next; p->win=lineto_win;p->win_name=LINETO_WIN;p=p->next; p->win=color_win;p->win_name=0;p=p->next; p->win=color0_win;p->win_name=COLOR0_WIN;p=p->next; p->win=color1_win;p->win_name=COLOR1_WIN;p=p->next; p->win=color2_win;p->win_name=COLOR2_WIN;p=p->next; p->win=color3_win;p->win_name=COLOR3_WIN;p=p->next; p->win=color4_win;p->win_name=COLOR4_WIN;p=p->next; p->win=color5_win;p->win_name=COLOR5_WIN;p=p->next; p->win=color6_win;p->win_name=COLOR6_WIN;p=p->next; p->win=color7_win;p->win_name=COLOR7_WIN;p=p->next; p->win=color8_win;p->win_name=COLOR8_WIN;p=p->next; p->win=color9_win;p->win_name=COLOR9_WIN;p=p->next; p->win=color10_win;p->win_name=COLOR10_WIN;p=p->next; p->win=color11_win;p->win_name=COLOR11_WIN;p=p->next; p->win=color12_win;p->win_name=COLOR12_WIN;p=p->next; p->win=color13_win;p->win_name=COLOR13_WIN;p=p->next; p->win=color14_win;p->win_name=COLOR14_WIN;p=p->next; p->win=color15_win;p->win_name=COLOR15_WIN;p=p->next; p->win=pencolor_win;p->win_name=0;p=p->next; p->win=zoom_win;p->win_name=0;p=p->next; p->win=roll_winx;p->win_name=0;p=p->next; p->win=roll_winx1;p->win_name=0;p=p->next; p->win=roll_winx2;p->win_name=0;p=p->next; p->win=roll_winx3;p->win_name=0;p=p->next; p->win=roll_winy;p->win_name=0;p=p->next; p->win=roll_winy1;p->win_name=0;p=p->next; p->win=roll_winy2;p->win_name=0;p=p->next; p->win=roll_winy3;p->win_name=0;p=p->next; p->win=point_win;p->win_name=0;p=p->next; p->win=exit_win;p->win_name=0; p=head; for(i=0;p!=NULL;i++) {draw_win(&(p->win)); p=p->next; } head=(_headline *)malloc(size); work_win=head; p=head; for(i=0;i<=21;i++) {p->next=(_headline *)malloc(size); q=p; p=p->next; } q->next=NULL; p=head; p->win=pic_win;p->win_name=PIC_WIN;p=p->next; p->win=color0_win;p->win_name=COLOR0_WIN;p=p->next; p->win=color1_win;p->win_name=COLOR1_WIN;p=p->next; p->win=color2_win;p->win_name=COLOR2_WIN;p=p->next; p->win=color3_win;p->win_name=COLOR3_WIN;p=p->next; p->win=color4_win;p->win_name=COLOR4_WIN;p=p->next; p->win=color5_win;p->win_name=COLOR5_WIN;p=p->next; p->win=color6_win;p->win_name=COLOR6_WIN;p=p->next; p->win=color7_win;p->win_name=COLOR7_WIN;p=p->next; p->win=color8_win;p->win_name=COLOR8_WIN;p=p->next; p->win=color9_win;p->win_name=COLOR9_WIN;p=p->next; p->win=color10_win;p->win_name=COLOR10_WIN;p=p->next; p->win=color11_win;p->win_name=COLOR11_WIN;p=p->next; p->win=color12_win;p->win_name=COLOR12_WIN;p=p->next; p->win=color13_win;p->win_name=COLOR13_WIN;p=p->next; p->win=color14_win;p->win_name=COLOR14_WIN;p=p->next; p->win=color15_win;p->win_name=COLOR15_WIN;p=p->next; p->win=pen_win;p->win_name=PEN_WIN;p=p->next; p->win=line_win;p->win_name=LINE_WIN;p=p->next; p->win=rectangle_win;p->win_name=RECTANGLE_WIN;p=p->next; p->win=ellipse_win;p->win_name=ELLIPSE_WIN;p=p->next; p->win=lineto_win;p->win_name=LINETO_WIN;p=p->next; }
//把数转化为字符的函数(用于显示鼠标的当前坐标,在屏幕右下方) char *getstr(long x) {char k,*a="0000000000"; int i,j=10; if(x==0) return("0"); for(i=0;x>=1;i++) {a[i]='0'+ (x % 10); x=x/10; } i--; for(j=0;j<=i/2;j++) {k=a[j]; a[j]=a[i-j]; a[i-j]=k; } a[i+1]='\0'; return(a); } //在一个小窗口中显示鼠标坐标 void outpoint() { if(Pre_x!=Cp_x||Pre_y!=Cp_y) {setfillstyle(SOLID_FILL,LIGHTGRAY); bar(585,462,628,468); setcolor(BLACK); outtextxy(585,460,getstr(Cp_x)); outtextxy(610,460,getstr(Cp_y)); } } //检测鼠标在哪个工作窗口内,并返回窗口代码 int where() {_headline *p; p=work_win; for(;p!=NULL;p=p->next) {if(Cp_x>((p->win).lt).x&&Cp_x<((p->win).rb).x &&Cp_y>((p->win).lt).y&&Cp_y<((p->win).rb).y) return p->win_name; } return 0; }
//改变窗口的凹凸(凸变凹或者凹变凸) void anti_win(_win *p) {setcolor(WHITE*(p->condition)); line((p->lt).x,(p->lt).y,(p->rb).x,(p->lt).y); line((p->lt).x,(p->lt).y,(p->lt).x,(p->rb).y); setcolor(WHITE*!(p->condition)); line((p->rb).x,(p->rb).y,(p->rb).x,(p->lt).y); line((p->rb).x,(p->rb).y,(p->lt).x,(p->rb).y); setcolor(Thecolor); }
[此贴子已经被作者于2004-10-12 10:25:12编辑过]