第 2 章 会話型入出力
2.3 日本語文字コード
Advance CAD 標準の日本語文字コードは EUC です。プログラム中の文字列はメッセージやエラーメッ セージをはじめ、すべて日本語 EUC、マルチバイト文字列です。また半角カナは使用できません。
Windowsの場合、日本語文字コードは MS 漢字コード (シフトJISとも言う) です。
2.4 例
この場合ソースコードに直接 MS 漢字コードの文字定数を記述してはいけません。またディスクファイ ルから日本語文字列を読み込んだ場合は、MS 漢字コードを日本語EUCに変換しなければなりません。
ファイルに出力する場合は、逆の変換をしなければなりません。
日本語文字コードの変換のため、2つの関数を用意しています。
sjis2euc : MS 漢字コードから日本語 EUC への変換 euc2sjis : 日本語 EUC から MS 漢字コードへの変換
ソースコードに MS 漢字コードを直接記述する場合はつぎのようにします。
char text[80];
sjis2euc(" 日本語の文字列 ", text, sizeof(text));
Mesagdisp(MZONECOLOR1, 1, 1, 0, 10*strlen(text), text);
テキストファイルを1行読み込み表示したい場合は、つぎのようにします。
FILE *fp
char cbuf[80], text[80];
if ((fp=fopen("myfile.txt", "r")) == (FILE *)NULL) return;
if (fgets(cbuf, sizeof(cbuf), fp) == (char *)NULL) { fclose(fp);
return;
}
fclose(fp);
sjis2euc(cbuf, text, sizeof(text));
Mesagdisp(MZONECOLOR1, 1, 1, 0, 10*strlen(text), text);
このように Advance CAD のシステム関数、広域変数に設定する文字列は、すべて日本語 EUC でなけれ ばなりません。誤って日本語 EUC 以外の日本語文字コードが混入すると、モデルファイル、シンボル ファイルなどの重要なデータファイル中の文字列は信用出来ず、正しい結果が得られませんので注意し てください。
メニュー、メッセージ、エラーメッセージのソースファイルは MS 漢字コードでかまいません。
2.4 例
2.4.1 座標値、数値および文字列トークンの取り扱い
/*
* 入力された座標値、数値および文字列をメッセージ領域に表示する。
* <CE> でこのコマンドを終了する。
*/
#include "acaddef.h"
#include "acadprm.h"
#include "acadusr.h"
#include "acadupi.h"
#define CMDLVL 3 /* コマンドレベル3の割り込みコマンド */
void ucmd01(TOKEN *token) { switch (token->typ) {
case TknCMD: /* コマンドトークン */
break;
第2章 会話型入出力
case TknCOD: /* 座標トークン */
case TknDIG: /* デジタイズ座標トークン */
/*
* 入力された座標値をメッセージ領域に表示する。
* メッセージ番号 9000001 : " 座標値 X"
* メッセージ番号 9000002 : " 座標値 Y"
*/
Mesageras(MSGZONE, 0, 0);
Mesagdisp(MZONECOLOR1, 1, 1, 9000001, 3, &token->pnt.x);
Mesagdisp(MZONECOLOR1, 2, 1, 9000002, 3, &token->pnt.y);
break;
case TknSCL: /* 数値トークン */
/*
* 入力された数値をメッセージ領域に表示する。
* メッセージ番号 9000003 : " 数値 "
*/
Mesageras(MSGZONE, 0, 0);
Mesagdisp(MZONECOLOR1, 1, 1, 9000003, 3, &token->scl);
break;
case TknTXT: /* 文字列トークン */
/*
* 入力された文字列をメッセージ領域に表示する。
* メッセージ番号 9000004 : " 文字列 "
*/
Mesageras(MSGZONE, 0, 0);
Mesagdisp(MZONECOLOR1, 1, 1,9000004, strlen(token->txt) * 10, token->txt);
break;
case TknEOC: /* CE トークン */
/*
* Advance CAD では CE トークンの場合は概ね以下のように処理している。
* 基本コマンドの場合は今までの操作で設定された条件に基づき処理を行う。
* その後このコマンド処理関数を初期状態に戻して次のトークンの入力を待つ。
* 割り込みコマンドの場合はコマンド処理を終了させる。
* この例ではコマンドレベル3の割り込みコマンドであるので cmdidcla 関数 * を呼出してこのコマンドを終了する。
* これ以後に入力されたトークンは現在動作中のより下位の割り込みコマンド * または基本コマンドに渡されるようになる。
*/
cmdidcla(CMDLVL);
return;
case TknEXIT: /* コマンド終了トークン */
return;
default: /* その他のトークン */
Errorcode(9000001); /* 無効な入力です */
break;
}
/* 入力促進メッセージ */
Opmsgcode(CMDLVL, 9000005); /* 座標値、数値、文字列を入力/終了は <CE> */
}
2.4.2 修飾子トークンの取り扱い
/*
2.4 例
*/
#include "acaddef.h"
#include "acadprm.h"
#include "acadusr.h"
#include "acadupi.h"
#define CMDLVL 1 /* 基本コマンド */
void ucmd01(TOKEN *token) { switch (token->typ) {
case TknCMD: /* コマンドトークン */
break;
case TknMDF: /* 修飾子トークン */
if (token->cid[0] == 34 &&
token->cid[1] == 1 &&
token->cid[2] == CSWTSIZE) { /* 修飾子 TSIZE */
/* EMPTY */
} else if (token->cid[0] == 34 &&
token->cid[1] == 1 &&
token->cid[2] == CSWANG) { /* 修飾子 ANG */
/* EMPTY */
} else { /* その他の修飾子 */
Errorcode(9000001); /* 無効な修飾子です */
/*
* 無効な修飾子をクリアする。
*/
cmdmdfcla(CMDLVL);
} break;
case TknSCL: /* 数値トークン */
if (Idispatch(2) == 34 &&
Idriver(2) == 1 &&
Iformat(2) == CSWTSIZE) { /*
* 修飾子 TSIZE が指定されている。
* 入力された数値は文字高さ。文字高さをメッセージ領域に表示する。
* メッセージ番号 9000001 : " 文字高さ "
*/
Mesageras(MSGZONE, 1, 0);
Mesagdisp(MZONECOLOR1, 1, 1, 9000001, 3, &token->scl);
} else if (Idispatch(2) == 34 &&
Idriver(2) == 1 &&
Iformat(2) == CSWANG) { /*
* 修飾子 ANG が指定されている。
* 入力された数値は文字角度。文字角度をメッセージ領域に表示する。
* メッセージ番号 9000002 : " 文字角度 "
*/
Mesageras(MSGZONE, 2, 0);
Mesagdisp(MZONECOLOR1, 2, 1, 9000002, 3, &token->scl);
} else { /*
* 修飾子が指定されていない。
*/
Errorcode(9000002); /* 修飾子が指定されていない */
} break;
第2章 会話型入出力
case TknEOC: /* CE トークン */
break;
case TknEXIT: /* コマンド終了トークン */
return;
default: /* その他のトークン */
Errorcode(9000003); /* 無効な入力です */
break;
}
/* 入力促進メッセージ */
if (Idispatch(2) == 34 &&
Idriver(2) == 1 &&
Iformat(2) == CSWTSIZE) { /*
* 修飾子 TSIZE が指定されている。
*/
Opmsgcode(CMDLVL, 9000003); /* 文字高さを入力 */
} else if (Idispatch(2) == 34 &&
Idriver(2) == 1 &&
Iformat(2) == CSWANG) { /*
* 修飾子 ANG が指定されている。
*/
Opmsgcode(CMDLVL, 9000004); /* 文字角度を入力 */
} else { /*
* 修飾子が指定されていない。
*/
Opmsgcode(CMDLVL, 9000005); /* 修飾子「文字高さ」「文字角度」を選択 */
} }
2.4.3 テンポラリポイントの作成
/*
* 入力された二点間の距離をメッセージ領域に表示する。
*/
#include "acaddef.h"
#include "acadprm.h"
#include "acadusr.h"
#include "acadupi.h"
#define CMDLVL 1 /* 基本コマンド */
void ucmd01(TOKEN *token) {
static DPOINT pnts[2]; /* テンポラリポイントの保存領域 */
static int npnt = 0; /* 入力済みのテンポラリポイントの点数 */
switch (token->typ) {
case TknCMD: /* コマンドトークン */
/*
* 初期設定。
*/
npnt = 0;
break;
2.4 例
case TknCOD: /* 座標トークン */
case TknDIG: /* デジタイズ座標トークン */
case TknPNT: /* テンポラリポイントトークン */
/*
* テンポラリポイントを作成する。
* IdentPoint 関数の概要
* TknCOD が渡されたときの戻り値
* IDENT_SUCCESS : 渡された点をテンポラリポイントとする。
* TknDIG が渡されたときの戻り値
* IDENT_SUCCESS : テンポラリポイントが作成できた。
* IDENT_FAILURE : テンポラリポイントが作成できない。
* IDENT_CONTINUE : テンポラリポイントモードが交点や投影点などであり、
* 指定された1点ではテンポラリポイントが作成できな * いのでテンポラリポイント作成コマンド(割り込みコ * マンド)を起動した。
* テンポラリポイント作成コマンドが終了すると、
* その結果はトークンタイプ TknPNT で通知される。
* TknPNT が渡されたときの戻り値
* IDENT_SUCCESS : テンポラリポイントが作成できた。
* IDENT_FAILURE : テンポラリポイントが作成できない。
* 戻り値が IDENT_SUCCESS のときは2番目の引数にテンポラリポイント * が設定されている。
* 戻り値が IDENT_FAILURE のときは IdentPoint 関数内でエラーメッセージ * を表示している。
*/
if (IdentPoint(token, &pnts[npnt]) != IDENT_SUCCESS) { return;
} else { /*
* テンポラリポイントが作成できた。
*/
npnt++;
if (npnt == 2) { /*
* 二点間の距離を計算しメッセージ領域に表示する。
* メッセージ番号 9000001 : " 距離 "
*/
double dist = gmudst(&pnts[0], &pnts[1], 2, 1);
Mesageras(MSGZONE, 0, 0);
Mesagdisp(MZONECOLOR1, 1, 1, 9000001, 3, &dist);
npnt = 0;
} } break;
case TknBSP: /* バックスペーストークン */
if (npnt == 1) { /*
* 1点目のテンポラリポイントをキャンセルする。
*/
npnt = 0;
} else {
Errorcode(9000001); /* 取り消すテンポラリポイントがない */
} break;
case TknEOC: /* CE トークン */
/*
初期化する。
*/
npnt = 0;
第2章 会話型入出力
case TknEXIT: /* コマンド終了トークン */
return;
default: /* その他のトークン */
Errorcode(9000002); /* 無効な入力です */
break;
}
/* 入力促進メッセージ */
if (npnt == 0) {
Opmsgcode(CMDLVL, 9000002); /* 線分の1点目を入力 */
} else {
Opmsgcode(CMDLVL, 9000003); /* 線分の2点目を入力 */
} }
2.4.4 アイテムの選択
/*
* 選択された曲線アイテムの中点をメッセージ領域に表示する。
*/
#include "acaddef.h"
#include "acadprm.h"
#include "acadusr.h"
#include "acadupi.h"
#define CMDLVL 1
void ucmd01(TOKEN *token) { TOKEN tkn;
int idptr;
switch (token->typ) {
case TknCMD: /* コマンドトークン */
/*
* 初期設定。
* IdentItem 関数の初期化を行う。
* 入力処理関数は、トークンタイプ TknCMD でコマンド処理関数を呼出す前に * IdentItem 関数を初期化している。従って下の1行は不要。あってもよい。
*/
(void)IdentItem(CMDLVL, token, 0);
break;
case TknCOD: /* 座標トークン */
case TknDIG: /* デジタイズ座標トークン */
case TknIDP: /* アイテム識別子トークン */
case TknSPC: /* スペースキートークン */
/*
* アイテムを選択する。
* IdentItem 関数の概要
* TknCOD、TknDIG が渡されたときの処理 * 渡された点でアイテムをピックする。
* ピックできればそのアイテムのアイテム識別子を返す。
* ピックできなければ 0 を返す。
* TknIDP が渡されたときの処理 * 渡されたアイテム識別子を調べる。
2.4 例
* アイテム識別子が正しくなければ 0 を返す。
* TknSPC が渡されたときの処理 * 次候補アイテムの有無を調べる。
* 次候補アイテムがあればそのアイテムのアイテム識別子を返す。
* 次候補アイテムがなければ 0 を返す。
*/
if ((idptr = IdentItem(CMDLVL, token, 0)) == 0) { /* アイテムが選択できなかった */
Errorcode(9000001);
} else { /*
* アイテムが選択できた。
* 選択された曲線アイテムの中点座標をメッセージ領域に表示する。
* メッセージ番号 9000001 : " 中点 X"
* メッセージ番号 9000002 : " 中点 Y"
*/
DPOINT pmid;
Mesageras(MSGZONE, 0, 0);
if (gmpntpdv(1, idptr, 1, 0.0, (DPOINT *)NULL, &pmid) == 1) { Mesagdisp(MZONECOLOR1, 1, 1, 9000001, 3, &pmid.x);
Mesagdisp(MZONECOLOR1, 2, 1, 9000002, 3, &pmid.y);
} } break;
case TknEOC: /* CE トークン */
break;
case TknEXIT: /* コマンド終了トークン */
return;
default: /* その他のトークン */
Errorcode(9000002); /* 無効な入力です */
break;
}
/* 入力促進メッセージ */
tknclear(&tkn);
tkn.typ = -1;
if (IdentItem(CMDLVL, &tkn, 0)) { /* 次候補アイテムの有無を調べる */
/*
* 次候補アイテムあり。
*/
Opmsgcode(CMDLVL, 9000003); /* 中点を求める曲線アイテムを選択 または <SP>(次候補)を入力 */
} else { /*
* 次候補アイテムなし。
*/
Opmsgcode(CMDLVL, 9000004); /* 中点を求める曲線アイテムを選択 */
} }
2.4.5 複数アイテムの自動選択
/*
* 複数アイテムを選択し、現在選択されているアイテム数と最後に選択された * アイテムのアイテム識別子をメッセージ領域に表示する。
* <CE> で選択状態を初期化する。
第2章 会話型入出力
#include "acaddef.h"
#include "acadprm.h"
#include "acadusr.h"
#include "acadupi.h"
#define CMDLVL 1
void ucmd01(TOKEN *token) { TOKEN tkn;
switch (token->typ) {
case TknCMD: /* コマンドトークン */
/*
* 初期設定。
* IdentItems 関数の初期化を行う。
* 入力処理関数は、トークンタイプ TknCMD でコマンド処理関数を呼出す前に * IdentItems 関数を初期化している。従って下の1行は不要。あってもよい。
*/
(void)IdentItems(CMDLVL, token, 0);
break;
case TknCOD: /* 座標トークン */
case TknDIG: /* デジタイズ座標トークン */
case TknIDP: /* アイテム識別子トークン */
case TknSPC: /* スペースキートークン */
case TknBSP: /* バックスペーストークン */
case TknITM: /* アイテム選択トークン */
/*
* アイテムを選択する。
* IdentItems 関数の概要
* TknCOD、TknDIG が渡されたときの戻り値 * IDENT_SUCCESS : アイテムがピックできた。
* IDENT_CONTINUE : 渡された点でアイテムがピックできなかったので * 矩形または多角形領域でのアイテム選択とみなし、
* 複数アイテムの自動選択コマンド(割り込み * コマンド)を起動した。
* 複数アイテムの自動選択コマンドが終了すると、
* その結果はトークンタイプ TknITM で通知される。
* TknIDP が渡されたときの戻り値
* IDENT_SUCCESS : アイテムが選択できた。
* IDENT_FAILURE : アイテムが選択できなかった。(渡されたアイテム * 識別子が不正)
* TknSPC が渡されたときの戻り値
* IDENT_SUCCESS : 次候補アイテムあり。
* 以前のアイテムを排除し、次候補アイテムを選択する。
* IDENT_FAILURE : 次候補アイテムはない。
* TknBSP が渡されたときの戻り値
* IDENT_SUCCESS : 最後の操作を元に戻した。
* IDENT_FAILURE : 元に戻すべきアイテムが存在しない。
* TknITM が渡されたときの戻り値
* IDENT_SUCCESS : 複数アイテムの自動選択コマンドでアイテムが選択 * できた。
* IDENT_FAILURE : アイテムが選択できなかった。
* 戻り値が IDENT_SUCCESS のときは、選択されたアイテムはハイライト * アイテムリストに追加されている(または排除されている)。
* 戻り値が IDENT_FAILURE のときは IdentItems 関数内でエラーメッセージ * を表示している。
*/
if (IdentItems(CMDLVL, token, 0) != IDENT_SUCCESS) {