/* STDEG.INC */
BOOL CheckChineseOs(void) { outportb(0x03ce,0x06); return( (peekb(0x0040,0x0049)==3 && inportb(0x03cf)&0x0F!=0x0e)?1:0 ); }
void InitGr(void) { int gd=VGA,gm=VGAHI; static UINT hadinit=0; if( hadinit>0 ) return; /* 防止重复调用初始化函数 */ hadinit++; if( CheckChineseOs() ){ printf("\ \n注意:\ \nE.G.被设计成在英文DOS方式下运行\ \n如果被运行在中文DOS下,可能出现一些与原设计相悖的情况.\ \n\n按ESC键退出 E.G. 环境,其它键强制运行\ \n"); if( GetKey()==ESC ) exit(0); } initgraph(&gd,&gm,""); if( graphresult()!=grOk ){ printf("\nE.G. can not initializes graphics."); exit(1); } printf("Check HIMEM.SYS . . ."); if( !xms_init() ){ closegraph(); printf("\nXMS device not installed or not enough memory."); exit(1); } printf("done"); printf("\nLoad HZK16 & ASC16 to XMS . . ."); if( (xms_hzk16=xms_malloc(270))==ERROR ){ end_xms(); closegraph(); printf("\nError alloc XMS memory to load HZK16."); exit(1); } if( (xms_asc16=xms_malloc(5))==ERROR ){ xms_free(xms_hzk16); end_xms(); closegraph(); printf("\nError alloc XMS memory to load ASC16."); exit(1); } if( load_hzk16_2_xms()==ERROR ){ /* 不可以在此释放分配给字库和ASCII码的XMS内存,因它们已在装载函数内释放 */ end_xms(); closegraph(); printf("\nError load HZK16 or ASC16 to XMS."); exit(1); } printf("done"); printf("\nCheck MOUSE . . ."); reset_mouse(); if( !MOUSE_THERE ){ xms_free(xms_hzk16); xms_free(xms_asc16); end_xms(); closegraph(); printf("\nMOUSE not installed."); exit(1); } mouse_off(); printf("done"); printf("\nEasy Graphics initializes OK!"); mouse_on(); InstallEvent(); InitTimer(); atexit( CloseGr ); /* 注册退出函数,当中途意外调用exit时,保证系统不崩溃 */ }
void CloseGr(void) { static UINT hadclose=0; if( hadclose>0 ) return; /* 防止重复调用退出函数 */ hadclose++; EndTimer(); set_event_handler(0,0); xms_free( xms_hzk16 ); xms_free( xms_asc16 ); end_xms(); closegraph(); }
BOOL InBar(int x,int y,int l,int t,int r,int b) { return( (x>=l && x<=r && y>=t && y<=b)?1:0 ); }
int Max(int a,int b) { return( a>=b?a:b ); }
void FillBar(int l,int t,int r,int b,int style,int bkground) { struct fillsettingstype f; getfillsettings(&f); setfillstyle(style,bkground); mouse_off(); bar(l,t,r,b); mouse_on(); setfillstyle(f.pattern,f.color); }
BOOL WinMake(int l,int t,int r,int b,int bc,int frame,int status) { int i,frame_thick,color1,color2; if( frame==NULL_FRAME ) return(OK); switch(frame){ case STD_FRAME: /* 类似win95中菜单的边框 */ frame_thick=2; break; case BUTTON_FRAME: /* 边框宽度只有1个 */ frame_thick=1; break; case SHADOWLINE_FRAME: /* 带有阴阳线的边框 */ FillBar(l,t,r,b,SOLID_FILL,bc); mouse_off(); setcolor(15); line(l,t,r,t); line(l,t,l,b); setcolor(8); line(r,t,r,b); line(l,b,r,b); setcolor(8); for(i=0;i<2;i++){ line(l+4+i,t+4+i,r-3-i,t+4+i);/*up-*/ line(l+4+i,t+4+i,l+4+i,b-4-i);/*left|*/ line(l+4+i,b-5+i,r-5+i,b-5+i);/*bottom-*/ line(r-5+i,t+6-i,r-5+i,b-5+i);/*right|*/ setcolor(15); } mouse_on(); return(OK); default: /* 如非上述情况,则frame参数作为边框的宽度 */ frame_thick=frame; } /* switch end */ color1=(status==BUTTON_UP)?15:8; color2=(status==BUTTON_UP)?8:15; FillBar(l+1,t+1,r-1,b-1,SOLID_FILL,bc); mouse_off(); for(i=0;i<frame_thick;i++){ setcolor(color1); line(l,t+i,r-i,t+i);/*-*/ line(l+i,t,l+i,b-i);/*|*/ setcolor(color2); line(l+i,b-i,r,b-i);/*-*/ line(r-i,t+i,r-i,b);/*|*/ } mouse_on(); } /* function end */
void OutTextEx(int x,int y,int bkground,int color,unsigned char *hz) { FillBar(x,y,x+strlen(hz)*8,y+16,SOLID_FILL,bkground); mouse_off(); OutText(x,y,color,hz); mouse_on(); }
/* 直接写屏 & XMS字库读取技术显示字符串 */ void OutText(int x,int y,unsigned char color,unsigned char *hz) { long i; char far *ptr; SHORT movebit,ybit; struct xms_move block; struct viewporttype v; UBYTE by[32],by1,by2,byte1,byte2,bm; getviewsettings(&v); x+=v.left; y+=v.top; /* 考虑到有可能设置了一个非全屏幕的视 */ if( x<0 || y<0 || x>=639 || y>=479 || x>=v.right || y>=v.bottom ) return; ybit= y+15>=v.bottom?v.bottom-y:16; /* 使Y坐标不超过视的下边界 */ ybit= ybit<=0?0:ybit; /* 采用写方式2 */ outportb(0x3ce,5); outportb(0x3cf,2); /* 一次写4个位平面 */ outportb(0x3c4,2); outportb(0x3c5,255); outportb(0x3ce,8); while(*hz){ byte1=(UBYTE)*hz; byte2=(UBYTE)*(hz+1); if( (byte1>=0xa1 && byte1<=0xfe) && (byte2>=0xa1 && byte2<=0xfe) ){ UBYTE *byptr=by; if(x+15>v.right) break; /* 超出视区不显示 */ i=(byte1-0xa1)*94+byte2-0xa1; i<<=5; block.destination_handle=0; /* 将汉字点阵数据从扩充内存移至数组中 */ block.source_handle=xms_hzk16; block.destination_offset=(long)MK_FP(_DS,by); /* _DS用于小模式 */ block.source_offset=i; block.byte_count=32; xms_movedata( &block ); /* 因为一个字节含有8个像点,必须考虑到起始位置未处于x%8==0时的情况 */ /* 为此设置一个只从有效的x位置写起的偏移量movebit */ movebit=x%8; /* 起始位置在缓冲区中字节内相对偏移 */ for( i=0;i<ybit;i++ ){ ptr=MK_FP( 0xA000,(y+i)*80+x/8 ); by1=*byptr++; by2=*byptr++; /* 将汉字点阵的两个字节写入缓冲区 */ /* the first byte */ /* 要写8个像点的掩码,此掩码即为汉字的点阵信息,第一个字节 */ outportb( 0x3cf,by1>>movebit ); bm=*ptr; *ptr++=color; /* 将颜色值写入缓冲区 */ /* the second byte */ outportb( 0x3cf,(by1<<(8-movebit))|(by2>>movebit) ); /* 要写8个像点的掩码,第二个字节 */ bm=*ptr; *ptr++=color; /* the third byte,if movebit==0 not write */ if( movebit!=0 ){ /* 要写8个像点的掩码 */ outportb( 0x3cf,by2<<(8-movebit) ); bm=*ptr; *ptr=color; } } /* 显示汉字end */ x+=16; hz+=2; } else{ if(x+7>v.right) break; /* 超出视,则不显示 */ block.destination_handle=0; /* 将汉字点阵数据从扩充内存移至数组中 */ block.source_handle=xms_asc16; block.destination_offset=(long)MK_FP(_DS,by); /* _DS用于小模式 */ block.source_offset=byte1*16; block.byte_count=16; xms_movedata( &block ); movebit=x%8; /* 起始位置在缓冲区中字节内相对位移 */ for(i=0;i<ybit;i++){ ptr=MK_FP( 0xA000,(y+i)*80+x/8 ); by1=*(by+i); outportb( 0x3cf,by1>>movebit ); bm=*ptr; *ptr++=color; if( movebit!=0 ){ outportb( 0x3cf,by1<<(8-movebit) ); bm=*ptr; *ptr++=color; } } /* for end */ x+=8; hz++; } /* if ascii end */ } /* while end */ bm=bm; outportb(0x3ce,8); outportb(0x3cf,255); /* 缓冲区中每个字节的8位全部允许写 */ outportb(0x3ce,5); outportb(0x3cf,0); }
BOOL load_hzk16_2_xms() { FILE *fp,*fp1; /* 装载hzk16进扩充内存,需要一个已分配足够大容量的句柄 */ struct SREGS sregs; struct xms_move block; long string_length; long char_count=0L; if( (fp=fopen("hzk16","rb"))==NULL ) return(ERROR); if( (fp1=fopen("asc16","rb"))==NULL ){ fclose(fp); return(ERROR); } while( (string_length=fread(xms_2_basemem_buffer,1,XMS_BUF,fp))!=0 ){ block.byte_count=string_length; /* 实际读到的字节数 */ block.source_handle=0; block.source_offset=(long)MK_FP(_DS,xms_2_basemem_buffer); block.destination_handle=xms_hzk16; /* xms内存句柄 */ block.destination_offset=char_count; /* 在扩充内存中的偏移量 */ char_count+=string_length; /* 修正偏移量 */ if( xms_movedata( &block )==ERROR ){ fclose(fp); xms_free(xms_hzk16); return(ERROR); } } /* while end */ fclose(fp); while( (string_length=fread(xms_2_basemem_buffer,1,XMS_BUF,fp1))!=0 ){ block.byte_count=4096; /* 实际读到的字节数 */ block.source_handle=0; block.source_offset=(long)MK_FP(_DS,xms_2_basemem_buffer); block.destination_handle=xms_asc16; /* xms内存句柄 */ block.destination_offset=0; /* 在扩充内存中的偏移量 */ if( xms_movedata( &block )==ERROR ){ fclose(fp1); xms_free(xms_asc16); return(ERROR); } } /* while end */ fclose(fp1); return(OK); }
BOOL BackupWin(int l,int t,int r,int b,int *block,int imageblock[]); BOOL BackupWin(int l,int t,int r,int b,int *block,int imageblock[]) /* 参数:边界及将界面分成的块数blocks,*imageblock是希望得到一个指向xms内存\ 屏幕数据句柄的变量地址 */ { struct xms_move xms_block; int i,block_num,high,block_high; /* high每个分区块的高度 */ long total_size,block_size[XMS_BLOCK_NUM]; int handle; /* 一个临时句柄 */ high=b-t; total_size=imagesize(l,t,r,b); /* 因为 imagesize() 无法计算大于64K的位图,这里根据这个函数的原理计算之 */ if( total_size>65534 ) total_size=(long)((float)(r-l)*high/2.0+41); for(i=1;i<=XMS_BLOCK_NUM;i++) if( (float)total_size/(float)i < XMS_BUF ){ *block=block_num=i; break; } for( i=0,block_high=high/block_num;i<block_num;i++ ){ if(i==block_num-1) block_high=high-block_high*(block_num-1); block_size[i]=imagesize(l,t,r,t+block_high); mouse_off(); getimage(l,t,r,t+block_high,xms_2_basemem_buffer); mouse_on(); t+=block_high; handle=xms_malloc( block_size[i]/1024+1 ); imageblock[i]=handle; xms_block.byte_count=block_size[i]; xms_block.source_handle=0; xms_block.source_offset=(long)MK_FP(_DS,xms_2_basemem_buffer); xms_block.destination_handle=handle; xms_block.destination_offset=0; if( xms_movedata( &xms_block )==ERROR ){ xms_free(handle); return(ERROR); } } /* for end */ return(OK); }
BOOL RestoreWin(int l,int t,int r,int b,int block,int imageblock[]); BOOL RestoreWin(int l,int t,int r,int b,int block,int imageblock[]) /* 参数:边界及将界面分成的块数block,*imageblock是希望得到一个指向xms内存\ 屏幕数据句柄的变量地址 */ { struct xms_move xms_block; int i,high,block_high; /* high每个分区块的高度 */ long block_size[XMS_BLOCK_NUM]; high=b-t; r=r; for( i=0,block_high=high/block;i<block;i++ ){ if(i==block-1) block_high=high-block_high*(block-1); block_size[i]=imagesize(l,t,r,t+block_high); xms_block.byte_count=block_size[i]; xms_block.source_handle=imageblock[i]; xms_block.source_offset=0; xms_block.destination_handle=0; xms_block.destination_offset=(long)MK_FP(_DS,xms_2_basemem_buffer); if( xms_movedata( &xms_block )==ERROR ){ xms_free(imageblock[i]); return(ERROR); } mouse_off(); putimage(l,t,xms_2_basemem_buffer,COPY_PUT); mouse_on(); xms_free(imageblock[i]); t+=block_high; } /* for end */ return(OK); }
/* ...菜单函数对返回值的处理: 收到MENU_CLOSE时,关闭自己,关返回OK; */ /* 收到MENU_NOT_CLOSE时continu.收到MENU_CLOSE_ALL时关闭自己,关且返回 */ /* MENU_CLOSE_ALL */ /* ...菜单函数:只返回OK(当正常结束时),MENU_CLOSE_ALL(当要求所有菜单全关闭时 */ /* ...调用菜单的函数:当菜单返回OK时,由其决定父菜单的关闭与否,返回MENU_CLOSE*/ /* 或MENU_NOT_CLOSE;当菜单返回MENU_CLOSE_ALL,本身也返回MENU_CLOSE_ALL */ int PopMenu(struct CMenu (*m)) { int how_to_do, mx, my, redraw=1 ; int oldchoice, newchoice, left,top,right, bottom; int width=0, i, n, y; ClearKeyBuffer(); if( (*m).frame==NULL_FRAME ) redraw=0; /* this is for NULL_FRAME */ for(i=0,n=0;i<MAX_MENU_TITLE;i++){ if( ((*m).inf[i].info)!=NULL ) n++; else break; } for(i=0;i<n;i++) width=Max( strlen((*m).inf[i].info),width ); width*=8; left=(*m).left+6; top=(*m).top+8; right=(*m).left+width+6; bottom=(*m).top+(n+1)*16-8; if( (*m).left<0 || (*m).top<0 || ((*m).left+width+12)>639 || ((*m).top+(n+1)*16)>479 ){ SystemError.str1="[PopMenu]菜单坐标不合法"; SystemError.str2="坐标应该处在屏幕范围之内"; MessageBox( &SystemError ); return(ERROR); } if( BackupWin(left-6,top-8,right+6,bottom+8,&(*m).BackImageBlockNum,(*m).SaveBackImage)==ERROR){ SystemError.str1="[PopMenu]无足够内存创建菜单,如果经常出现"; SystemError.str2="此种现象,请与王家宝联系."; MessageBox( &SystemError ); return(ERROR); } WinMake(left-6,top-8,right+6,bottom+8,MENU_BACKGROUND,(*m).frame,BUTTON_UP); mouse_off(); for(i=0,y=top;i<n;i++,y+=16){ if( (*m).inf[i].info[0]=='-' ){ setcolor(DARKGRAY); line(left+7,y+8,right-9,y+8); setcolor(WHITE); line(left+8,y+9,right-8,y+9); continue; } /* draw a line end */ OutText(left,y,MENU_TEXT_COLOR,(*m).inf[i].info); } /* for end */ mouse_on(); if( redraw ){ FillBar(left,top,right,top+16,SOLID_FILL,MENU_CHOICE_BACKGROUND); mouse_off(); OutText(left,top,MENU_CHOICE_TEXT_COLOR,(*m).inf[0].info); mouse_on(); } else{ mouse_off(); OutText(left,top,MENU_CHOICE_TEXT_COLOR,(*m).inf[0].info); mouse_on(); } oldchoice=newchoice=0; A: for(;;){ if(MOUSE_MOVED){ MOUSE_MOVED=0; mx=CMX; my=CMY; if( mx>left && mx<right && my>top && my<bottom ){ newchoice=(my-top)/16; if(newchoice!=oldchoice){ if( (*m).inf[newchoice].info[0]!='-' ){ if( redraw ){ FillBar(left,oldchoice*16+top,right,oldchoice*16+top+16,SOLID_FILL,MENU_BACKGROUND); mouse_off(); OutText(left,oldchoice*16+top,MENU_TEXT_COLOR,(*m).inf[oldchoice].info); mouse_on(); FillBar(left,newchoice*16+top,right,newchoice*16+top+16,SOLID_FILL,MENU_CHOICE_BACKGROUND); mouse_off(); OutText(left,newchoice*16+top,MENU_CHOICE_TEXT_COLOR,(*m).inf[newchoice].info); mouse_on(); } else{ mouse_off(); OutText(left,oldchoice*16+top,MENU_TEXT_COLOR,(*m).inf[oldchoice].info); OutText(left,newchoice*16+top,MENU_CHOICE_TEXT_COLOR,(*m).inf[newchoice].info); mouse_on(); } oldchoice=newchoice; } /* 使提示信息随着光条的移动而改变 */ } } /* if mouse in menu end */ } /* cursor end */ if(RBUTTON_DOWN){ RBUTTON_DOWN=0; RestoreWin(left-6,top-8,right+6,bottom+8,(*m).BackImageBlockNum,\ (*m).SaveBackImage); return(OK); } if(LBUTTON_DOWN){ /* 如击左键在菜单内则调用函数进行处理 */ LBUTTON_DOWN=0; mx=CMX; my=CMY; if( InBar(mx,my,left,top,right,bottom-1) ){ if( (*m).inf[(my-top)/16].info[0]!='-' ){ if( redraw ){ FillBar(left,oldchoice*16+top,right,oldchoice*16+top+16,SOLID_FILL,MENU_BACKGROUND); mouse_off(); OutText(left,oldchoice*16+top,MENU_TEXT_COLOR,(*m).inf[oldchoice].info); mouse_on(); } else{ mouse_off(); OutText(left,oldchoice*16+top,MENU_TEXT_COLOR,(*m).inf[oldchoice].info); mouse_on(); } oldchoice=(my-top)/16; if( redraw ){ FillBar(left,oldchoice*16+top,right,oldchoice*16+top+16,SOLID_FILL,MENU_CHOICE_BACKGROUND); mouse_off(); OutText(left,oldchoice*16+top,MENU_CHOICE_TEXT_COLOR,(*m).inf[oldchoice].info); mouse_on(); } else{ mouse_off(); OutText(left,oldchoice*16+top,MENU_CHOICE_TEXT_COLOR,(*m).inf[oldchoice].info); mouse_on(); } KEYENTER: how_to_do=(*(*m).inf[oldchoice].function)(); switch( how_to_do ){ case MENU_CLOSE: EXIT: RestoreWin(left-6,top-8,right+6,bottom+8,(*m).BackImageBlockNum,\ (*m).SaveBackImage); return(OK); case MENU_NOT_CLOSE: MOUSE_MOVED=1; LBUTTON_DOWN=0; how_to_do=MENU_NOT_CLOSE; /* 被指示保持打开状态 */ goto A; case MENU_CLOSE_ALL: RestoreWin(left-6,top-8,right+6,bottom+8,(*m).BackImageBlockNum,\ (*m).SaveBackImage); LBUTTON_DOWN=0; return(MENU_CLOSE_ALL); default: /* perhpers the function is null() */ how_to_do=MENU_NOT_CLOSE; continue; } /* switch end */ } /* if lbutton in menu end */ } else{ /* press lbutton out of menu coords,close the menu */ RestoreWin(left-6,top-8,right+6,bottom+8,(*m).BackImageBlockNum,\ (*m).SaveBackImage); return(OK); } } /* if button down end */ if( Kbhit() ){ int kbcode; if( (kbcode=GetKey())==ENTER ) goto KEYENTER; if( kbcode==ESC ) goto EXIT; } } /* for end */ } /* function end */
BOOL InitDialog(struct CDialog *bm) { int l,t,r,b,i; /* the frame coords of menu */ if((*bm).left<0 || (*bm).top<0 || (*bm).right>639 || (*bm).bottom>479){ SystemError.str1="[InitDialog]对话框坐标不合法"; SystemError.str2="坐标应该处在屏幕范围之内"; MessageBox( &SystemError ); return(ERROR); } l=(*bm).left; t=(*bm).top; r=(*bm).right; b=(*bm).bottom; if( r-l>=639 && b-t>=479 ) (*bm).move=0; if( BackupWin(l,t,r,b,&(*bm).BackImageBlockNum, (*bm).SaveDialogBack)==ERROR){ SystemError.str1="[InitDialog]无足够内存创建对话框,如果经常出现"; SystemError.str2="此种现象,请与王家宝联系."; MessageBox( &SystemError ); return(ERROR); } WinMake(l,t,r,b,MENU_BACKGROUND,STD_FRAME,BUTTON_UP); FillBar( l+4,t+4,r-4,t+20 ,SOLID_FILL,LIGHTBLUE ); setviewport(l+4,0,r-((*bm).close?20:4),479,1); mouse_off(); OutText(0,(*bm).top+5,WHITE,(*bm).title); /* 写标题 */ mouse_on(); setviewport(0,0,639,479,1); if( (*bm).close ) /* 判断是否显示关闭按钮 */ Button( (*bm).right-20,(*bm).top+4,NULL,"x",BUTTON_UP); (*bm).active=1; /* 应用于无模式对话框 */ (*(*bm).draw)(*bm); /* 可以初始化客户区 */ }
int RunDialog( struct CDialog *bm ) { int x,y,distx,disty,mx,my; int ol,ot,or,ob,nl,nt,nr,nb; int once_in_title=0,return_value=DIALOG_CLOSE; if( !(*bm).active ) return(OK); nl=ol=(*bm).left; nt=ot=(*bm).top; nr=or=(*bm).right; nb=ob=(*bm).bottom; while( 1 ){ if( LBUTTON_DOWN ){
mx=CMX; my=CMY; if( InBar(mx,my,(*bm).right-20,(*bm).top+4,(*bm).right-4,\ /* 如果按了关闭按钮 */ (*bm).top+20) && (*bm).close ){ if( ActionButton((*bm).right-20,(*bm).top+4,NULL,"x")==0 ) continue; EXIT: RestoreWin(ol,ot,or,ob,(*bm).BackImageBlockNum,(*bm).SaveDialogBack); (*bm).active=0; reset_event_status(); ClearKeyBuffer(); return(return_value); } /* if pressed X button end */ if( InBar(mx,my,(*bm).left+4,(*bm).top+4,(*bm).right-((*bm).close?20:4),(*bm).top+20) &&\ (*bm).move ){ /* 在标题区内 */ distx=mx-(*bm).left; disty=my-(*bm).top; /* 设置mouse最大移动区 */ set_mousex(distx,639-( (*bm).right-(*bm).left-distx )); set_mousey(disty,479-( (*bm).bottom-(*bm).top-disty )); setwritemode(XOR_PUT); setcolor(8); setlinestyle(0,0,3); mouse_off(); rectangle(nl+1,nt+1,nr-1,nb-1); mouse_on(); while( !LBUTTON_UP ){ if( MOUSE_MOVED ){ MOUSE_MOVED=0; x=CMX; y=CMY; mouse_off(); rectangle(nl+1,nt+1,nr-1,nb-1); nl=x-distx; nt=y-disty; nr=x-distx+(*bm).right-(*bm).left; nb=y-disty+(*bm).bottom-(*bm).top; rectangle(nl+1,nt+1,nr-1,nb-1); mouse_on(); once_in_title=1; } /* if mosue_moved end */ } /* while lbutton_down title bar end */ set_mousex(1,639); set_mousey(1,479); if( once_in_title ){ mouse_off(); rectangle(nl+1,nt+1,nr-1,nb-1); mouse_on(); } setlinestyle(0,0,1); if( LBUTTON_UP ){ /* 松开左键结束移动,则将框移至新区域 */ reset_event_status(); if( ot==nt && ol==nl ){/* if new positon==old position do nothing */} else{ BackupWin(ol,ot,or,ob,&(*bm).BackImageBlockNum,(*bm).SaveDialogImage); RestoreWin(ol,ot,or,ob,(*bm).BackImageBlockNum,(*bm).SaveDialogBack); BackupWin(nl,nt,nr,nb,&(*bm).BackImageBlockNum,(*bm).SaveDialogBack); RestoreWin(nl,nt,nr,nb,(*bm).BackImageBlockNum,(*bm).SaveDialogImage); ol=nl; ot=nt; or=nr; ob=nb; } (*bm).left=ol; (*bm).top=ot; /* 保存新坐标 */ (*bm).right=or; (*bm).bottom=ob; setlinestyle(0,0,1); setwritemode(COPY_PUT); } continue; } /* if pressed title bar end */ setwritemode(COPY_PUT); setlinestyle(0,0,1); ClearKeyBuffer(); if( InBar(mx,my,(*bm).left+2,(*bm).top+22,(*bm).right-2,(*bm).bottom-2) ) if( (*(*bm).react)( mx, my, *bm, &return_value )==DIALOG_CLOSE ) goto EXIT;/* 如左键点在框内,则调用响应函数 */ LBUTTON_DOWN=0; continue; } /* if lbutton_down end */ if( Kbhit() ){ mx=my=-1; if( (*(*bm).react)( mx, my, (*bm), &return_value )==DIALOG_CLOSE ) goto EXIT; ClearKeyBuffer(); continue; } } /* while end */ } /* function end */
BOOL Button(int gl,int gt,char *btn_str,char *style,int status) { char kind,*p,*str[]={"确认","取消","开始 Start"}; int width, height, gr, gb, i, x, y, which_arrow,addbits; static int arrow[][8]={ 0x10,0x38,0x7c,0xfe,0x38,0x38,0x38,0x00, 0x00,0x38,0x38,0x38,0xfe,0x7c,0x38,0x10 }; /* arrow数组0为向上的,1为向下的 */ if( gl<0 || gt<0 ) return(ERROR); switch( (kind=toupper(style[0])) ){ case 'X': /* exit btn */ case 'U': width=X_BTN_W; height=X_BTN_H; /* up arrow btn */ which_arrow=0; break; case 'D': width=X_BTN_W; height=X_BTN_H; /* down arrow btn */ which_arrow=1; break; case 'C': /* check */ case 'R': width=CBtn_W; height=CBtn_H; /* radio */ p=NULL; break; case 'Y': width=NORMAL_BTN_W; height=NORMAL_BTN_H; /* yes btn */ p=str[0]; break; case 'N': width=NORMAL_BTN_W; height=NORMAL_BTN_H; /* no btn */ p=str[1]; break; case 'S': width=100; height=23; /* start btn*/ p=str[2]; break; default: width=NORMAL_BTN_W; height=NORMAL_BTN_H; p=btn_str; } gr=gl+width; gb=gt+height; WinMake(gl+1,gt+1,gr-1,gb-1,7,BUTTON_FRAME,status); if( kind=='U' || kind=='D' ){ /* 画箭头 */ if(status==BUTTON_UP) addbits=0; else addbits=1; /* 使其被向里按 */ mouse_off(); for(y=0;y<8;y++) for(x=0;x<8;x++) if( (arrow[which_arrow][y]>>(7-x)) &1 ) putpixel(gl+5+x+addbits,gt+5+y,BLACK); mouse_on(); return(OK); } /* if 'u' || 'd' end */ if( kind=='X' ){ /* 画关闭按钮 */ if(status==BUTTON_UP) addbits=0; else addbits=1; /* 使其被向里按 */ mouse_off(); for(i=0;i<2;i++){ setcolor(0); line(gl+4+addbits,gt+4+i,gr-4+addbits,gb-4+i); /* \ */ line(gr-4+addbits,gt+4+i,gl+4+addbits,gb-4+i); /* / */ } mouse_on(); return(OK); } /* if end */ i=gl+(int)(width/2.0-(strlen(p)/2.0)*8); mouse_off(); setcolor(BLACK); /* 给按钮加个框 */ rectangle(gl,gt,gr,gb); OutText(i+(status==BUTTON_UP?0:1),gt+5,style[1]==0?BTN_TEXT_COLOR:8,p); mouse_on(); return(OK); }
BOOL ActionButton(int l,int t,char *btn_str,char *style) { int width,height,r,b,x,y; if( LBUTTON_DOWN ) LBUTTON_UP=0; Button( l,t,btn_str,style,!BUTTON_UP); switch( toupper(style[0]) ){ case 'S': width=100; height=23; /* start btn*/ break; case 'X': /* exit btn */ case 'U': /* up arrow btn */ case 'D': width=X_BTN_W; height=X_BTN_H; /* down arrow btn */ break; case 'C': /* check */ case 'R': width=CBtn_W; height=CBtn_H; /* radio */ break; case 'Y': /* yes btn */ case 'N': /* no btn */ default: width=NORMAL_BTN_W; height=NORMAL_BTN_H; } r=l+width; b=t+height; while( !LBUTTON_UP ) ; LBUTTON_UP=0; x=CMX; y=CMY; Button( l,t,btn_str,style,BUTTON_UP); return( InBar(x,y,l,t,r,b) ); }
int MessageBox(struct CMessageBox *w) { int x,y,which,i,return_value,x_width,y_width,max_str; char whichchar; struct CDialog bm; x_width=(NORMAL_BTN_W+6)*(*w).style+16; y_width=NORMAL_BTN_H+76; max_str=Max( strlen((*w).str1),strlen((*w).str2) ); x_width=Max( x_width,max_str*8+8 ); if( x_width>639 ) ; bm.title=(*w).title; msg_btn_num=(*w).style; bm.left=319-x_width/2; bm.top=239-y_width/2; bm.right=319+x_width/2;; bm.bottom=239+y_width/2; bm.close=(*w).close; bm.move=(*w).move; msgbox_str1=(*w).str1; msgbox_str2=(*w).str2; bm.draw=gMessageBoxDraw; bm.react=gMessageBoxReact; for(i=msg_btn_num;i>0;i--){ msg_btn[msg_btn_num-i][0]=2+(NORMAL_BTN_W+6)*i; msg_btn[msg_btn_num-i][1]=6+NORMAL_BTN_H; } if( InitDialog(&bm)==ERROR) return(ERROR); return( RunDialog( &bm ) ); }
static int gMessageBoxDraw(struct CDialog bm) { int i; char *which_btn[]={"y","n"}; setviewport(bm.left,bm.top+22,bm.right,bm.bottom,1); mouse_off(); OutText( 6,6,MENU_TEXT_COLOR,msgbox_str1 ); OutText( 6,26,MENU_TEXT_COLOR,msgbox_str2 ); mouse_on(); setviewport(0,0,639,479,1); for(i=0;i<msg_btn_num;i++) if( msg_btn[i][0]>0 ) /* 条件显示2个按钮,顺序为y,n */ Button( bm.right-msg_btn[i][0],bm.bottom-msg_btn[i][1],NULL,which_btn[i],BUTTON_UP); }
int gMessageBoxReact(int x,int y,struct CDialog bm ,int *return_value) { /* the funcion return whether Dialog close, return_value tell RunDialog the function what had done */ int which,tmp_btn[2][2],pressed=0,key; char *whichchar[]={"y","n"}; for(which=0;which<msg_btn_num;which++){ tmp_btn[which][0]=bm.right-msg_btn[which][0]; tmp_btn[which][1]=bm.bottom-msg_btn[which][1]; } for(which=0;which<msg_btn_num;which++) /* 判断哪个按钮被按了 */ if(InBar(x,y,tmp_btn[which][0],tmp_btn[which][1],tmp_btn[which][0]+\ NORMAL_BTN_W,tmp_btn[which][1]+NORMAL_BTN_H) ){ pressed=1; break; } if( pressed ){ if( !ActionButton(tmp_btn[which][0],tmp_btn[which][1],NULL,whichchar[which]) ) return(DIALOG_NOT_CLOSE); *return_value=which; KEYPRESS: return(DIALOG_CLOSE); } if( Kbhit() ){ if( (key=GetKey())==ENTER ){ *return_value=0; pressed=1; goto KEYPRESS ; } if( key==ESC && msg_btn_num==2 ){ *return_value=1; pressed=1; goto KEYPRESS ; } } }
int GetBtnStatus(int groupnum,int member,struct CButton btn[]) { int i,num; if( btn[groupnum].style==CHECK ) /* check */ return( btn[groupnum].status[member] ); else{ /* radio */ num=btn[groupnum].num; for(i=0;i<num;i++) if( btn[groupnum].status[i] ) return( i ); } }
void InitBtn(int group,struct CButton btn[],struct CDialog bm) { int i,j,l,t; GROUPS=group; mouse_off(); for(i=0;i<group;i++) for(j=0;j<btn[i].num;j++){ l=bm.left+btn[i].btncoord[j][0]+4; t=bm.top+22+btn[i].btncoord[j][1]+4; if( btn[i].style==CHECK ){ WinMake(l,t,l+CBtn_W,t+CBtn_H,MENU_BACKGROUND,BUTTON_FRAME,!BUTTON_UP); if( btn[i].status[j] ) OutText(l+1,t-4,0,"x"); } else CreatRadioBtn(l+CBtn_W/2,t+CBtn_H/2,!btn[i].status[j]); OutText(l+CBtn_W+4,t-4,MENU_TEXT_COLOR,btn[i].btntip[j]); } mouse_on(); }
void CreatRadioBtn(int ox,int oy,int status) { int colorcircle; colorcircle=(status==BUTTON_UP)?MENU_BACKGROUND:BLACK; setcolor(8); setfillstyle(SOLID_FILL,MENU_BACKGROUND); mouse_off(); fillellipse(ox,oy,CBtn_W-4,CBtn_H-4); if( status!=BUTTON_UP ){ setfillstyle(SOLID_FILL,colorcircle); fillellipse(ox,oy,CBtn_W-6,CBtn_H-6); } mouse_on(); }
int BtnReact(int x,int y,struct CButton btn[],struct CDialog bm) { int i,j,k,l,t; for(i=0;i<GROUPS;i++) for(j=0;j<btn[i].num;j++){ l=bm.left+btn[i].btncoord[j][0]+4; t=bm.top+22+btn[i].btncoord[j][1]+4; if( InBar(x,y,l,t-4,l+CBtn_W+strlen(btn[i].btntip[j])*8,t+CBtn_H+12) ){ /* 点中一个按钮 */ if( btn[i].style==CHECK ){ btn[i].status[j]=!btn[i].status[j]; WinMake(l,t,l+CBtn_W,t+CBtn_H,MENU_BACKGROUND,BUTTON_FRAME,!BUTTON_UP); if( btn[i].status[j] ){ mouse_off(); OutText(l+1,t-4,0,"x"); mouse_on(); } return(OK); } if(btn[i].style==RADIO ){ for(k=0;k<btn[i].num;k++) if( btn[i].status[k] && k!=j ){ btn[i].status[k]=0; btn[i].status[j]=1; l=bm.left+btn[i].btncoord[k][0]+4; t=bm.top+22+btn[i].btncoord[k][1]+4; CreatRadioBtn(l+CBtn_W/2,t+CBtn_H/2,BUTTON_UP); l=bm.left+btn[i].btncoord[j][0]+4; t=bm.top+22+btn[i].btncoord[j][1]+4; CreatRadioBtn(l+CBtn_W/2,t+CBtn_H/2,!BUTTON_UP); return(OK); } } /* if radio end */ } /* biggest if end */ } /* the second for end */ return(OK); }
int gEditField(int l,int t,int r,int b,int n,struct CEdit g[],int yes_x,\ int yes_y,int no_x,int no_y,char *title) /* n is howmany edit filed,the edit not have Date type */ /* only return 0 or 1, 0 is yes, 1 is no */ { int i, j, x, y, ld, c, p, show=1,mx, my, count; struct CDialog bm; ClearKeyBuffer(); if( l<0 || t<0 || r>639 || b>479){ SystemError.str1="[gEditField]函数EditField出错,边界超界"; SystemError.str1=NULL; MessageBox( &SystemError ); return(ERROR); } oldx=-8; oldy=-8; bm.title=title; bm.left=l; bm.top=t; bm.right=r; bm.bottom=b; bm.close=0; bm.move=0; bm.draw=null; bm.react=null; if( InitDialog( &bm )==ERROR) return(ERROR); /* 初始化框 */ if( yes_x>=0 ) Button(l+yes_x,t+22+yes_y,NULL,"y",BUTTON_UP); if( no_x>=0 ) Button(l+no_x,t+22+no_y,NULL,"n",BUTTON_UP); for(i=0;i<n;i++){ mouse_off(); OutText(l+g[i].sx,t+22+g[i].sy,g[i].color,g[i].s); mouse_on(); WinMake(l+g[i].ex-1,t+22+g[i].ey-2,l+g[i].ex+1+g[i].w*8,t+22+g[i].ey+18,G_EDIT_FILL_COLOR,\ BUTTON_FRAME,!BUTTON_UP); mouse_off(); OutText(l+g[i].ex,t+22+g[i].ey-2,g[i].color,g[i].e); mouse_on(); } /* end for */ ClearKeyBuffer(); i=0;p=0; #define CURS_TIME 7604 CreateTimer(2,CURS_TIME); do{ if( CheckTimeOut( CURS_TIME ) ) Curs(l+g[i].ex+p*8,t+22+g[i].ey,(show=!show)); if(LBUTTON_DOWN){ LBUTTON_DOWN=0; mx=CMX; my=CMY; if(InBar(mx,my,l+yes_x,t+22+yes_y,l+yes_x+NORMAL_BTN_W,t+22+yes_y+NORMAL_BTN_H)){ if( ActionButton(l+yes_x,t+22+yes_y,NULL,"y")==0 ) continue; EXITEDIT: RestoreWin( l,t,r,b+1,bm.BackImageBlockNum,bm.SaveDialogBack); ReleaseTimer(CURS_TIME); return(0); } if(InBar(mx,my,l+no_x,t+22+no_y,l+no_x+NORMAL_BTN_W,t+22+no_y+NORMAL_BTN_H)){ if( ActionButton(l+no_x,t+22+no_y,NULL,"n")==0 ) continue; RestoreWin( l,t,r,b+1,bm.BackImageBlockNum,bm.SaveDialogBack); ReleaseTimer(CURS_TIME); return(1); } for(count=0;count<n;count++) /*check whethe mouse press in editfiled*/ if(InBar(mx,my,l+g[count].ex,t+22+g[count].ey,l+g[count].ex+g[count].w*8,\ t+22+g[count].ey+16)){ i=count; p=0; break; } /* if mouse in filed press end */ } /* if LBUTTON_DOWN end */ if( Kbhit() ){ switch(c=GetKey()){ case UP: if( i>0 ) i--; p=0; break; case DOWN: if( i<n-1 ) i++; p=0; break; case LEFT: if(p>0) p--; break; case RIGHT: if( p<g[i].w-1 && p<strlen(g[i].e)-1 ) p++; break; case ENTER: if( n==1 ) goto EXITEDIT; if( i<n-1 ) i++; p=0; break; case HOME: p=0;break; case END: p= strlen(g[i].e)==0?0:strlen(g[i].e)-1; break; case INS: insert=!insert; break; case BACKSPACE: if(p==0) break; if(toupper(g[i].p[0])=='N' && g[i].e[p-1]=='.'){ p--;break;} if( toupper(g[i].p[0])=='N') g[i].e[p-1]=' '; /* in the ' '=space */ else{ memmove(&g[i].e[p-1],&g[i].e[p],g[i].w-p); g[i].e[g[i].w-1]='\0';} /* int the '_' */ WinMake(l+g[i].ex-1,t+22+g[i].ey-2,l+g[i].ex+1+g[i].w*8,t+22+g[i].ey+18,G_EDIT_FILL_COLOR,\ BUTTON_FRAME,!BUTTON_UP); mouse_off(); OutText(l+g[i].ex,t+22+g[i].ey-2,g[i].color,g[i].e); mouse_on(); p--; break; case DEL: if(toupper(g[i].p[0])=='N' && g[i].e[p]=='.') break; if(g[i].w==1) g[i].e[0]=NULL; else{ if( toupper(g[i].p[0]=='N') ) g[i].e[p]=' '; else{ memmove(&g[i].e[p],&g[i].e[p+1],g[i].w-p); g[i].e[g[i].w-1]=NULL; /* in the '_' */ } } WinMake(l+g[i].ex-1,t+22+g[i].ey-2,l+g[i].ex+1+g[i].w*8,t+22+g[i].ey+18,G_EDIT_FILL_COLOR,\ BUTTON_FRAME,!BUTTON_UP); mouse_off(); OutText(l+g[i].ex,t+22+g[i].ey-2,g[i].color,g[i].e); mouse_on(); break; case ESC: case PGUP: case PGDN: case TAB: continue; default: switch(toupper(g[i].p[0])){ /* the @ switch */ case 'C': switch(toupper(g[i].p[1])){ case 'N': if(!isdigit(c)) continue; break; case 'A': if(!isalpha(c)) continue; break; case 'B': if(!isalnum(c)) continue; break; } break; } /* the @ switch end */ if(p<g[i].w){ if(insert){ switch(toupper(g[i].p[0])){ case 'C': memmove(&g[i].e[p+1],&g[i].e[p],g[i].w-p-1); break; } } g[i].e[p]=c; WinMake(l+g[i].ex-1,t+22+g[i].ey-2,l+g[i].ex+1+g[i].w*8,t+22+g[i].ey+18,G_EDIT_FILL_COLOR,\ BUTTON_FRAME,!BUTTON_UP); mouse_off(); OutText(l+g[i].ex,t+22+g[i].ey-2,g[i].color,g[i].e); mouse_on(); p++; } /* if(p<g[i].w) end */ if(p==g[i].w) p=g[i].w-1; } /* switch end */ } /* if kbhit end */ }while(1); /* do while cycle end */ }
void Curs(int x, int y,int show) { mouse_off(); if(oldx!=x || oldy!=y){ setcolor(G_EDIT_FILL_COLOR); line(oldx,oldy+16,oldx+8,oldy+16); /* earse the old Curs */ line(oldx,oldy+17,oldx+8,oldy+17); /* earse the old Curs */ } if( show ) setcolor(YELLOW); else setcolor(G_EDIT_FILL_COLOR); line(x,y+16,x+8,y+16); line(x,y+17,x+8,y+17); oldx=x; oldy=y; mouse_on(); }
int Select(int wl,int wt,int wr,int wb,char *str[]) /* 窗口的坐标为图形的,凡涉及到实际作图函数的坐标的为图形的,否则为文本坐标, 窗口的坐标必须为 16 的倍数, 调用方法: char *str[]={"123", ... ,"dataEND122", "NULL" };数组必须以NULL结尾 "NULL" is the end flag of select() 传给此函数的str[]的最后一个*str必须为"NULL",it a string, not a '\0' */ { int i,n,HScroll_height,HScroll_start; int w_old_ligter=0,w_ligter=0,w_height,str_end=-1,str_old_option=0,str_option=0; /* 老的加亮的T ,此为加亮的T,窗口高度T,字串尾,将被擦除的老的选项,当前被选择的*/ int need_draw=1,must_redraw=0,key,double_press=0;/* 是否重写WIN */ char tmp[80]; if( (wr-wl)/16<2 || (wb-wt)/16<3 || (wr-wl)%16 || (wb-wt)%16 || wl<0 || wt<0 || wr>639 || wb>479 || wl>=wr || wt>=wb ){ SystemError.str1="[Select]列表选择函数的坐标不合法"; SystemError.str2="宽与高应该为16倍数,并且坐标不应超出屏幕范围"; MessageBox( &SystemError ); return(NOSELECT); } while( strcmp(strupr(strcpy(tmp,str[++str_end])),"NULL")!=0 ); if( str_end==0 ) return(NOSTRING); /* No string can be select */ w_height=(wb-wt)/16; /* 计算窗口高度*/ WinMake(wr-14,wt+16,wr,wb-16,7,BUTTON_FRAME,BUTTON_UP); Button(wr-15,wt,NULL,"U",BUTTON_UP); Button(wr-15,wb-16,NULL,"D",BUTTON_UP); wr-=16; /* left the scroll bar space */ FillBar(wl,wt,wr,wb,SOLID_FILL,MENU_BACKGROUND); for(;;){ if(need_draw){ /* 如果窗口不必重画,就略过,提高速度,防止闪烁 */ for(i=0,n=str_option-w_ligter;i<w_height;i++,n++){ /*准备重画整个窗口*/ setviewport(0,0,639,479,1); if( w_ligter==0 || w_ligter==w_height-1 || must_redraw ){ /*窗口必须滚动,其中的全部选项必须更新*/ FillBar(wl,wt+i*16,wr,wt+(i+1)*16,SOLID_FILL,MENU_BACKGROUND); if( n<str_end && n>=0 ){ /*处理最后的选项不在窗口最下端的情况*/ if( i>=str_end ) break; setviewport(wl,wt,wr,wb,1); mouse_off(); OutText(0,i*16,MENU_TEXT_COLOR,str[n]); mouse_on(); } } /* if end */ else{ /*窗口不必滚动,只需让亮条移动即可,对旧亮条选项进行更新*/ FillBar(wl,wt+w_old_ligter*16,wr,wt+(w_old_ligter+1)*16,SOLID_FILL,MENU_BACKGROUND); setviewport(wl,wt,wr,wb,1); mouse_off(); OutText(0,w_old_ligter*16,MENU_TEXT_COLOR,str[str_old_option]); mouse_on(); } /* else end */ } /* for end */ setviewport(0,0,639,479,1); /* 重画正在被选择的亮条 */ FillBar(wl,wt+w_ligter*16,wr,wt+(w_ligter+1)*16,SOLID_FILL,MENU_CHOICE_BACKGROUND); setviewport(wl,wt,wr,wb,1); mouse_off(); OutText(0,w_ligter*16,MENU_CHOICE_TEXT_COLOR,str[str_option]); mouse_on(); /* 更新显示进度条 */ setviewport(0,0,639,479,1); if(str_end>w_height){ HScroll_height=(int)((float)(wb-wt-32)/(float)str_end*(float)w_height); HScroll_start=(int)((float)(wb-HScroll_height-wt-32)/(float)(str_end-1)*(float)str_option); FillBar(wr+1,wt+16,wr+16,wt+16+HScroll_start,SOLID_FILL,7); FillBar(wr+1,wt+16+HScroll_height+HScroll_start,wr+16,wb-16,SOLID_FILL,7); WinMake(wr+2,wt+16+HScroll_start,wr+16,wt+16+HScroll_start+HScroll_height,7,BUTTON_FRAME,BUTTON_UP); } /* if end */ } /* if end */ if( double_press ) return(str_option); need_draw=0; if( LBUTTON_DOWN ){ int tmpx,tmpy; tmpx=CMX; tmpy=CMY; if( InBar(tmpx,tmpy,wl+1,wt+1,wr-1,wb-1) ){ int press_postion=(tmpy-wt)/16; if( str_option+press_postion-w_ligter>str_end-1 ){ LBUTTON_DOWN=0; /* here is where >maxstrings,no react */ continue; } w_old_ligter=w_ligter; str_old_option=str_option; w_ligter=press_postion; str_option+=press_postion-w_old_ligter; need_draw=1; if( get_double_press() ) double_press=1; LBUTTON_DOWN=0; continue; } /* press in test window end */ if( InBar(tmpx,tmpy,wr+1,wt+1,wr+15,wt+15) ){ if( !ActionButton(wr+1,wt,NULL,"u") ) continue; need_draw=1; key=UP; reset_event_status(); goto MOUSE_OPERATION; } if( InBar(tmpx,tmpy,wr+1,wt+17,wr+15,wt+17+HScroll_start) ){ need_draw=1; key=PGUP; reset_event_status(); goto MOUSE_OPERATION; } if( InBar(tmpx,tmpy,wr+1,wt+17+HScroll_height+HScroll_start,wr+15,wb-17) ){ need_draw=1; key=PGDN; reset_event_status(); goto MOUSE_OPERATION; } if( InBar(tmpx,tmpy,wr+1,wb-15,wr+15,wb-1) ){ if( !ActionButton(wr+1,wb-16,NULL,"d") ) continue; need_draw=1; key=DOWN; reset_event_status(); goto MOUSE_OPERATION; } LBUTTON_DOWN=0; } /* lbtn_down end */ if( Kbhit() ){ need_draw=1; key=GetKey(); MOUSE_OPERATION: switch( key ){ case UP:if( str_end>0 ){ if( str_option==0 ){ need_draw=0; break; } if(w_ligter>=0){ /* 如果亮条未到达上边界*/ w_old_ligter=w_ligter; if( w_ligter>0 ) w_ligter--; str_old_option=str_option--; break; } } /* if str_end>0 end */ break; case DOWN:if( str_end>0 ){ if(str_option==str_end-1){ need_draw=0; break; } if(w_ligter<=w_height-1){ w_old_ligter=w_ligter; if( w_ligter<w_height-1 ) w_ligter++; str_old_option=str_option++; break; } } /* str_end >0 end */ break; case HOME:if(str_end>0){ if( str_option==0 ){ need_draw=0; break; } str_old_option=str_option; str_option=0; w_old_ligter=w_ligter; w_ligter=0; } break; case END: if(str_end>0){ if( str_option==str_end-1 ){ need_draw=0; break; } str_old_option=str_option; str_option=str_end-1; w_old_ligter=w_ligter; if( str_end<w_height ) w_ligter=str_end-1; else w_ligter=w_height-1; } break; case PGUP:if(str_end>0){ if( str_option==0 ){ need_draw=0 ; break; } must_redraw=1; str_old_option=str_option; w_old_ligter=w_ligter; if( str_option-w_height*2>=0 ){ str_option-=w_height; break; } else str_option=w_ligter=0; } break; case PGDN: if(str_end>0){ if( str_option==str_end-1 ){need_draw=0; break; } must_redraw=1; str_old_option=str_option; w_old_ligter=w_ligter; if( str_option+w_height<str_end ) str_option+=w_height; else{ str_option=str_end-1; if( str_end<w_height ) w_ligter=str_end-1; else w_ligter=w_height-1; } } break; case ESC: return(NOSELECT); case ENTER:return(str_option); default: need_draw=0; continue; } /* end switch */ } /* if kbhit() end */ } /* end for */ } /* end function */
int WinReadTxt(struct CReadTxt r) { int x, y, l, t; struct CDialog bm; if( (r.txtbottom-r.txttop)%16!=0 || (r.txtright-r.txtleft)%16!=0 ){ SystemError.str1="函数ReadTxtFile出错,边界未对齐"; SystemError.str2="显示区域的长&宽皆应为16的倍数"; MessageBox( &SystemError ); return(ERROR); } bm.title=r.txtfilename; bm.left=r.left; bm.top=r.top; bm.right=r.right; bm.bottom=r.bottom; wl=r.txtleft; wt=r.txttop; wr=r.txtright; wb=r.txtbottom; bm.close=1; bm.move=1; bm.draw=null; bm.react=ActTxtWinButton; if( (TxtFileHandle=fopen(r.txtfilename,"rb"))==NULL) return(ERROR); if( InitDialog( &bm )==ERROR ) return(ERROR); /* sub init readtxt window */ Button(bm.right-20,bm.top+20,NULL,"U",BUTTON_UP); Button(bm.right-20,bm.bottom-20,NULL,"d",BUTTON_UP); WinMake(bm.right-19,bm.top+22+16,bm.right-20+15,\ /*上翻页*/ bm.top+20+(bm.bottom-bm.top-20)/2,LIGHTGRAY,BUTTON_FRAME,BUTTON_UP); WinMake(bm.right-19,bm.top+22+(bm.bottom-bm.top-20)/2,bm.right-20+15,\ /*下翻页*/ bm.bottom-22,LIGHTGRAY,BUTTON_FRAME,BUTTON_UP); mouse_off(); ReadTxtFile( bm.left+wl,bm.top+22+wt,bm.left+wr,bm.top+22+wb,INITTXTWIN); mouse_on(); /* end init */ RunDialog( &bm ); fclose(TxtFileHandle); return(OK); }
int ActTxtWinButton(int mx,int my,struct CDialog bm) { int key; if( InBar(mx,my,bm.right-19,bm.top+21+16,bm.right-20+16,\ /* PGUP */ bm.top+20+(bm.bottom-bm.top-20)/2) ) key=PGUP; if( InBar(mx,my,bm.right-19,bm.top+22+(bm.bottom-bm.top-20)/2,\ /* PGDN */ bm.right-20+16,bm.bottom-22) ) key=PGDN; if( InBar(mx,my,bm.right-20,bm.top+20,bm.right-20+16,bm.top+20+16) ) key=UP; if( InBar(mx,my,bm.right-20,bm.bottom-4-16,bm.right-20+16,bm.bottom-4) ) key=DOWN; if( key==UP || key==DOWN || key==PGUP || key==PGDN ){ mouse_off(); while( !LBUTTON_UP ) ReadTxtFile(bm.left+wl,bm.top+22+wt,bm.left+wr,bm.top+22+wb,key); reset_event_status(); mouse_on(); return(DIALOG_NOT_CLOSE); } if( Kbhit() ){ key=GetKey(); ClearKeyBuffer(); if( key==ESC ) return(DIALOG_CLOSE); if( key==UP||key==DOWN||key==PGUP||key==PGDN ){ mouse_off(); ReadTxtFile(bm.left+wl,bm.top+22+wt,bm.left+wr,bm.top+22+wb,key); mouse_on(); return(OK); } /* if have txtwinkey is pressed end */ else return(OK); } }
int ReadTxtFile(int left,int top,int right,int bottom,int key) /* 显示区的长度与宽度必须同时为16的倍数 */ { char tmp[3]; char *linenumerr="所定义文本行数小于显示的文本行数"; static unsigned long count1,count2; static int x,y,maxline,linenum=0; static long fileoffset; static unsigned char endflag,eoln; unsigned char ch1,ch2; int backactionbutton=0; /* 当显示完毕后,返回响应函数的标志 */ if( linenum>=MAXLINENUM ){ SystemError.str1=linenumerr; MessageBox( &SystemError ); return(ERROR); } setfillstyle(SOLID_FILL,TXT_WIN_BACKGROUND); if( key!=INITTXTWIN ) goto JMP_HERE; bar(left,top,right,bottom); for(count1=1;count1<MAXLINENUM;count1++) lineaddr[count1]=-1L; maxline=(bottom-top)/16; x=left; y=top; linenum=0; lineaddr[0]=fileoffset=0L; endflag=0; count1=count2=0; while(1){ endflag=0; while(!endflag){ eoln=0; while(!eoln){ if(count2==count1){ if(count1!=0) fileoffset+=XMS_BUF-10; if((count2<XMS_BUF-10) && (count2!=0)){ endflag=1; break; } if( (count1=read(fileno(TxtFileHandle),xms_2_basemem_buffer,(int)XMS_BUF-10))==-1) /* 有可能读失败 */ return( ERROR ); count1--; if(count1<XMS_BUF-10){ for(count2=count1;count2<XMS_BUF-10;++count2) xms_2_basemem_buffer[count2]=0; } count2=0; } ch1=xms_2_basemem_buffer[count2++]; if( ch1&0x80 ){ tmp[0]=ch1; tmp[1]=(unsigned char)xms_2_basemem_buffer[count2++];tmp[2]='\0'; setviewport(left,top,right,bottom,1); OutText(x-left,y-top,TXT_WIN_TEXT,tmp); setviewport(0,0,639,479,1); if( x+16>right ) count2-=2; x+=16; } else{ switch(ch1){ case '\r': break; case '\n': y+=16; x=left; eoln=1; lineaddr[++linenum]=fileoffset+count2; break; case '\t': x+=64; break; default: tmp[0]=ch1; tmp[1]='\0'; setviewport(left,top,right,bottom,1); OutText(x-left,y-top,TXT_WIN_TEXT,tmp); setviewport(0,0,639,479,1); x+=8; break; } } if(x>=right){ lineaddr[++linenum]=fileoffset+count2; y+=16; x=left; eoln=1; } } if( linenum>=MAXLINENUM ){ SystemError.str1=linenumerr; MessageBox( &SystemError ); return(ERROR); } if( (y>=bottom) || (count1<XMS_BUF-10) && (count1==count2) ){ JMP_HERE: if( key==INITTXTWIN ) return(OK); if( backactionbutton ) return(OK); x=left; y=top; bar(left,top,right,bottom); backactionbutton=1; switch( key ){ case ESC: return(DIALOG_CLOSE); case PGUP: linenum-=maxline*2; if(linenum<0) linenum=0; fileoffset=lineaddr[linenum]; fseek(TxtFileHandle,fileoffset,SEEK_SET); count1=count2=0; break; case PGDN: if(linenum<0) linenum=0; fileoffset=lineaddr[linenum]; fseek(TxtFileHandle,fileoffset,SEEK_SET); count1=count2=0; break; case UP: linenum-=maxline+1; if(linenum<0) linenum=0; fileoffset=lineaddr[linenum]; fseek(TxtFileHandle,fileoffset,SEEK_SET); count1=count2=0; break; case DOWN: linenum-=maxline-1; if(linenum<0) linenum=0; fileoffset=lineaddr[linenum]; fseek(TxtFileHandle,fileoffset,SEEK_SET); count1=count2=0; break; } /* switch end */ } } /* while end */ } /* while end */ } /* function end */ 
|