分享
 
 
 

EGL--标准基础类实现文件 STDEG.INC

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

/*

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 */

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有