/*====================================================[ WIND98.C ]======*/ /* */ /* ウィンドゥライブラリー for Turbo−C */ /* ver 2.12 H4/12/05 by S.F */ /* */ /*----------------------------------------------------------------------*/ #include #include #include #include #include "WIND98.H" #include "CONS98.H" /*-------------- マクロ定義 -----------------------------------*/ #define GRAPH_MODE textmode(BG8025) #define KANJI_MODE textmode(VL8025) #define C_CHG(c) ( (c)<0 ? -(c)*32|5 : (c)*32|1 ) #define T_COL(c) textattr(C_CHG(c)) /*-------------- ウィンドゥ構造体用グローバルポインタ ---------*/ WIN *win_top = NULL; /* 最上層ウィンドゥ */ WIN *win_crt = NULL; /* カレントウインドゥ */ int mn_blnk = 0; /* メニュー表示間隙 */ int w_crner = 0; /* ウィンドウの4隅形状の指定 */ int mn_mode = 0; /* 選択外文字入力の許可フラグ */ int org_cx,org_cy; /* add H4/12/14 初期カーソル位置 */ /*==============================================================*/ /* レベル1ウィンドウ関数 */ /*==============================================================*/ /*-------------- カーソル移動エリアの指定 ----------------------*/ void w_view( WIN *wh ) { if( wh == NULL ) /* オリジナル画面の場合 */ window(1,1,80,25); else{ /* ウィンドウの文字エリアのみ */ window( wh->l+1,wh->t+1,wh->r-1,wh->b-1); T_COL(wh->tc); /* 文字カラーを設定 */ } } /*-------------- 下端を1行広いエリアで指定 --------------------*/ void w_view2( WIN *wh ) /* ウィンドウの右下に文字を書くと */ { /* スクロールするので1行大きく指定 */ window( wh->l+1,wh->t+1,wh->r-1,wh->b); T_COL(wh->tc); } /*-------------- ウインドゥタイトルを書くサブルーチン ----------*/ void w_title0( WIN *wh ) { int i,n,wn,hn; n = strlen(wh->np); /* タイトルの長さ */ wn = wh->r - wh->l + 1; /* ウィンドウの横幅 */ hn = ( wn - n ) / 2; /* タイトルの左右の空白 */ GRAPH_MODE; CRS_OFF(); /* グラフ文字表示、カーソル消去 */ T_COL(wh->bc); /* ボーダー(枠)の色設定 */ gotoxy(wh->l+1,wh->t); /* カーソルを上ボーダーの左端へ */ if(n>wn-2){ /* タイトルが横幅より大きければ */ for(i=wh->l+1;ir;i++) /* タイトルは表示しない */ putch(0x95); } else{ for(i=1;il+hn,wh->t); /* タイトル表示位置に移動 */ T_COL(wh->nc); /* タイトル色の設定 */ cprintf("%s",wh->np); /* タイトルを書く */ GRAPH_MODE; CRS_OFF(); /* グラフ文字モード、カーソル消去 */ gotoxy(wh->l+hn+n,wh->t); T_COL(wh->bc); for(i=hn+n;itc); } /*------------- ウィンドゥを描く -------------------------------*/ void w_disp( WIN *wh, int cch, /* cch=0:4隅が角、cch=1:4隅が丸 */ int clch ) /* clch:タイル文字コード */ { int i,j; PUSH_CRS(); if(cch == 1) cch=0x9c; else cch= 0x98; GRAPH_MODE; T_COL(wh->bc); CRS_OFF(); if(wh->bc == 0 ) gotoxy(wh->l,wh->t+1); else{ gotoxy(wh->l,wh->t); putch(cch++); w_title0( wh ); putch(cch++); } for(j=wh->t+1;jb;j++){ if(wh->bc == 0) gotoxy(wh->l+1,j); else{ gotoxy(wh->l,j); putch(0x96); } T_COL(wh->tc); for(i=wh->l+1;ir;i++){ putch(clch); } if(wh->bc != 0){ T_COL(wh->bc); putch(0x96); } } if(wh->bc != 0){ gotoxy(wh->l,wh->b); putch(cch++); for(i=wh->l+1;ir;i++){ putch(0x95); } putch(cch); } KANJI_MODE; POP_CRS(); CRS_ON(); } /*==============================================================*/ /* レベル2ウィンドゥ関数用サブルーチン */ /*==============================================================*/ /*-------------- ウィンドゥ指定とカーソル復帰 ------------------*/ void w_locate( WIN *wh ) { w_view( wh ); if( wh != NULL ) gotoxy(wh->lx,wh->ly); else /* add H4/12/14 */ gotoxy(org_cx,org_cy); win_crt = wh; } /*-------------- 現在カーソル位置の退避 ------------------------*/ void w_crspos( WIN *wh ) { if( wh != NULL ){ wh->lx = wherex(); wh->ly = wherey(); } } /*==============================================================*/ /* レベル2ウィンドゥ関数 */ /*==============================================================*/ /*-------------- ウィンドウの内部か調べる -----------*/ int w_chek( WIN *wh , int x, int y ) { if((wh->l <= x)&&(x < wh->r - 1)){ if((wh->t <= y)&&(y < wh->b - 1)) return(1); else if( (wh->t -1 == y )&&(wh->bc != 0) ) return(2); else if( (y == wh->b -1 )&&(wh->bc != 0) ) return(3); } return(0); } /*-------------- ウィンドウが上位にあるか調べる -------*/ WIN *w_cktop( WIN *wt, /* サーチ開始ウィンドウのポインタ */ WIN *wh ) /* 対象ウィンドウのポインタ */ { while((wt != NULL)&&( wt != wh )){ if( !((wt->r > wh->l)||(wh->r < wt->l)) ){ if( !((wt->b < wh->t)||(wh->b < wt->t)) ) return( wt ); /* 最初に見つかった上位のポインタ */ } wt = wt->wlast; /* 次のウィンドウを調べる */ } return(NULL); } /*-------------- ウインドゥ内の消去 ----------------------------*/ void w_cls( WIN *wh ) { int i,x,y; w_crspos( win_crt ); w_view2( wh ); x = wh->r - wh->l -1; y = wh->b - wh->t -1; T_COL(wh->tc); for(i=0;itc = col; T_COL( col ); } /*------------- カレントウィンドウの指定 -----------------------*/ void w_window( WIN *wh ) { w_crspos( win_crt ); w_locate( wh ); if( wh != NULL ) T_COL( wh->tc ); } /*------------- ウィンドゥを作成する ---------------------------*/ WIN *w_open( int l,int t,int r,int b, /* 4隅の座標値 */ char *name, /* ウィンドウ名 */ int tc,int bc,int nc, /* テキスト、枠、名前の色 */ int mode ) /* 0:隠れ部をセーブしない、1:する */ { WIN *wh; char *cp; if(l<1 || t<1 || r>80 || b>24 ) return(NULL); if((wh = (WIN *)malloc(sizeof(WIN)))==NULL) return(NULL); if(mode==0){ wh->bf = NULL; } else{ if((cp = (char *)malloc((b-t+2)*(r-l+1)*4))==NULL) return(NULL); gettext(l,t,r,b,cp); wh->bf = cp; } if(win_top!=NULL) w_crspos( win_top ); else{ /* add H4/12/14 */ org_cx = wherex(); org_cy = wherey(); } wh->wlast = win_top; win_top = wh; wh->l = l; wh->t = t; wh->r = r; wh->b = b; wh->np = name; wh->tc = tc; wh->bc = bc; wh->nc = nc; w_disp(wh,w_crner,0x20); w_view( wh ); return(wh); } /*-------------- ウィンドウを閉じる ----------------------------*/ void w_close( WIN *wh ) { /* 必ず開いた順と逆順で閉じること */ if( wh == win_top ){ if(wh->bf != NULL){ puttext(wh->l,wh->t,wh->r,wh->b,wh->bf); free(wh->bf); } win_top = wh->wlast; if(win_top == NULL){ normvideo(); w_locate(NULL); /* add H4/12/14 */ } else{ w_locate(win_top); T_COL(win_top->tc); } free(wh); } } /*-------------- ウィンドゥオープンデータを構造体で渡す --------*/ WIN *w_open_st( WIN* wh , /* 渡すデータがあるウィンドゥ構造体 */ int mode ) /* 隠れ部の処理モード */ { return( w_open( wh->l, wh->t, wh->r, wh->b, wh->np, wh->tc, wh->bc, wh->nc, mode ) ); } /*-------------- ウィンドウの隅形状の指定 ----------------------*/ void w_corner(int c) { /* add H3/12/9 */ w_crner = c; /* c=0:角, c=1:丸 */ } /* add H04/06/10 */ /*-------------- ウィンドウ下部にメッセージの表示 --------------*/ int w_msgout( WIN *wh, char *msg, int col ) { int n,wn,hn; n = strlen(msg); wn = wh->r - wh->l - 1; if(n>wn) return(-1); hn = wn - n + 1; KANJI_MODE; CRS_OFF(); gotoxy(wh->l+hn, wh->b); T_COL(col); cprintf("%*s",n,msg); w_view(wh); w_locate(wh); } /*-------------- ウィンドウ下部メッセージの消去 ----------------*/ void w_msgcls( WIN *wh ) { int i; GRAPH_MODE; CRS_OFF(); gotoxy(wh->l+1, wh->b); T_COL(wh->bc); for(i=wh->l+1;ir;i++) putch(0x95); KANJI_MODE; CRS_OFF(); w_view(wh); w_locate(wh); } /*==============================================================*/ /* メニュー関数 */ /*==============================================================*/ /*-------------- メニューの表示サブルーチン --------------------*/ void menu_prt(int x, int y, MENU *mn, int i, int max) { /* chang H3/3/21 */ gotoxy(x*mn->w+1+x*mn_blnk,y+1); /* add blnk H3/6/21 */ if(iw,mn->str[i]); }else{ cprintf("%*s",mn->w," "); } } /*-------------- ブランク文字数の設定 --------------------------*/ void menu_blnk(int b) { /* add H3/6/21 */ mn_blnk = b; /* b:メニューの列間の文字数 */ } /*-------------- メニューモードの指定 --------------------------*/ void menu_mode(int m) { /* add H3/12/9 */ mn_mode = m; /* m=0:選択外文字入力の禁止 */ } /* m=1:選択外文字入力の許可 */ /*-------------- メニューを書く --------------------------------*/ void wm_disp( WIN *wh, MENU *mn, int max, int st ) { /* st:表示文字配列オフセット */ int x,y,i; w_view2( wh ); for(y=0,i=st;yr;y++){ for(x=0;xc;x++,i++){ menu_prt(x,y,mn,i,max); } } } /*-------------- メニューの選択(マウス対応版)------------------------*/ /* 選択した番号を返します。決定は CR で行う */ /* ESC は中止で 0 を返す */ int wm_sel( WIN *wh, /* メニューを表示するウィンドゥ構造体 */ MENU *mn, /* 表示するメニューの構造体 */ int max ) /*スペース表示メニューの最大個数 */ { int ky, ch, i, j; char *cp; int loop=1, x=0, y=0, st=0; int r,l,mx,my,cx,cy,lx,ly,msm; int lbf, rbf,xi,yi,wck; CRS_OFF(); msm = ms_init(); /* add H4/12/08 */ if((i=mn->last)!=0){ x = (i-mn->st)%mn->c; y = (i-mn->st)/mn->c; st = mn->st; } if( win_crt != NULL) { w_crspos( win_crt ); } wm_disp( wh, mn, max, st ); win_crt = wh; T_COL(mn->hc); menu_prt(x,y,mn,i,max); if(msm){ while(ms_get(&r,&l,&mx,&my)); lx = mx/8; ly = my/16; wck = w_chek(wh,lx,ly); atr_inv(lx,ly); } do{ if(msm){ /* add H4/12/08 */ ms_get(&r,&l,&mx,&my); cx = mx/8; cy = my/16; if((cx!=lx)||(cy!=ly)){ atr_inv(lx,ly); lx = cx; ly = cy; wck = w_chek(wh,lx,ly); if( wck == 1 ){ yi = ly - wh->t; xi = (lx - wh->l + mn_blnk)/(mn->w + mn_blnk); if((xic)&&((yi!=y)||(xi!=x))){ T_COL(wh->tc); menu_prt(x,y,mn,i,max); y = yi; x=xi; i = x + mn->c * y + st; T_COL(mn->hc); menu_prt(x,y,mn,i,max); } } atr_inv(lx,ly); } }else{ /* add H4/12/08 */ l = 0; r= 0; } ky = cinkey(); if(l==0) lbf=0; /* add H4/12/08 */ else{ /* left bottun on */ if(lbf){ /* change 92/12/4 */ /* if((lbf==0)&&(wck)){ */ switch(wck){ case 0: ky = C_CR; break; /* add 92/12/4 */ case 1: ky = C_CR; break; case 2: ky = C_UP; break; case 3: ky = C_DOWN; break; } } lbf = 1; } if(r==0) rbf=0; else{ /* right bottun on */ /* if((rbf==0)&&(wck==1))*/ if(rbf==0){ /* change 92/12/4 */ ky = C_ESC + 27; while( ms_get(&r,&l,&mx,&my)) ; /* add 92/12/4 */ rbf = 0; /* change 92/12/4 */ } /* rbf = 1; */ } if(ky != 0){ if(msm){ atr_inv(lx,ly); } switch( ky & 0xff00 ){ case C_ESC: T_COL(wh->tc); menu_prt(x,y,mn,i,max); loop = 0; ch = 0; break; case C_CR: if(isc); menu_prt(x,y,mn,i,max); mn->last = i; mn->st = st; ch = i + 1; loop = 0; } break; case C_RIGHT: if(xc-1 && i+1tc); menu_prt(x,y,mn,i,max); x++; i = x + mn->c * y + st; T_COL(mn->hc); menu_prt(x,y,mn,i,max); } break; case C_LEFT: if(x>0){ T_COL(wh->tc); menu_prt(x,y,mn,i,max); x--; i = x + mn->c * y + st; T_COL(mn->hc); menu_prt(x,y,mn,i,max); } break; case C_DOWN: if(yr-1 && i+mn->ctc); menu_prt(x,y,mn,i,max); y++; i = x + mn->c * y + st; T_COL(mn->hc); menu_prt(x,y,mn,i,max); }else if(y==mn->r-1 && (i/mn->c+1)*mn->cc; wm_disp(wh,mn,max,st); i = x + mn->c * y + st; T_COL(mn->hc); menu_prt(x,y,mn,i,max); } break; case C_UP: if(y>0){ T_COL(wh->tc); menu_prt(x,y,mn,i,max); y--; i = x + mn->c * y + st; T_COL(mn->hc); menu_prt(x,y,mn,i,max); }else if(y==0 && st>0){ st = st - mn->c; wm_disp(wh,mn,max,st); i = x + mn->c * y + st; T_COL(mn->hc); menu_prt(x,y,mn,i,max); } break; default: /* H2/12/3,H3/3/21 add */ ch = toupper(ky & 0xff); j=0; for(j=0;jstr[j]); if(*cp==ch){ T_COL(wh->tc); menu_prt(x,y,mn,i,max); if(jc) * mn->c; wm_disp(wh,mn,max,st); }else if(j >= st + mn->c*mn->r){ st = (j/mn->c - mn->r + 1) * mn->c; wm_disp(wh,mn,max,st); } x = (j-st)%mn->c; y =(j-st)/mn->c; i = j; T_COL(mn->sc); menu_prt(x,y,mn,i,max); mn->last = i; mn->st = st; ch = i + 1; loop = 0; break; } } if((loop == 1)&&(mn_mode == 1)){ /* add H3/12/09 */ ch = ky ; loop = 0; } break; } if(msm){ atr_inv(lx,ly); } } }while(loop); if(msm){ atr_inv(lx,ly); } CRS_ON(); return( ch ); } /*---------------- メニュー用のウィンドウを開ける -----*/ WIN *wm_open( MENU *mn, char **mnlst, int l, int t, char *name, int tc,int bc, int nc, int mode) { int r,b; mn->str = mnlst; r = l + mn->c * mn->w + (mn->c - 1) * mn_blnk + 1; b = t + mn->r + 1; return( w_open(l,t,r,b,name,tc,bc,nc,mode) ); } /*-------------- メニューの指定 ----------------------------------*/ int wm_set( WIN *wh, /* メニューを表示するウィンドゥ構造体 */ MENU *mn, /* 表示するメニューの構造体 */ int max, /* スペース表示メニューの最大個数 */ int kno ) /* 選択指定番号 */ { int i,j; int x, y, st; if((kno<1)||(kno>max)) return(0); CRS_OFF(); if( win_crt != NULL) { w_crspos( win_crt ); } if((i=mn->last)!=0){ st = mn->st; x = (i-st)%mn->c; y = (i-st)/mn->c; }else{ st = 0; } j = kno - 1; wm_disp( wh, mn, max, st ); win_crt = wh; if(jc) * mn->c; wm_disp(wh,mn,max,st); }else if(j >= st + mn->c*mn->r){ st = (j/mn->c - mn->r + 1) * mn->c; wm_disp(wh,mn,max,st); } x = (j-st)%mn->c; y = (j-st)/mn->c; T_COL(mn->sc); menu_prt(x,y,mn,j,max); mn->last = j; mn->st = st; return(kno); } /*-------- ウインドウによるYes/No確認 -----*/ int w_yesno(int x, int y, int xc, int bc,int ys) { MENU mn = {2,1,5,-2,-3}; char *yn[]= {"Yes ","No "}; int sel; WIN *wp; menu_blnk(1); wp = wm_open(&mn,yn,x,y,"",xc,bc,bc,0); if(ys) mn.last = 1; sel = wm_sel( wp, &mn, 2 ); w_close(wp); return(sel); } /*-------- ウインドウによる確認 --------*/ int w_ok(int x, int y, int xc, int bc) { MENU mn = {1,1,4,-2,-3}; char *yn[]= {"Ok "}; int sel,r,l,xx,yy; WIN *wp; wp = wm_open(&mn,yn,x,y,"",xc,bc,bc,0); sel = wm_sel( wp, &mn, 1 ); w_close(wp); return(sel); } /*-------- マウスを選択項目の位置に移動する -----(add 92/12/5)---*/ w_msset(WIN *wp, MENU mnu) { int x,y; x = 8 * (wp->l + (mnu.w + mn_blnk)*(mnu.last % mnu.c)); y = 16 * (wp->t + (mnu.last / 2)); ms_set(x,y); } /*============ e n d ==========================(WIND98.C)==================*/