/*
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 */
本文地址:http://com.8s8s.com/it/it25079.htm