漢字のメッセージを出すためのデータが、ヘッダーファイル"kanji.h"(リスト7−1)に書か れています。それぞれのメッセージは、マクロ定義されています。奇妙なのは、本当のメッセージ の前に、訳の分からない余分なものがついていることでしょう。(\dは文字定数の10進数表記を示 しています。これはふつうのCにはない仕様ですが、そのままにしておきます。)
リスト7−1 ヘッダファイル(漢字メッセージの定義) |
1 /****************************************************************************** 2 * 3 * Definition of Kanji message for Command Make program 4 * 5 */ 6 7 #ifndef _KANJI_H 8 #define _KANJI_H 9 10 #define M140 "\d074\d018■MOD" 11 #define M150 "\d043\d018■中止" 12 #define M160 "\d050\d018■実行" 13 #define M170 "\d057\d018■印字" 14 #define M180 "\d064\d018■次へ" 15 #define M190 "\d043\d018■中断" 16 #define M192 "\d071\d018■設定" 17 #define M194 "\d071\d018■全削除" 18 19 #define M200 "\d040\d001子局名選択" 20 #define M210 "\d040\d001制御項目選択" 21 #define M220 "\d040\d001受信中" 22 #define M222 "\d040\d001受信できませんでした。" 23 #define M224 "\d040\d001ステーション・エラーが生じました。" 24 #define M226 "\d040\d001ライン・エラーが生じました。" 25 26 #define M692 "\d045\d003運用開始" 27 #define M694 "\d045\d004運用終了" 28 29 #define M720 "運用時間" 30 #define M730 "運用時間設定" 31 32 #define M900 "\d065\d003●0" 33 #define M910 "\d065\d004●1" 34 #define M920 "\d065\d005●2" 35 #define M930 "\d065\d006●3" 36 #define M940 "\d065\d007●4" 37 #define M950 "\d065\d008●5" 38 #define M960 "\d065\d009●6" 39 #define M970 "\d065\d010●7" 40 #define M980 "\d065\d011●8" 41 #define M990 "\d065\d012●9" 42 43 #endif _KANJI_H |
リスト7−2 漢字メッセージの表示関数 |
1 /****************************************************************************** 2 * 3 * Command Make program 4 * 5 */ 6 7 #include "mydefs.h" 8 9 /****************************************************************************** 10 * 11 * Display of Message for light pen 12 * 13 */ 14 DispMsg(msgcnt, msgptr) 15 16 int msgcnt; 17 char **msgptr; 18 19 { 20 int x,y; 21 char *ptr; 22 23 for( ; msgcnt != ZERO; msgcnt--){ 24 ptr = *msgptr; 25 x = *ptr++; 26 x -= W3XOFFSET; 27 y = *ptr++; 28 y -= W3YOFFSET; 29 locate(STDERR, x, y); 30 fprintf(wpath, "%s", ptr); 31 fflush(wpath); 32 33 msgptr++; 34 } 35 } 36 37 /****************************************************************************** 38 * 39 * Standerd data Display (jyushin chuu no hyouji, chuushi, inji, tsugie) 40 * 41 */ 42 StandDsp(timeup) 43 44 int timeup; /* time until time up */ 45 46 { 47 char *msgptr[3]; /* message pointer arry */ 48 int msgcnt; /* message count */ 49 int msgnum; /* message number */ 50 51 int d3_cnt; /* d3_ data count */ 52 int d3_offset; /* d3_ structure offset */ 53 int dspline; /* display line */ 54 int dspend; /* display end flag */ 55 int getd3data; /* get d3 data count */ 56 int timecnt; /* time counter for operater */ 57 int value; /* return value */ 58 59 60 cls2(); 61 msgcnt = 1; 62 msgptr[0] = M220; 63 DispMsg(msgcnt, msgptr); 64 65 /* receive of ressponce data */ 66 value = Receive(timeup); 67 if(value == TIMEUP){ 68 cls2(); 69 msgcnt = 1; 70 msgptr[0] = M222; 71 DispMsg(msgcnt, msgptr); 72 tsleep(3 * TPS); 73 return(RETURN); 74 }else{ 75 if(value == STD_ERROR){ 76 switch(TdRpt.tr_lineno.str2[1]){ 77 case CE_STATERR: 78 cls2(); 79 msgcnt = 1; 80 msgptr[0] = M224; 81 DispMsg(msgcnt, msgptr); 82 break; 83 case CE_LINEERR: 84 cls2(); 85 msgcnt = 1; 86 msgptr[0] = M226; 87 DispMsg(msgcnt, msgptr); 88 break; 89 default: 90 break; 91 } 92 tsleep(3 * TPS); 93 return(RETURN); 94 }else{ 95 /* standerd data */ 96 } 97 } 98 99 /* hyouji */ 100 d3_cnt = d3expand(d3_count); 101 d3_offset = ZERO; 102 103 dspend = TRUE; 104 do{ 105 cls2(); 106 locate(STDERR, DSPLINEX - W3XOFFSET, DSPLINEY - W3YOFFSET); 107 if(d3_cnt <= DSPLINECNT){ 108 dspline = d3_cnt; 109 getd3data = d3disp(wpath, d3_offset, dspline, OFF); 110 dspend = FALSE; 111 }else{ 112 dspline = d3_cnt; 113 getd3data = d3disp(wpath, d3_offset, dspline, OFF); 114 } 115 116 msgcnt = 3; 117 msgptr[0] = M150; 118 msgptr[1] = M170; 119 msgptr[2] = M180; 120 DispMsg(msgcnt, msgptr); 121 122 msgnum = ReadLPen(msgcnt, msgptr, 60 * 1); 123 if(msgnum == TIMEUP){ 124 goto Jump2; 125 } 126 switch(msgnum){ 127 case 1: /* chuushi */ 128 return(RETURN); 129 case 2: /* inji */ 130 if(PaperChk() == ON){ 131 (PaperChk() == ON)? putc(CR, ppath): NULL; 132 d3disp(ppath, d3_offset, dspline, ON); 133 (PaperChk() == ON)? putc(CR, ppath): NULL; 134 } 135 case 3: /* tsugie */ 136 Jump2: 137 d3_offset += getd3data; 138 d3_cnt -= getd3data; 139 if(d3_cnt == ZERO){ 140 dspend = FALSE; 141 } 142 break; 143 default: 144 break; 145 } 146 147 }while(dspend); 148 149 return(CONTINUE); 150 } |
この変なメッセージを処理するための関数が、リスト7−2の最初の関数DispMsgです。この関 数は、メッセージの個数と配列を与えると、複数のメッセージを表示します。msgptrはchar**型で、 メッセージ(文字列)へのポインタの配列です。 msgptrから、forループの度に、メッセージへの ポインタをptrに入れています。ここまでは、普通です。
次に、ポインタの指す内容からW3XOFFSETを引いたものをx、次の内容からW3YOFFSETを引いたも のをyにしています。そして、その次にlocate関数があるので、このx,yがカーソル位置だったこと が分かります。
つまり、メッセージの最初の2バイトは、表示位置でした。表示位置は0もあり、そのままでは 文字列が終わってしまうと思い込み、適当な値 (W3XOFFSET,W3YOFFSET)を加えていたのでした。こ れで、変なメッセージの書き方の謎は解けました。
ここで読者に紹介しているのは、元の漢字メッセージファイル中から、今回ご覧いただくファイ ルに直接関係する辺りだけです。実際のファイルには、このような#defineが200行以上並んでいま す。それも、マクロ名がみんな、M140という調子で、たぶんメッセージを意味するMの後に、メッ セージ番号をつけただけなのでしょう。このような名前の付け方もいやなものです。M720とM730の 2 つだけは、先頭に位置データがありません。実際にこのデータを使用する関数(リストは省略) を調べてみると、これらのデータにも先頭に位置データが必要なことが分かりました。先頭に変な 方法で位置データを入れたりするため、忘れてしまったのでしょう。「運」の字の文字コードから 位置を決めたら、いったいどこに表示されるのでしょうね。
このメッセージ表示関数の呼出しは、リスト7−2の関数StandDsp中に何カ所もあります。1行 だけの表示は、61〜63行にあり、
msgcnt = 1; msgptr[0] = M220; DispMsg(msgcnt,msgptr);となっています。複数行にわたって表示する例は、 116〜120行にあり、
msgcnt = 3; msgptr[0] = M150; msgptr[1] = M170; msgptr[2] = M180; DispMsg(msgcnt,msgptr);となっています。多くのメッセージ表示が1行のみであることから、DispMsgの仕様を1つのメッ セージだけを表示することにすると、以上の部分は、
DispMsg(M220);と
DispMsg(M150); DispMsg(M170); DispMsg(M180);だけで済みます。こうすると、1行の場合は非常に単純になりますね。DispMsgをデータ1個のみ、 最後にsをつけたDispMsgsをデータn個の表示用にすると良いでしょう。もちろん、DispMsgsの実 現にはDispMsgを使います。
以上のメッセージ表示関数を利用した実際の処理の一部がリスト7−3です。Job2という関数で、 「運用時間の登録抹消」という処理をしているようです。
ところで91,101行に、
ptr += 2;があります。突然こんな式が出てくると、「何だろう?」と悩みの種になります。直前で、ptrに はメッセージデータの先頭アドレスを代入しているので、+=2 で位置データの2バイト分をスキッ プしていることが分かります。でも、メッセージ部分を指定するのに、わざわざ2加えるなんて細 工はしたくないものです。
リスト7−3 Job Process |
1 /****************************************************************************** 2 * 3 * *** CmdMake_DTS *** 4 * 5 * Job process of Command Make program 6 * 7 */ 8 9 #include "mydefs.h" 10 11 #define UNYOU0PATH "/D0/DATA/Unyou_0" 12 #define UNYOU1PATH "/D0/DATA/Unyou_1" 13 14 /****************************************************************************** 15 * 16 * Job 2 (unnyou-jikan no touroku matsusyou) 17 * 18 */ 19 Job2() 20 { 21 char *msgptr[12]; /* message pointer arry */ 22 int msgcnt; /* message counter */ 23 int msgnum; /* message number */ 24 int msgnum2; 25 int fpath; /* file path */ 26 int offset; /* offset for unyou table */ 27 int x, y; 28 29 char *posptr[4]; /* display postion pointer arry */ 30 int lcount; /* loop counter */ 31 char date[9]; /* arry of yy,mm,dd,hh,mm */ 32 char **pptr; /* postion pointer */ 33 char *ptr; /* xy axis value pointer */ 34 char outbuf[40]; /* buffer for output */ 35 36 37 /* unnyou jikoku no hyouji */ 38 cls(); 39 msgcnt = 2; 40 msgptr[0] = M692; 41 msgptr[1] = M694; 42 DispMsg(msgcnt, msgptr); 43 44 /* UNYOU no hyouji */ 45 fpath = open((jobid==0)? UNYOU0PATH: UNYOU1PATH, S_IREAD); 46 if(fpath == ERROR) xexit(413); 47 lseek(fpath, 0L, 0); 48 if(read(fpath, &unyoutbl[0].t_year, sizeof(unyoutbl)) == ERROR) xexit(414); 49 close(fpath); 50 51 pptr = msgptr; 52 offset = 0; 53 while(offset != sizeof(unyoutbl) / sizeof(struct sgtbuf)){ 54 ptr = *pptr++; 55 x = *ptr++; 56 x += KANJILEN * 4; 57 x -= W3XOFFSET; 58 y = *ptr; 59 y -= W3YOFFSET; 60 if(unyoutbl[offset].t_year == ON){ 61 locate(STDERR, x, y); 62 fprintf(wpath, " %02d:%02d", 63 unyoutbl[offset].t_hour, unyoutbl[offset].t_minute); 64 fflush(wpath); 65 } 66 else{ 67 locate(STDERR, x, y); 68 fprintf(wpath, " 00:00"); 69 fflush(wpath); 70 } 71 offset++; 72 } 73 74 msgcnt = 3; 75 msgptr[0] = M150; 76 msgptr[1] = M170; 77 msgptr[2] = M180; 78 DispMsg(msgcnt, msgptr); 79 msgnum = ReadLPen(msgcnt, msgptr, 60 * 1); 80 if(msgnum == TIMEUP){ 81 return; 82 } 83 switch(msgnum){ 84 case 1: /* chuushi */ 85 return; 86 case 2: /* inji */ 87 if(PaperChk() == ON){ 88 (PaperChk() == ON)? putc(CR, ppath): NULL; 89 if(PaperChk() == ON){ 90 ptr = M692; 91 ptr += 2; 92 if(unyoutbl[0].t_year == ON){ 93 sprintf(outbuf," %s %02d:%02d", 94 ptr, unyoutbl[0].t_hour, unyoutbl[0].t_minute); 95 fprintf(ppath, "%s\n", outbuf); 96 } 97 else{ 98 fprintf(ppath, " %s 00:00\n", ptr); 99 } 100 ptr = M694; 101 ptr += 2; 102 if(unyoutbl[1].t_year == ON){ 103 sprintf(outbuf," %s %02d:%02d", 104 ptr, unyoutbl[1].t_hour, unyoutbl[1].t_minute); 105 fprintf(ppath, "%s\n", outbuf); 106 fflush(ppath); 107 } 108 else{ 109 fprintf(ppath, " %s 00:00\n", ptr); 110 fflush(ppath); 111 } 112 } 113 (PaperChk() == ON)? putc(CR, ppath): NULL; 114 } 115 case 3: /* tsugie */ 116 break; 117 default: 118 break; 119 } 120 121 Retry: 122 /* unnyou kaishi(hh,mm) to syuuriyou(hh,mm) no nyuuriyoku */ 123 cls(); 124 msgcnt = 2; 125 msgptr[0] = M720; 126 msgptr[1] = M730; 127 DispMsg(msgcnt, msgptr); 128 msgcnt = sizeof(msgptr) / sizeof(char *); 129 msgptr[0] = M900; 130 msgptr[1] = M910; 131 msgptr[2] = M920; 132 msgptr[3] = M930; 133 msgptr[4] = M940; 134 msgptr[5] = M950; 135 msgptr[6] = M960; 136 msgptr[7] = M970; 137 msgptr[8] = M980; 138 msgptr[9] = M990; 139 msgptr[10] = M150; /* chuushi */ 140 msgptr[11] = M192; /* retry */ 141 DispMsg(msgcnt, msgptr); 142 143 posptr[0] = M720; 144 posptr[1] = M730; 145 146 lcount = 2; 147 msgnum2 = Select3(lcount, msgcnt, msgptr, posptr, date); 148 if(msgnum2 == msgcnt - 1){ 149 return; 150 }else{ 151 if(msgnum2 == msgcnt){ 152 goto Retry; 153 } 154 } 155 156 /* HH 10**1 */ 157 outbuf[0] = date[2]; 158 date[2] = NULL; 159 unyoutbl[0].t_hour = atoi(&date[0]); 160 date[2] = outbuf[0]; 161 /* HH 10**0 */ 162 outbuf[0] = date[4]; 163 date[4] = NULL; 164 unyoutbl[0].t_minute = atoi(&date[2]); 165 date[4] = outbuf[0]; 166 /* MM 10**1 */ 167 outbuf[0] = date[6]; 168 date[6] = NULL; 169 unyoutbl[1].t_hour = atoi(&date[4]); 170 date[6] = outbuf[0]; 171 /* MM 10**0 */ 172 date[8] = NULL; 173 unyoutbl[1].t_minute = atoi(&date[6]); 174 175 unyoutbl[0].t_year = ON; 176 unyoutbl[1].t_year = ON; 177 Next2: 178 /* chuushi ka jitsukou */ 179 cls(); 180 msgnum = Select2(); 181 if(msgnum == STOP2) return; 182 UnyouIssue(FALSE); 183 } |