サブフォームライブラリ詳細設計書
（NCURSESを使用した画面設計ライブラリ） ｖ３．０
2009.8.17

Assistant form library details specifications (the screen design library which I used NCURSES for) v3 .0 

０はじめに
本ライブラリはMS-Access でおなじみのサブフォーム（テキストボックスとグリッドが混在した画面）をLinux の xterm と Kterm 及び TeraTerm等のターミナルソフト画面で操作するライブラリです。
本ライブラリを使用することで、PostgreSQLデータベースからの行列情報の表示及び、入出力操作を行うことが出来ます。操作出来るタイプの型として、現在のバージョンではテキスト型、通貨型、数値型、DATE型の４つのタイプの値を操作可能になっています。
なお、本マニュアルは読者が NCURSES ライブラリに精通していることを前提に記述しています。そのためサンプル中にある NCURSES 関数に関しての説明はしておりません。

0 Preamble 
This library is a library operating a familiar assistant form (the screen that text box and a grid coexisted) with terminal software screens such as xterm and Kterm of Linux and TeraTerm in MS-Access. 
I can perform indication of line information from a PostgreSQL database and input and output operation by using this library. As a model of the type that I can operate, I can come to operate a text type, a currency type, numerical value type, a value of four types of DATE type in a current version. 


１．機能説明
テキストボックスとグリッドには以下の条件で入力出来ます。

1. Function explanation 
I can input it into text box and a grid in the following conditions. 

名前	値	容量	
テキスト型	英数字と全角の文字列	１３８バイト(生成するECPGソースではVARCHAR型として扱います。)
NUMERIC型	長整数	−２１４７４８３６４７〜２１４７４８３６４７(生成するECPGソースではINTEGER型として扱います。)
CURRENCY型	長整数	−２，１４７，４８３，６４７〜２，１４７，４８３，６４７(生成するECPGソースではINTEGER型として扱います。)
DATE型	英数字の文字列	DATE型は基本的にテキスト型と同じ扱いになります。フォーマットは生成するECPGソースではTIMESTAMP()として扱われます。

A name     A value capacity text type alphanumeric character and character string of full size     138 bytes(I treat it as VARCHAR type in an ECPG source to generate.) 
NUMERIC type long integer - 2147483647-2147483647(I treat it as INTEGER type in an ECPG source to generate.) 
CURRENCY type long integer - 2,147,483,647-2,147,483,647(I treat it as INTEGER type in an ECPG source to generate.) 
I agree with a text type basically and treat character string DATE type of a DATE type alphanumeric character. A format is treated as TIMESTAMP() in an ECPG source to generate. 

１．１　機能範囲
サブフォーム内では以下の範囲で定義可能です。

1.1 　A function range 
I can define it in an assistant form in the following ranges.

名前	範囲	
ラベル	３８４個	
テキストボックス	３８４個	
グリッド	１グリッドのみ。３８４桁／５２行以内	
パネル	１枚に２行づつテキストボックスを配置。最大１８枚	
最大画面幅(MAXCOL)	１７８col
最大画面行(MAXLINE)		６８row

A name     384 range label text box     384 grids     Only as for one grid. By two lines arrange text box to one piece of 384 columns of less than /52 lines panels. 18 pieces at the maximum 

１．２　カーソル移動
セルカーソルは以下のキーで移動します。

1.2 cursor movement 
Selker Sor moves with the following keys. 

テキストボックス
↓と→：前に進むが最終テキストボックスで止まる。
↑と←：後ろに戻る
TAB　：前に進み最終テキストボックスで止る。

With text box ↓→： I advance before, but stop in last text box. 
↑と←： TAB which returns behind　： I advance before and stop in last text box. 

グリッド
→：現在行のみ右に移動
←：現在行のみ左に移動
↓：現在列のみ下に移動
↑：現在列のみ上に移動
TAB　：横に進み、行の最後で次の行に移動しながら進み、それを最後のセルまで到達したら最初の行に戻り繰り返す。

A grid  →： Only a line is moved now by the right  ←： Only a line is moved now by the left  ↓： Only a line moves below now  ↑： It is movement TAB only on a line now　： I advance aside and advance while moving to the next line by the last of a line and I come back to the first line if I arrive at the last cell and repeat it.

---------------------------------------------------------------------------------------
１．３　セル機能
セルの属性として左詰、右詰、中詰の設定が出来ます。これは次の章で詳細を説明しますが、画面定義ファイルで設定します。また、書込有／書込無の設定、カーソル移動有／無の設定等が出来ます。
グリッドでは列毎にタイトルを書き込む設定も出来ます。

1.3  A cell function 
左詰, 右詰, setting of 中詰 are possible as an attribute of a cell. This explains the details in the next chapter, but sets it with a screen definition file. In addition, setting of note existence / note nothing, setting of cursor movement existence / nothing are possible. 
Setting to write in a title at every line is possible with a grid.

---------------------------------------------------------------------------------------
２．定義ファイル
２．１　サブフォーム定義ファイル
サブフォームは単独セル（テキストボックス）と集合セル（グリッド）の混在した画面を定義するテキストファイルです。以下に見本のファイルを示します。

2.   A definition file 
2.1  An assistant form definition file 
An assistant form is text file to define the screen which coexisted of a set cell (a grid) as an independent cell (text box). I show below a file of a sample.
---------------------------------------------------------------------------------------
＜グリッドとテキスト用定義＞
COLS=136	#for form window columns
ROWS=44	#for form window rows

CELL_LENGTH=4,20,30,15,15,14,14,14,0
CELL_ALIGN=right,left,left,left,left,right,right,right,0
CELL_ACTION=edit,edit,edit,edit,edit,edit,edit,edit,0
GRID_SX=0
GRID_SY=14
GRID_EX=134
GRID_EY=42
GRID_TITLES=No,品物名,取引先名,TEL,FAX,単価,個数,合計,0
GRID_FIELD_TYPE=numeric,text,text,text,text,currency,currency,currency,0
GRID_SKIP_STEP= skip,step,step,step,step,step,step,step,0

LABEL_X=2,2,2,2,2,83,83,83,0
LABEL_Y=4,6,8,10,12,4,6,8,0
LABEL_LENGTH=10,10,10,10,10,12,10,12,0
LABEL_TEXT=No,品物名,取引先名,TEL,FAX,単価,個数,合計,0
TEXTBOX_NO=0,1,2,3,4,5,6,7,0
TEXTBOX_X=18,18,18,18,18,99,99,99,0
TEXTBOX_Y=2,4,6,8,10,2,4,6,0
TEXTBOX_LENGTH=4,20,30,15,15,14,14,14,0
TEXTBOX_ALIGN=RIGHT,LEFT,LEFT,LEFT,LEFT,RIGHT,RIGHT,RIGHT,0
TEXTBOX_ACTION=edit,edit,edit,edit,edit,edit,edit,edit,edit,0
TEXTBOX_FIELD_TYPE= numeric,text,text,text,text,currency,currency,currency,0
TEXTBOX_SKIP_STEP =skip,step,step,step,step,step,step,step,0

＜グリッドとパネルテキスト用定義＞
COLS=138	#for form window columns
ROWS=43	#for form window rows

LABEL_X=1,6,27,58,74,90,105,120,0
LABEL_Y=3,3,3,3,3,3,3,3,3
LABEL_LENGTH=4,20,30,15,15,14,14,14,0
LABEL_TEXT=No,品物名,取引先名,TEL,FAX,単価,個数,合計,0

PANEL_COLS=136
PANEL_ROWS=4
PANEL_SX=0
PANEL_SY=5
PANEL_DIFF=3
PANEL_NUM=3

TEXTBOX_NO=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0
TEXTBOX_X=1,1,6,6,27,27,58,58,74,74,90,90,105,105,120,120,0
TEXTBOX_Y=1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,0
TEXTBOX_LENGTH=4,4,20,20,30,30,15,15,15,15,14,14,14,14,14,14,0
TEXTBOX_ALIGN=RIGHT,LEFT,RIGHT,LEFT,LEFT,LEFT,RIGHT,RIGHT,RIGHT,RIGHT,RIGHT,RIGHT,CENTER,RIGHT,
LEFT,CENTER,CENTER,CENTER,CENTER,CENTER,0
TEXTBOX_ACTION=EDIT,NONE,EDIT,EDIT,NONE,EDIT,EDIT,EDIT,EDIT,NONE,NONE,EDIT,NONE,EDIT,EDIT,NONE,
EDIT,EDIT,EDIT,EDIT,NONE,NONE,0
TEXTBOX_FIELD_TYPE=NUMERIC,TEXT,TEXT,TEXT,TEXT,CURRENCY,CURRENCY,CURRENCY,CURRENCY,
CURRENCY,CURRENCY,CURRENCY,CURRENCY,CURRENCY,CURRENCY,CURRENCY,CURRENCY,0
TEXTBOX_SKIP_STEP=step,step,skip,step,skip,step,skip,step,skip,step,skip,step,skip,step,step,step,skip,0

CELL_LENGTH=4,20,30,15,15,14,14,14,0
CELL_ALIGN=right,left,left,left,left,right,right,right,0
CELL_ACTION=edit,edit,edit,edit,edit,edit,edit,edit,0
GRID_SX=0
GRID_SY=14
GRID_EX=134
GRID_EY=42
GRID_TITLES=No,品物名,取引先名,TEL,FAX,単価,個数,合計,0
GRID_FIELD_TYPE=numeric,text,text,text,text,currency,currency,currency,0
GRID_SKIP_STEP=skip,step,step,step,step,step,step,step,0

サブフォームとは単独セルに対し、テーブルカラムの一覧を同時に表示する機能をもったウインドウ画面のことを指します。
また、この定義ファイルを変更することで、一覧だけの画面、帳票だけの画面も作成出来ます。
＃マークはコメントを意味し、１行あたり最大１０２３バイトまで読みとることが出来ます。
【注意事項】
・グリッドでは最初の１行はタイトル用に予約されているため、１行だけのグリッドでも必ず２行作成する必要があります。
・aseで画面設計する場合グリッドの作成開始位置は３行目からにするとヘッダ右にある位置カウンタを表示することが出来ます。

It points at the window screen which had a function to display a list of a table column at the same time for an independent cell with an assistant form. 
In addition, I can make a screen only for a list, a screen only for a book vote by changing this definition file. 
A # mark means comment and can read it to 1,023 bytes per one line at the maximum. 
【Instructions】 
* First one line has to make two lines with a grid only for one line by all means with a grid so that it is made reservations for titles. 
* When a making start position of a grid does a screen in ase in from the third line when I design it, I can display a position counter in the header right. 

---------------------------------------------------------------------------------------
２．２　定義ファイルの機能
以下の定義は主画面（メインフォーム）のカラム数と行数を設定します。
COLS
ROWS

CELL_LENGTH		グリッド上のセルの長さを列ごとにカンマで区切り設定します。
CELL_ALIGN		グリッド上のセル内テキストの配置を列ごとにカンマで区切り設定します。
CELL_ACTION		グリッド上のセル使用／使用不可を列ごとにカンマで区切り設定します。
GRID_SX		フォーム上のＸ軸セルの開始位置を設定します。
GRID_SY		フォーム上のＹ軸セルの開始位置を設定します。
GRID_EX		フォーム上のＸ軸セルの終了位置を設定します。
GRID_EY		フォーム上のＹ軸セルの終了位置を設定します。
GRID_TITLES		グリッドの上に表示するタイトルを列ごとにカンマで区切り設定します。
GRID_FIELD_TYPE	グリッド上のセルの入力タイプを列ごとにカンマで区切り設定します。
GRID_SKIP_STEP	スキップセルをセルごとにカンマで区切り設定します
DB_TITLES		データベース項目を列ごとにカンマで区切り設定します。

LABEL_X		単独セルに対するラベルの開始Ｘ軸
LABEL_Y		単独セルに対するラベルの開始Ｙ軸
LABEL_LENGTH		単独セルに対するラベルの長さ
LABEL_TEXT		単独セルに対するラベル文字
TEXTBOX_NO		単独セル番号（０−３８３）
TEXTBOX_X		単独セルのＸ軸位置
TEXTBOX_Y		単独セルのＹ軸位置
TEXTBOX_LENGTH	単独セルの長さ
TEXTBOX_ALIGN	セル内テキストの配置をセルごとにカンマで区切り設定します。
TEXTBOX_ACTION	セル内テキストの使用／使用不可をセルごとにカンマで区切り設定します。
TEXTBOX_FIELD_TYPE	セル内テキストの入力タイプをセルごとにカンマで区切り設定します。
TEXTBOX_SKIP_STEP	スキップセルをセルごとにカンマで区切り設定します。

PANEL_COLS		パネルウインドウの幅
PANEL_ROWS		パネルウインドウの行数
PANEL_SX		フォーム上のＸ軸セルの開始位置を設定します。
PANEL_SY		フォーム上のＹ軸セルの開始位置を設定します。
PANEL_DIFF		次のパネルとの差分行数
PANEL_NUM		作成するパネルの数

2.2  　A function of a definition file 
The following definitions set the number of the columns and linage of the main screen (a main form).

COLS 
ROWS 

CELL_LENGTH      I divide length of a cell on a grid with a comma every line and set it. 
CELL_ALIGN       I divide placement of a text in a cell on a grid with a comma every line and set it. 
CELL_ACTION      I divide cell use / use impossibility on a grid with a comma every line and set it. 
GRID_SX      I set a start position of X-axis cell in a form. 
GRID_SY      I set a start position of Y-axis cell in a form. 
GRID_EX      I set an end position of X-axis cell in a form. 
GRID_EY      I set an end position of Y-axis cell in a form. 
GRID_TITLES      I divide a title to display on a grid with a comma every line and set it. 
I divide an input type of a cell on a GRID_FIELD_TYPE grid with a comma every line and set it. 
DB_TITLES which I divide a GRID_SKIP_STEP skip cell with a comma every cell and set        I divide a database item with a comma every line and set it. 

LABEL_X:      Start X-axis LABEL_Y: of a label for an independent cell      Start Y-axis LABEL_LENGTH: of a label for an independent cell         Length LABEL_TEXT: of a label for an independent cell       Label letter TEXTBOX_NO: for an independent cell       Independent cell number (0-383) TEXTBOX_X:        X-axis position TEXTBOX_Y: of an independent cell        Y-axis position TEXTBOX_LENGTH: of an independent cell   Length TEXTBOX_ALIGN: of an independent cell    I divide placement of a text in a cell with a comma every cell and set it. 
TEXTBOX_ACTION:   I divide use / use impossibility of a text in a cell with a comma every cell and set it. 
TEXTBOX_FIELD_TYPE:   I divide an input type of a text in a cell with a comma every cell and set it. 
TEXTBOX_SKIP_STEP:    I divide a skip cell with a comma every cell and set it. 

PANEL_COLS:       Width PANEL_ROWS: of a panel window       Linage PANEL_SX: of a panel window         I set a start position of X-axis cell in a form. 
PANEL_SY:         I set a start position of Y-axis cell in a form. 
PANEL_DIFF:       It is linage PANEL_NUM: for a difference with the next panel        The number of panels to make
---------------------------------------------------------------------------------------
２．３　ヘッダー定義ファイル
主画面の上に表示するヘッダーを定義します。

2.3  A header definition file 
I define a header to display on the main screen.
---------------------------------------------------------------------------------------
COLS=136	#for header window columns
ROWS=4	#for header window rows
CELL_LENGTH=132,0
CELL_ALIGN=CENTER,0
CELL_ACTION=EDIT
GRID_SX=0
GRID_SY=1
GRID_EX=134
GRID_EY=1
GRID_TITLES=Linux Subforms  1.0,0

２．４　フッター定義ファイル
主画面のの下表示するフッターを定義します。主に列ごとの計算結果を表示します。

2.4 　A footer definition file 
I define a footer displaying a bottom of a thing of the main screen. I display a calculation result every line mainly.
---------------------------------------------------------------------------------------
COLS=136	#for footer window columns
ROWS=4	#for footer window rows
CELL_LENGTH=4,20,30,15,15,14,14,14,0
CELL_ALIGN=right,left,left,left,left,right,right,right,0
CELL_ACTION=EDIT
GRID_SX=0
GRID_SY=1
GRID_EX=134
GRID_EY=1
#GRID_TITLES=No,品物名,取引先名,TEL,FAX,単価,個数,合計,0

３．サブフォーム画面詳細設計
サブフォームメイン画面は以下の６つの構造体で定義されます。

3. assistant form screen details design assistant form Maine screens are defined with six following structure bodies.
---------------------------------------------------------------------------------------
１）テキストボックス用セル情報構造体
typedef struct textbox {
	struct textbox *next; //Next link for Textbox
	struct textbox *prev;  //Previous link for Textbox
	char *s;    //入力及びSQLの結果をセルの長さ分表示
	unsigned long n;   //現在未使用
	int no;    //テキストボックスの番号（0 1 2 3 …）
	int x;    //フォームウインドウ上のＸ軸セル位置
	int y;    //フォームウインドウ上のＹ軸セル位置
	int c;    //テキストボックスセル番号（1 2 3 …）
	int col;    //テキストボックスセル番号（0 1 2 3 …）
	int len;    //テキストボックスセルの長さ
	int attr; //現在未使用
	int ftype;   //フィールドの型（TEXT NUMERIC CURRENCY …）
	int action;   //テキストボックスアクション（編集可能／編集不可）
	int align;    //テキストボックスアライメント
} TextBox;
２）グリッド用セル情報構造体
struct cell {  int no;    //グリッドセルの番号（0 1 2 3 …）
	int x;    //フォームウインドウ上のＸ軸セル位置
	int y;    //フォームウインドウ上のＹ軸セル位置
	int c;    //グリッドセル番号（1 2 3 …）
	int len;    //グリッドセルの長さ
	int attr;    //現在未使用
	int ftype;   //フィールドの型（TEXT NUMERIC CURRENCY …）
	int action;   //グリッドセルアクション（編集可能／編集不可）
	int align;    //グリッドセルアライメント
	char s[MAX_STR];   //入力及びSQLの結果を最大１３８バイト表示
	WINDOW * cell;
};
３）パネル用サブウインドウ用構造体
struct PanelBox {
	WINDOW *panel;    //パネルウインドウ
	int sx;      //パネルウインドウのＸ軸左開始位置
	int ex;      //パネルウインドウのＸ軸左終了位置
	int sy;      //パネルウインドウのＹ軸左開始位置
	int ey;      //パネルウインドウのＹ軸左終了位置
	int width;     //
	int height;     //
};
４）セル用サブウインドウ用構造体
	struct SubForm {  WINDOW *vs;    //セルウインドウ（セルの長さ＋２桁／１行）
	int col;     //save column
	int line;     //save line
	int no;     //Textbox number
	int n;     //Textbox number
	int x;     //x col
	int y;     //y line
	int c;     //Cell position of numeric
	int len;     //Cell length
	int ftype;    //Filed type
	int action;    //Cell action
	int align;     //Cell aligment
	int stype;    //Cell skip or step.
};
５）メインフォームウインドウ用構造体
	struct VewBox {
	WINDOW *form;
	int panel_num;				//パネル番号 save number
	int maxlabel;				//ラベルの最大値
	int alltext;				//パネルのテキスト番号
	int maxtext;				//テキストセルの最大値
	int t_col;					//テキストセルのカラム番号
	int t_line;					//テキストセルの行番号
	int t_n;					//テキストセルの番号
	int t_len;					//テキストセルの長さ
	int t_c;					//テキストセルのポジション
	int t_x;					//テキストセルの場所X軸
	int t_y;					//テキストセルの場所Y軸
	int t_ftype;				//テキストセルのフィールドタイプ(TEXT or NUMERIC or DATE or CURRNCY)
	int t_action;				//テキストセルのアクション(EDIT or NONE)
	int t_align;				//テキストセルの内部アライメント(LEFT or RIGHT or CENTER)
	int t_stype;				//テキストセルのスキップとステップ設定(SKIP or STEP)
	int g_col;					//グリッドセルのカラム番号
	int g_line;					//グリッドセルの行番号
	int g_no;					//グリッドセルの番号
	int g_len;					//グリッドセルのの長さ
	int g_c;					//グリッドセルのポジション番号
	int g_x;					//グリッドセルの場所X軸
	int g_y;					//グリッドセルの場所Y軸
	int g_ftype;				//グリッドセルのフィールドタイプ
	int g_action;				//グリッドセルののアクション
	int g_align;				//グリッドセルのアライメント
	int g_stype;				//グリッドセルのスキップとステップ設定
	int g_dbindex;				//ＤＢグリッドセルのインデックス。ポインタ配列*splitDBbuff[index][]のための番号
	int dbstartline;			//ＤＢ配列からグリッドに表示する最初のライン。splitDBbuff[index][]のための位置情報
	int dbstartcol;				//ＤＢ配列からグリッドに表示する最初の列。splitDBbuff[index][]のための位置情報
	} xt[MAX_FORM];    //最大１０(cygwinの場合は最大３にして下さい)

６）メインフォーム位置情報構造体
	struct FormBox { // WINDOW *form; /*Form WINDOW*/
	int sx;     //フォームウインドウのＸ軸左開始位置
	int ex;     //フォームウインドウのＸ軸右終了位置
	int sy;     //フォームウインドウのＹ軸上開始位置
	int ey;     //フォームウインドウのＹ軸下終了位置
	int lcol;     //一行あたりのセルの数
	int width;    //現在未使用
	int height;    //現在未使用
	int attr;     //現在未使用
	struct SubForm pos[MAX_COL];  //テキストボックスの位置を管理（最大３８４個）
	struct SubForm st[MAX_COL][MAX_ROW]; //グリッド上のセル位置を管理（最大５２行）
	struct PanelBox pt[MAX_PANEL];  //フォーム上のテキストボックスエリアを管理（最大１８個）
	struct cell cp[MAX_COL][MAX_ROW]; //グリッド上のセル属性を管理（最大５２行）
	char *splitDBbuff[MAX_DB_LINE][MAX_COL];//DBgrid()用。DBからの項目を行毎に管理するポインタ配列。assget()が使用する。
} ft[MAX_FORM];    //最大１０(cygwinの場合は最大３にして下さい)

	char *splitDBbuff[MAX_COL];//textbox()用。DBからの項目を管理するポインタ配列。UPDATE INSERT用の一時的な配列。assput()が使用する。

以上テキストボックス、グリッド、パネルテキストともメインフォーム上の相対位置に設置されます。
このほか、ラベルがありますが、ラベルはメインフォーム上に直接書き込まれます。
ラベルは以下の定義を持ちます。なおラベルは最大３８４個設置出来ます。

It is installed in a relative position in a main form with text box, a grid, a panel text as things mentioned above. 
In addition, there is a label, but a label is written in on a main form directly. 
A label has the following definitions. In addition, greatest 384 can install a label.
---------------------------------------------------------------------------------------
“LABEL_X=",    //フォームウインドウ上のＸ軸ラベル位置
“LABEL_Y=",    //フォームウインドウ上のＹ軸ラベル位置
“LABEL_LENGTH=",   //ラベルの長さ（最大１３７バイト）
“LABEL_TEXT=",    //ラベルテキスト 	

４．セル作成の詳細
４．１　グリッド
４．１．１ 通常のグリッド

サブフォームメイン画面上のグリッドは以下の２つのCURSES関数で設定されます。

xt[no].form = newwin(rows,xcol,fy,fx);
ここで、変数no は０がメインフォーム、１がヘッダー、２をフッターに使用します。
rowsとxcol は、定義ファイルのrowsとxcolの定義項目名の値に設定されます。
fyは、メインフォームのＹ軸開始位置です。fxはＸ軸開始位置です。
もし、サブフォームを複数ウインドウ表示したい場合は wsubform.hのMAX_FORMの値を増やして下さい。

ft[no].st[c][j].vs = subwin(xt[no].form,1,length[l]+2,fy+grid_sy+j,(grid_sx+k+0));

この命令はグリッド用セルを作成しています。ここで、st構造体の変数cは行カラムを意味します。
セルの行数は１で長さは変数length[l]+2で設定されます。Length[]は定義ファイルの中にあるCELL_LENGTHの設定値になります。
＋２と増やしてあるのは縦罫線を表示するための余白です。変数jは行数をカウントします。変数grid_sxは開始位置が定義ファイルから設定されているので、これに変数k各カラム毎の長さを足していき、縦罫線分の余白１をとります。
以上、フォームウインドウ上のセル配置行うと同時に、定義ファイルに記述されたセル属性を順次cp[]構造体に書き込みます。グリッドは最大３８４桁×５２行のセルを作成出来ます。

4.  The details of cell making 
4.1 　A grid 
4.1.1  A normal grid 

A grid on assistant form Maine screen is set by two following CURSES functions. 

xt[no]. Form = newwin(rows,xcol,fy,fx); 
Here, as for variable no, main form, 1 use header, 2 for a footer 0. 
rows and xcol are set by a value of the definition item name of rows and xcol of a definition file. 
fy is Y-axis start position of a main form. fx is X-axis start position. 
Please increase values of MAX_FORM of wsubform.h when a window wants to display plural assistant forms. 

ft[no]. st[c][j]. vs = subwin(xt[no]. form,1,length[l]+2,fy+grid_sy+j,(grid_sx+k+0)); 

This order makes a cell for grids. Here, variable c of st structure health means a line column. 
As for the linage of a cell, length is set in variable length[l]+2 with 1. Length[] becomes a set point of a certain CELL_LENGTH in a definition file. 
It is a blank to display a ruled line long that is increased with +2. Variable j counts linage. Because a start position is set by a definition file, variable grid_sx adds length every each variable k column to this and takes blank 1 for a ruled line long. 
I write in a cell attribute described in a definition file at a cp[] structure body sequentially as things mentioned above at the same time to perform cell placement on a form window. Grid can make a cell of 384 columns *52 lines at the maximum.
---------------------------------------------------------------------------------------
４．１．２ ＤＢグリッド
グリッドの作成過程は通常のグリッドと同じですが、wsubform.hに定義されているsplitDBbuff[][]のmalloc()された行列と同期をとることが出来ます。
同時にwsubform.hに定義されたg_dbindexを利用してDB行の位置を把握することでグリッドの行列に連結したsplitDBbuff[][]をスクロールすることが出来ます。
ＤＢグリッドの操作はECPGソースと密接に関連しています。そのため、ＤＢグリッドの作成には ase のECPGソース生成機能を利用することを推奨します。
ase の画面ファイルの作成とECPGソース生成およびテンプレートのsubform()を追加するだけでＤＢグリッドが扱えます。
ＤＢグリッドでアプリケーションを開発する場合、UPDATE と INSERT では、ポップアップフォームウインドウのテキストボックスからの入出力を可能にするために ポインタ配列 splitDBbuff[]を用意しました。グリッド用の２次元配列では無く１次元配列になっています。
この splitDBbuff[] を利用している assputDB() 関数では、ECPGの内部配列の初期化および使用後のsplitDBbuff[]の開放までを自動的に行います。
※自動生成するECPGソースを参考にしてください。

4.1.2   A DB grid 
A making process of a grid is the same as a normal grid, but can take a line and the same period done malloc() of splitDBbuff[][] defined by wsubform.h. 
I can scroll splitDBbuff[][] which I connected with a line of a grid by grasping a position of DB line using g_dbindex defined at the same time by wsubform.h. Operation of a DB grid is related to an ECPG source and closeness. Therefore I recommend that I use an ECPG source generation function of ase for making of a DB grid. 
I can treat a DB grid just to add making and ECPG source generation of a screen file of ase and subform() of a template. 
When I developed an application with a DB grid, I prepared pointer arrangement splitDBbuff[] to enable input and output from text box of a popup form window in UPDATE and INSERT. I am not be it for a one-dimensional arrangement by a two-dimensional arrangement for grids. 
This splitDBbuff[]  assputDB which uses を()  By a function, I perform initialization of inside arrangement of ECPG and opening of splitDBbuff[] after use automatically. 
※ Please refer to an automatic ECPG source to generate.
---------------------------------------------------------------------------------------
４．２　テキストボックス
テキストボックスの場合はリスト構造の連鎖を作成し、それを外部から操作出来るようにtpという名前の構造体ポインタにおきかえます。このリスト構造の先頭から最後までpos[]という構造体配列の中のvsがテキストボックスセルを指します。
Pos[]はセルウインドウを管理し、セル属性は定義ファイルより読みとられた後、tpのしめす構造体TextBoxの中にあるメンバー変数に設定されます。
以下がセルを作成する場面です。

	ft[no].pos[i].vs = subwin(xt[no].form,1,Textpos[j][3]+2,fy+Textpos[j][2],Textpos[j][1]);

テキストボックスはpos[]構造体にセルを定義します。定義ファイルに書き込まれたポジションはローカル変数Textps[][]によって読みとられ、メインフォームの上に相対的にセル定義されます。Textpos[][3]はセルの長さです。
また、Textpos[][1]及び、Textpos[][2]はメインフォーム上のＸ軸、Ｙ軸になります。
テキストボックスの最大数は現在の仕様では３８４個となっています。
【注意事項 】
テキストボックスのセルはグリッドと同じように配置出来ますが、セルとセルとの間に１桁の間隔を空けるようにしてください。
そうしないとセルを意味する[ ]で右側の ] が見えなくなります。これは右側の ] がグリッドとは違い付け加えられているためです。
 ] が無くても影響が無ければグリッドと同じように配置しても問題はありません。

4.2 　Text box 
I make a chain of list structure in the case of text box and I get up and exchange it with a structure body pointer named tp to be able to operate it from the outside. vs in a structure position line of pos[] points at a text box cell till the last from the top of this list structure. 
Pos[] manages a cell window, and a cell attribute is set by the member variable that there is in structure body TextBox which tp shows after it was read than a definition file. 
It is the scene where the following makes a cell. 

    ft[no]. pos[i]. vs = subwin(xt[no]. form,1,Textpos[j][3]+2,fy+Textpos[j][2],Textpos[j][1]); 

	Text box defines a cell to a pos[] structure body. A position written in at a definition file is read by local variable Textps[][], and it is relatively defined a cell on a main form. Textpos[][3] is length of a cell. 
	In addition, Textpos[][1] and Textpos[][2] become the X-axis in a main form, the Y-axis. 
	A maximum number of text box becomes 384 with current specifications. 
	【Instructions】I can arrange a cell of text box in the same way as a grid, but please leave one column of interval between a cell and cells. 
	] of the right side that means a cell unless I do so it  I become it without が vanity. This] of the right side  The reason is because it is added unlike a が grid. 
	 ]  A problem is not not have が even if I post it in the same way as a grid if there is not influence.
---------------------------------------------------------------------------------------
４．３　パネルテキスト
パネルテキストは、テキストボックスの集合をft[no].pt[k].panelというサブウインドウの中に納め列と行で管理出来るようにしたものです。各パネル毎最大３８４個のテキストボックスを配置出来ます。パネル数の最大値は１８個になります。

ft[no].pt[k].panel = subwin(xt[no].form,panel_rows,panel_cols,l,panel_sx);

パネルの中のテキストボックスは以下のようにderwin()で作成されます。仕様はテキストボックスと同じです。

ft[no].pos[i].vs = derwin(ft[no].pt[k].panel,1,Textpos[j][3]+2,Textpos[j][2],Textpos[j][1]);

4.3 　A panel text 
A panel text is ft[no]. with a set of text box pt[k]. I put it in an assistant window of panel and was able to manage it in a line and a line. Every each panel can arrange text box of greatest 384. The maximum of the number of the panels becomes 18. 

ft[no]. pt[k]. panel = subwin(xt[no]. form,panel_rows,panel_cols,l,panel_sx); 

Text box in a panel is made in derwin() as follows. Specifications are the same as text box. 

ft[no]. pos[i]. vs = derwin(ft[no]. pt[k]. panel,1,Textpos[j][3]+2,Textpos[j][2],Textpos[j][1])
---------------------------------------------------------------------------------------
４．４　属性
セルの属性には以下があります。
１）	セル内配置属性（align 1右詰 2左詰 3センター）
２）	編集属性（action 0 編集可能、1 編集不可）
３）	入力型属性（ftype）
フィールド型には８つの型があり、プログラム上以下の数値で区分けします。
	TEXT		1
	NUMERIC		2
	BOOL		3
	CURRENCY	4
	DATE		5
	SINGLE		6
	DOUBLE		7
	BYTE		8

４）	選択属性（stype 0スキップ　1 ステップ）
セル内配置属性は付属のライブラリ関数srcep(),slcep(),sccep()の３つの関数を呼び出して決定します。
テキストボックスの場合、編集属性はテキストボックス操作関数formtext()内で入力時tp->actionフラグの値が０の場合
だけ入力を許可する方法をとっています。グリッドの場合はcp[].actionになります。
入力型属性はtekitinput()関数内からライブラリ関数jmvwgetnstr()関数を呼び出し、テキスト型、数値型、通貨型のタイプ
を切り分けます。通貨型の場合、３桁毎にカンマを付加するCURLIB01ライブラリ関数varprint()を呼び出します。
なお、各セルは文字以外は全てスペースで埋められます。このため入力時スペーシング処理が行われます。spacerという関数内配列がその役割を果たします。文字以外のスペースはグリッドでは横罫線のかわりとなるアンダーラインを引き、カーソルを反転表示します。
選択属性というのは、カーソル移動時にセルをスキップするかどうかの属性です。定義ファイルのTEXTBOX_SKIP_STEPに定義された内容でカーソル移動の様子が変化します。この判定は操作関数formtext()、グリッドではgrid()内でカーソル移動のコマンド毎に行っています。

4.4 　An attribute 
An attribute of a cell has the following. 
1,     Placement attribute (one two align 右詰 左詰 3 center) in a cell
2,     Editing attribute (0 action editing possibility, one editing impossibility)
3,     There are eight models in input type attribute (ftype) Field type and divides it with the following numerical value in a program. 
	TEXT         1 
	NUMERIC      2 
	BOOL         3 
	CURRENCY     4 
	DATE         5 
	SINGLE       6 
	DOUBLE       7 
	BYTE         8 

Four)     A placement attribute in a choice attribute (0 one stype skip steps) cell calls three functions of attached library function srcep(),slcep(),sccep() and is decided. 
In the case of text box, an editing attribute takes the method how a value of a tp-action flag admits the input only in the case of 0 in text box operation function formtext() at input time. It is cp[]. in the case of a grid I become action. 
An input type attribute calls a library function jmvwgetnstr() function from a tekitinput() function and cuts a text type, numerical value type, currency-shaped type into pieces. In the case of a currency type, I call CURLIB01 library function varprint() which adds a comma to every three columns. 
In addition, each cell is buried other than a letter entirely in space. On this account Spey thing processing is performed at input time. An arrangement in a function of spacer serves as the role. Space except a letter pulls an underline becoming a change of a wide ruled line with a grid, and reversing display does a cursor. 
A choice attribute is an attribute skipping in a cell at the time of cursor movement. A state of cursor movement changes by contents defined by TEXTBOX_SKIP_STEP of a definition file. This judgment goes every command of cursor movement in grid() with operation function formtext(), a grid.
---------------------------------------------------------------------------------------
５．カーソル操作
テキストボックス、グリッド内のカーソル移動は以下の操作になります。
テキストボックス	
キーマップ	機能	
KEY_IC KEY_DC KEY_BACKSPACE TAB KEY_DOWN KEY_RIGHT 0x0d 0x0a KEY_UP KEY_LEFT KEY_F(1)-KEY_(F11 KEY_F(12)) ESC その他の文字	挿入／上書の切り替え 一文字右を削除（右寄セルの場合は全てを削除） 一文字左を削除 カーソルを前に進め、最後のセルに達したら最初のセルに戻る カーソルを前に進め、最後のセルに達したら最初のセルに戻る カーソルを前に進め、最後のセルに達したら最初のセルに戻る カーソルを前に進め、最後のセルに達したら最初のセルに戻る カーソルを後ろに戻す カーソルを後ろに戻す テキストボックスの場合は101-111 パネルの場合は301-311を返す テキストボックスの場合は199 パネルの場合は399を返す テキストボックスの場合は100 パネルの場合は300を返す 文字、数値の入力	
 グリッド	
キーマップ	機能	
KEY_IC KEY_DC KEY_BACKSPACE TAB KEY_DOWN KEY_RIGHT 0x0d 0x0a KEY_UP KEY_LEFT KEY_F(1)-KEY_(F11 KEY_F(12)) ESC その他の文字	挿入／上書の切り替え 一文字右を削除（右寄セルの場合は全てを削除） 一文字左を削除 カーソルを右に移動し、最下行の最後のセルに達したら最初のセルに戻る カーソルを下に移動する カーソルを右に移動する カーソルを下に移動する カーソルを上に移動する カーソルを左に移動する 201-211を返す 299を返す 200を返す 文字、数値の入力	

5.   Cursor operation 
As for the text box, the cursor movement in a grid, it is operated the following. 
Text box key map function KEY_IC KEY_DC KEY_BACKSPACE TAB KEY_DOWN KEY_RIGHT 0x0d 0x0a KEY_UP KEY_LEFT KEY_F(1) -KEY_(F11 KEY_F(12))  A letter returning 300 in the case of 100 panels in the case of text box to return 399 in the case of 199 panels in the case of text box to return 301-311 in the case of 101-111 panels in the case of text box to return a cursor returning the cursor which comes back to the first cell if I advance with a deletion cursor forward in the deletion (I delete all in the case of a Right cell) 1 character left in the change 1 character right of epenthesis / overwrite of ESC others and advance with the cursor which comes back to the first cell if I reach the last cell forward and advance with the cursor which comes back to the first cell if I reach the last cell forward and advance with the cursor which comes back to the first cell if I reach the last cell forward and reach the last cell behind behind, the numerical input 
 A grid 
 A key map function 
 KEY_IC KEY_DC KEY_BACKSPACE TAB KEY_DOWN KEY_RIGHT 0x0d 0x0a KEY_UP KEY_LEFT KEY_F(1) -KEY_(F11 KEY_F(12))  A letter returning 200 to return 299 to return 201-211 to move to the left with a cursor moving to the top with a cursor moving with a cursor moving to the right with a cursor moving with the cursor which comes back to the first cell if I move to the right with a deletion cursor in the deletion (I delete all in the case of a Right cell) 1 character left in the change 1 character right of epenthesis / overwrite of ESC others and reach the last cell of a bottom line below below, the numerical input
---------------------------------------------------------------------------------------
６．アクセス関数
サブフォームには４１個の関数でアクセス出来ます。

6.   An access function 
I can access an assistant form by 39 functions.
---------------------------------------------------------------------------------------
int grid(int no,int maxtext,int xcol);
int no		ウインドウ番号
int maxtext	配置されたテキストの最大数
int xcol		画面の最大幅

この関数はグリッド内でキー入力を受付けキーの種類により処理を分岐します。
入力文字はa〜z、A〜Z及び、0〜9の数字となります。
Insert キーにて文字入力の挿入／上書の切り替えを行います。
DeleteキーとBackspaceキーは文字入力ルーチンjmvwgetnstr()関数の仕様に従います。
矢印キー及びTABキーでカーソル移動を行い、ファンクションキーで200〜299の正数値を返します。
	F1	201
	F2	202
	F3	203
	F4	204
	F5	205
	F6	206
	F7	207
	F8	208
	F9	209
	F10	210
	F11	211
	F12	299
	ESCキーは100を返します。
	入力時ではESCキーで入力前の状態に戻します。（UNDO）

この関数は定義ファイルを読み取り複数のラベルと複数のテキストボックスを作成します。
int textbox(int no, int fy, char *f);
int no		ウインドウ番号
int fy		ウインドウの開始Ｙ軸位置
char *f		サブフォーム定義ファイル名

char *addspace(int len, char *s);
int len
char *s

この関数はテキストボックス内でキー入力を受付けキーの種類により処理を分岐します。
int formtext(int no,int maxtext, int xcol);
int no		ウインドウ番号
int maxtext	配置されたテキストの最大数
int xcol		画面の最大幅
この関数はテキストボックスの操作を行います。
入力文字はa〜z、A〜Z及び、0〜9の数字となります。
Insert キーにて文字入力の挿入／上書の切り替えを行います。
DeleteキーとBackspaceキーは文字入力ルーチンjmvwgetnstr()関数の仕様に従います。
矢印キー及びTABキーでカーソル移動を行い、ファンクションキーで100〜199の正数値を返します。

	F1	101
	F2	102
	F3	103
	F4	104
	F5	105
	F6	106
	F7	107
	F8	108
	F9	109
	F10	110
	F11	111
	F12	199
	ESCキーは100を返します。
	入力時ではESCキーで入力前の状態に戻します。（UNDO）

この関数は定義ファイルを読み取りひとつのパネルの上に複数のラベルと複数のテキストボックスとを作成します。
int paneltext(int no, int maxpaneltext, int xcol);
int no		ウインドウ番号
int maxpaneltext	配置されたテキストの最大数
int xcol		画面の最大幅
この関数はパネルテキストの操作を行います。
入力文字はa〜z、A〜Z及び、0〜9の数字となります。
Insert キーにて文字入力の挿入／上書の切り替えを行います。
DeleteキーとBackspaceキーは文字入力ルーチンjmvwgetnstr()関数の仕様に従います。
矢印キー及びTABキーでカーソル移動を行い、ファンクションキーで300〜399の正数値を返します。

	F1	101
	F2	102
	F3	103
	F4	104
	F5	105
	F6	106
	F7	107
	F8	108
	F9	109
	F10	110
	F11	111
	F12	199
	ESCキーは100を返します。
	入力時ではESCキーで入力前の状態に戻します。（UNDO）

この関数は定義ファイルを読み取りひとつのパネルの上に複数のラベルと複数のテキストボックスとを作成します。
int panels(int no, int xcol,int rows,int fy, char *f);
int no		ウインドウ番号
int xcol		画面の最大幅
int rows		画面の最大行
int fx		ウインドウの開始Ｘ軸位置
int fy		ウインドウの開始Ｙ軸位置
char *f		サブフォーム定義ファイル名
subwin()でパネルを作成しderwin()でテキストボックスを作成します。

この関数は定義ファイルを読み取りグリッドを作成します。
int wsubform(int no, int xcol,int rows,int fx ,int fy, char *f);
int no		ウインドウ番号
int xcol		画面の最大幅
int rows		画面の最大行
int fx		ウインドウの開始Ｘ軸位置
int fy		ウインドウの開始Ｙ軸位置
char *f		サブフォーム定義ファイル名
Wsubform()関数はメインのモジュールです。サブフォームの縦横の大きさを確定し、グリッド領域を作成します。
返り値：フォームウインドウの幅(xcol)
※fyの値には注意して下さい。例えばヘッダーウインドウが２行を占めている場合はメインウインドウは、
  上部より２行の間隔を空けなければならないからです。もし、正確に間隔を取らないとセルの位置がずれます。

この関数はセルの属性を調査します。
int sf_status(int no, int type, char opt);
int no		ウインドウ番号
int type		テキストボックス＝１、グリッド＝２，パネルテキスト＝３
int opt		w,yx,y,X,n,l,c,a,A,f,s
この関数は現在のセルの情報を調査します。詳細は以下になります。
	w	ウインドウが存在するかどうか無い場合は−１を返す。
	y	フォームウインドウ上のセルのＹ軸
	x	フォームウインドウ上のセルのＸ軸
	Y	セルの行番号
	X	セルのカラム番号（０〜）
	n	セルの番号（０〜）
	l	セルの長さ
	c	セルのカラム番号（１〜）
	a	セルのアライメント
	A	セルのアクション
	f	セルのフィールドタイプ
	s	セルのスキップ
	D	DBgrid()のみ利用可能。DBのレコードを格納するsplitDBbuff[index][]のindex番号を取り出す。
	返り値：各オプションの値

この関数は複数のテキストボックスでのカーソル移動位置指定を行います。
int sf_tlocate(int no, int col);
int no		ウインドウ番号
int col		カラム番号
テキストボックス上のセル位置を変更します。
返り値：成功は0、失敗は-1

この関数はグリッド内でのカーソル移動位置指定を行います。
int sf_glocate(int no, int col, char line);
int no		ウインドウ番号
int col		カラム番号
int line		行番号
返り値：成功は0、失敗は-1
グリッド上のセル位置を変更します。

この関数はテキストボックスへ文字を書き込みます。1文字が2バイト以上の文字は-1を返す
int sf_tput(int no, int col, char *s);
int no		ウインドウ番号
int col		現在のカラム番号
char *s		テキストボックスセルに書き込む文字列
返り値：成功は0、失敗は-1
カーソルのあるテキストボックスに文字列を書き込みます。セルのアライメント属性に従って書き込みます。

この関数はグリッドセルへ文字を書き込みます。1文字が2バイト以上の文字は-1を返す
int sf_gput(int no, int col, int line, char *s);
int no		ウインドウ番号
int col		カラム番号
int line		行番号
char *s		グリッドセルに書き込む文字列
返り値：成功は0、失敗は-1
グリッドに文字列を書き込みます。セルのアライメント属性に従って書き込みます

この関数はテキストボックスから文字列を取り出します。
int sf_tget(int no, int col,char *s);
int no		ウインドウ番号
int col		現在のカラム番号
char *s		テキストボックスセルから読み込んだ文字列
返り値：成功は0、失敗は-1
カーソルのあるテキストボックスから文字列を読み込みます。

この関数はグリッドセルから文字列を取り出します。
int sf_gget(int no, int col, int line,char *s);
int no		ウインドウ番号
int col		カラム番号
int line		行番号
char *s		グリッドセルから読み込んだ文字列
返り値：成功は0、失敗は-1
グリッドセルから文字列を読み込みます。

	この関数はテキストボックス内の文字列を右寄せ、左寄せ、センター寄せします。
int sf_tcep(int no, int col, int align, char *s);
int no		ウインドウ番号
int col		カラム番号
int align		１：右詰　２：左詰　３：センター
char *s		テキストボックスセルに書き込む文字列文字列
返り値：成功は0、失敗は-1
テキストボックスのアライメントを変更します。

この関数はグリッドセル内の文字列を右寄せ、左寄せ、センター寄せします。
int sf_gcep(int no, int col, int line, int align, char *s);
int no		ウインドウ番号
int col		カラム番号
int line		行番号
int align		１：右詰　２：左詰　３：センター
char *s		グリッドセルに書き込む文字列文字列
返り値：成功は0、失敗は-1
グリッドセルのアライメントを変更します。

この関数はテキストボックス内の数字列に3桁ごとにカンマをふります。
int sf_tvarprint(int no, int col, char *s);
int no		ウインドウ番号
int col		現在のカラム番号
char *s		テキストボックスセルから読み込んだ文字列
通貨型のテキストボックス内数値に３桁毎のカンマをふります。

この関数はグリッドセル内の数字列に3桁ごとにカンマをふります。
int sf_gvarprint(int no, int col, int line, char *s);
int no		ウインドウ番号
int col		カラム番号
int line		行番号
char *s		グリッドセルから読み込んだ文字列
通貨型のグリッドセル内数値に３桁毎のカンマをふります。


ＤＢ関連の関数

	※ 以下はDBに対応した関数です。col と line の位置が逆になっていることに注意してください。
	※ DBに関連した関数は特殊な処理をしています。
	  特にwsubform.h に定義されている splitDBbuff[][] は ase エディタで定義された定義ファイルの情報を利用します。

	int sf_DBgrid(int no,int maxtext,int xcol,int startline,int DBcount,int maxcol);
	int no		ウインドウ番号
	int maxtext	配置されたテキストの最大数
	int xcol		画面の最大幅
	int startline	DB行の表示初期行
	int DBcount		読み込んだDBの最大行
	int maxcol		読み込んだDBの最大項目数
	
	この関数はデータベースと連結したグリッドの操作を行います。
	入力文字はa〜z、A〜Z及び、0〜9の数字となります。
	Insert キーにて文字入力の挿入／上書の切り替えを行います。
	DeleteキーとBackspaceキーは文字入力ルーチンjmvwgetnstr()関数の仕様に従います。
	矢印キー及びTABキーでカーソル移動を行い、ファンクションキーで200〜299の正数値を返します。
	F1	201
	F2	202
	F3	203
	F4	204
	F5	205
	F6	206
	F7	207
	F8	208
	F9	209
	F10	210
	F11	211
	F12	299
	ESCキーは100を返します。
	入力時ではESCキーで入力前の状態に戻します。（UNDO）

	void sf_initgridcell(int no);
	int no		ウインドウ番号
	全てのグリッドセルをスペースで初期化します。

	int sf_getstartline(int no);
	int no		ウインドウ番号
	DB連結行の初期行を決定します。(グリッドの上下スクロール時必須)
	ＤＢグリッドの表示初期行を返します。

	void sf_wrefreshcell(int no,int line,int col);
	int no		ウインドウ番号
	int line		行番号
	int col		カラム番号
	指定したウインドウのセルを再表示します。

	void sf_wrefreshform(int no);
	int no		ウインドウ番号
	指定したウインドウを再表示します。

	void sf_startcell(int no);
	int no		ウインドウ番号
	セルのポジションを０で初期化します。
	指定したウインドウのセルカーソル位置を決定します。

	void sf_to_text(int in,char *out)
	int in		int の数値
	char *out	数値を文字に変換したバッファ
	DBの各行をsplitDBbuff[][]に格納するために数値を文字列(テキスト)化します。

	long sf_to_numeric(char *in);
	char *in	数字の文字列
	splitDBbuff[][]の各行をDBに格納するために数字の場合は数値(long)に変換します。

	int sf_to_integer(char *in);
	char *in	数字の文字列
	整数字の文字列を数値にして返す。
	splitDBbuff[][]の各行をDBに格納するために数字の場合は数値(int)に変換します。

	int sf_to_double(char *in);
	小数点数字の文字列を小数点を含む数値にして返します。

	void sf_freeDB(int no, int DBcount, int maxcol);
	int no		ウインドウ番号
	int DBcount	データベースの現在の行数
	int maxcol	データベースの行の最大項目数
	テーブルのカラム項目と行が割り当てられたsplitDBbuff[][]をメモリから開放します。

	int sf_ggetDB(int no, int line, int col, int startline,char *s);
	int no		ウインドウ番号
	int line	DBグリッドの行番号
	int col		DBグリッドのカラム番号
	int startline	グリッドの１行目に読み込むDBの行番号
	char *s		DBから読み込んだ文字列
	グリッドセルと同じ位置にあるデータベース行とカラムの情報を読み取ります。

	int sf_gputDB(int no, int line, int col, int startline,char *s);
	int no		ウインドウ番号
	int line	DBグリッドの行番号
	int col		DBグリッドのカラム番号
	int startline	グリッドの１行目に書き込むDBの行番号
	char *s		DBに書き込む文字列
	グリッドセルと同じ位置にあるデータベース行カラムに情報を書き込みます。

	int sf_tgetDB(int no, int col, char *s);
	int no		ウインドウ番号
	int col		テキストボックスのカラム番号
	char *s		テキストボックスから読み込んだ文字列
	テキストボックスセルと同じ位置にあるデータベース行とカラムの情報を読み取ります。

	int sf_tputDB(int no, int col, char *s);
	int no		ウインドウ番号
	int col		テキストボックスのカラム番号
	char *s		DBに書き込む文字列
	テキストボックスセルと同じ位置にあるデータベース行カラムに情報を書き込みます。

	int sf_tgetDBall(int no);
	int no		ウインドウ番号
	テキストボックスをDBテキストボックス化する。

	int sf_assgetDB(int no,int line,int col, char *buff, int size);
	int no		ウインドウ番号
	int line	行番号
	int col		カラム番号
	char *buff	DBから読み込んだ文字列
	int size	ecpg で定義された内部配列のサイズ
	ECPGソースの内部で定義された配列をsf_DBgrid()で扱えるようsplitDBbuff[][]に展開します。
	同時に初期化も行います。
	FETCHされたDB行を扱うための関数です。DBからの読み取り専用の関数です。

	int sf_assputDB(int no,int col, char *buff, int size);
	int no		ウインドウ番号
	int col		カラム番号
	char *buff	DBに書き込む文字列
	int size	ecpg で定義された内部配列のサイズ
	テキストボックス用配列splitDBbuff[]に展開されたデータ(char*)をECPGで扱えるように元に戻すための準備をします。
	同時に初期化も行います。
	特にINSERT,UPDATEでDBへの書き込みを行う場合に使用します。


直接操作関数

	以下の2つの関数は定義ファイルを使用しないで直接テキストボックスやグリッドを作成する機能を持ちます。

	この関数は定義ファイルを使用しないでテキストボックスを作成します。
	aseのエディター画面からコマンドでＣ言語のソースファイルを生成し、
	その中身部分を定義ファイル呼出部分と置き換えて利用します。
	int MakeTextBox(int no,int fx,int fy,int xcol,int xrow,int *label_no,char **label_text,int *label_x,int *label_y,int *label_length,int *textbox_no,int *textbox_x,int *textbox_y,int *textbox_length,int *align,int *action,int *field,int *skipstep, int m)

	int no	ウインドウ番号	
	int fx	ウインドウＸ軸開始位置
	int fy	ウインドウＹ軸開始位置
	int xcol	ウインドウ横幅
	int xrow	ウインドウ高さ
	int *label_no	ラベル番号
	char **label_text	ラベル内文字列(ラベルテキストの配列へのポインタ)
	int *label_x	ラベルＸ軸開始位置
	int *label_y	ラベルＹ軸開始位置
	int *label_length	ラベルの長さ
	int *textbox_no		テキストボックス番号
	int *textbox_x	テキストボックスＸ軸開始位置
	int *textbox_y	テキストボックスＹ軸開始位置
	int *textbox_length	テキストボックスの長さ
	int *align	テキストボックス内の文字の位置属性(1.右 2.左 3.センター)
	int *action	テキストボックスの編集属性(0.編集可 1.編集不可)
	int *field	テキストボックスの属性
		TEXT.1 NUMERIC.2 BOOL.3 CURRENCY.4 DATE.5 SINGLE.6 DOUBLE.7 BYTE.8
	int *skipstep 	テキストボックス移動属性(0.SKIP 1.STEP)
	int m	テキストボックスの数

	この関数は定義ファイルを使用しないでグリッドを作成します。
	aseのエディター画面からコマンドでＣ言語のソースファイルを生成し、
	その中身部分を定義ファイル呼出部分と置き換えて利用します。
	int MakeWsubForm(int no, int xcol,int rows,int fx ,int fy,int grid_sx,int grid_sy,int grid_ex,int grid_ey,int *length,int *align,int *action,int *field,int *skipstep,char **grid_titles,int m)

	int no		ウインドウ番号
	int xcol	ウインドウ横幅
	int rows	ウインドウ高さ
	int fx 		ウインドウＸ軸開始位置
	int fy		ウインドウＹ軸開始位置
	int grid_sx		グリッドＸ軸開始位置
	int grid_sy		グリッドＹ軸開始位置
	int grid_ex		グリッドＸ軸終端位置
	int grid_ey		グリッドＹ軸終端位置
	int *length		グリッド各縦列の幅
	int *align		グリッド各縦列の文字の位置属性(1.右 2.左 3.センター)
	int *action		グリッド各縦列の編集属性(0.編集可 1.編集不可)
	int *field		グリッド各縦列の属性
		TEXT.1 NUMERIC.2 BOOL.3 CURRENCY.4 DATE.5 SINGLE.6 DOUBLE.7 BYTE.8
	int *skipstep		グリッド各縦列の移動属性(0.SKIP 1.STEP)
	char **grid_titles		グリッド各縦列内の文字列(テキストの配列へのポインタ)
	int m			グリッドの行数



7.その他の操作関数
サブフォームと直接的な関係のあるさまざまな処理を行う関数です。
char *addspace(int len, char *s);
文字列sにlenの長さだけスペースを追加します。
int compare(int c, char *p,char *s);
文字列pとsを比べて同じだったなら cと同じ数値を返します。
char *cutspace(char *s);
文字列sのなかにあるスペースを全て削除します。
char * cutspace_right(char *s)
文字列sの右側にあるスペースを全て削除します。
int dialogmsg(int x,int y,char *buff);
メッセージウインドウを表示しすぐ終了します。
int ifspace(int len,char *s);
文字列sの中のlenの長さだけスペースがあるかどうか調べます。無かった場合はゼロ、あればその数値を返します。
int popmsg(int x,int y,char *buff);
メッセージウインドウを表示し、一文字だけ入力を促します。’Y’が１、他は255を返します。
int errmsg(int x,int y,char *buff);
メッセージウインドウを表示しいずれかのキーで終了します。
char *sccep(char *buff);
文字列buffの中のスペースを左に寄せます。
char *slcep(char *buff);
文字列buffの名のスペースを右に寄せます。
char *srcep(char *buff);
文字列buffの中のスペースを両側に寄せます。
char *varprint(char *buff);
文字列buffの中の０〜９の数字だけに対応し、３桁ごとにカンマをふります。最大で２，１４７，４８３，６４７となります。
char *vs_ieee_c(WINDOW *vs,int x,int y,char *p,int N);
Curses関数mvwgetstr()を呼びます。

その他以下の漢字対応ライブラリがあります。入力時使用しています。
int jmvwgetnstr(WINDOW *win, int y, int x, unsigned char *str, int n, int wmode, int cmode);
WINDOW *win		セルから引き継いだウインドウ
Int y			セルウインドウ内開始Y位置
Int x			セルウインドウ内開始X位置
Unsigned char *str	セル内文字列
Int n			セル内編集対象文字数
Int wmode		挿入／上書モード
Int cmode		セルの型

この関数は全角文字入力が可能です。
セルの型が数値型と通貨型の場合、入力はセルの右端からとなります。この時Delete及びBackspaceキー
はセル内の文字列を全て消去します。
セルの型がテキスト型及び、日付型の場合は左から入力を始めます。この時Deleteは右側の文字を、Backspaceキー
は左側の文字を消去します。
テキスト型及び日付型文字列が入力されるとアンダーラインが引かれます。日付型文字列は特に定義していません。
Insertキーで挿入上書の切り替えが出来ます。

As for this function, the full size letter input is possible. 
A model of a cell becomes the input in the case of numerical value type and a currency type from the right-side end of a cell. Delete and a Backspace key erase all the character string in a cell then. 
A model of a cell begins the input with the left in the case of a text type and a date model. As for Delete, a Backspace key erases a letter of the left by a letter of the right side then. 
When a text type and date model character string are input, an underline is pulled. Model character string does not define it in particular on a date. 
A change of insertion overwrite is possible with an Insert key.
---------------------------------------------------------------------------------------
８．ライブラリファイルについて

サブフォームライブラリは以下のファイルにアーカイブされています。

8.  About a library file 

An assistant form library is archived by the following files.
---------------------------------------------------------------------------------------
Libsubform.a
内容：
wsubform.o	サブフォームアクセス関数
curlib01.o	サブフォーム関連関数
jmvwgetnstr.o	入力関数

ソースファイルは以下になります。
wsubform.c	サブフォームアクセス関数
wsubform.h	サブフォームヘッダファイル（サブフォーム本体のコンパイル時に必ず必要）
subform.h	サブフォームアクセス関数ヘッダファイル（サブフォームアプリケーション作成時必要）
curlib01.c	サブフォーム関連関数
jmvwgetnstr.c	入力関数
jmvwgetnstr.h	入力関数ヘッダファイル
これらはMakefile が付属していますので、コンパイル時参考にしてください。

＜注意事項＞
１）テキストボックス用アクセス関数は関数内でwrefresh()を行っていません。
２）セル内は全てスペースでおおわれているため、専用アクセス関数以外で操作する場合はスペース操作を追加しなければなりません。
３）テキストボックスはリスト連鎖順にカーソルが移動を行うため、移動順を変えたい場合は定義ファイルで行ってください。
４）画面定義ファイルに矛盾のある設定を行うとプログラムが異常終了する場合があります。
５）パネル上のテキストボックスは移動順を定義ファイルで設定しています。そのため現在の定義を変更するとカーソル移動に矛盾が生じる可能性があるので注意してください。
６）フォームウインドウの大きさがKterm画面の大きさを越えた場合、エラーメッセージを表示しexit(1)で終了します。
７）グリッドエリアのすぐ上の行は項目名（タイトル）用になっていますので、テキストボックス等を定義する場合１行あけてください。
８）aseでテキストボックスを連続して横に定義する場合、次のテキストボックスとの間に１カラム以上の間隔が必要になります。
９)	テキストボックスまたはグリッドのセルでBSキーにて^?の文字が入力される場合はTERMINFOファイルの中にあるBSキーの設定が^Hになっています。^?に直してTICコマンドでコンパイルする必要があります。(サンプルのTERMCAPファイルを付属してあります。)
１０)本ライブラリで日本語を扱う場合は必ずEUCを使用してください。UTF-8等のマルチバイト文字を扱うことは出来ません。これはテキストボックス及びグリッド内セルが文字数に対応したASCIIスペース文字で覆う必要があるからです。

<Instructions> 
1.     An access function for text box does not perform wrefresh() in a function. 
2.     All|all of the cell must add space operation so that it is covered in space when they operate it other than an exclusive access function. 
3.     Please perform text box with a definition file so that a cursor moves to list chain order when I want to change movement order. 
4.     There is the case that a program is terminated abnormally when I set it with contradiction to filing it a screen definition. 
5.     Text box on a panel sets movement order with a definition file. Because contradiction may occur for cursor movement when I change a definition as of that purpose, please be careful. 
6.     Size of a form window displays a case beyond size of a Kterm screen, error message and is finished in exit(1). 
7.     Because I become it for the item names (a title), in the line right on a grid area, one line please be open when I define text box. 
8.     When I define text box in ase aside in succession, distance more than one column is necessary between the next text box. 
9.     When a letter of ^? is input with a BS key in text box or a cell of a grid, setting of the BS key which there is in a TERMINFO file becomes ^H. I get over in ^? and have to compile it by a TIC command. (It is attached with a TERMCAP file of a sample.)
---------------------------------------------------------------------------------------
９．サブフォームのサンプル
サブフォームは以下のように使用します。

#include "wsubform.h" //サブフォーム専用ヘッダファイルをインクルードする。
#include "subform.h" //サブフォームアクセス関数のプロトタイプを定義したインクルードファイル。

#define Textbox	1
#define Grid	2
#define Panel	3

#define Tret	199
#define Gret	299
#define Pret	399

extern int wmode;
extern char gridtitles[MAX_POS][MAX_LEN];

extern TextBox	 *begin;
extern TextBox	 *tp;

typedef struct stat Dir;
static Dir dirptr;
static Dir  *fileptr = &dirptr;

char tmp[256];

int subform(void)
{
	int i,j,k;
	int ret;
	char f[128];
	int xcol,rows;
	int maxtext;
	char s[256];

#ifdef PANELS
	strcpy(f,"_subpanels.def");
#else
	strcpy(f,"_subform.def");
#endif

	initscr();

	xcol = COLS;
	rows = LINES;

	cbreak();
	noecho();
	keypad(stdscr, TRUE);
	meta(stdscr, TRUE);

	if(stat(f,fileptr) != 0)
	{
		echo();
		endwin();
		printf("canot find %s\n",f);
		exit(0);
	}

	xcol = wsubform(0,xcol,rows,0,2,f);

#ifdef PANELS
	maxtext = panels(0,xcol,rows,2,f);
#else
	maxtext = textbox(0,2,f);
#endif

	wrefresh(xt[0].form);

	for(i=0;i<MAX_POS;i++)
		memset(gridtitles[i],'\0',MAX_LEN);

#ifdef PANELS
	xcol = wsubform(2,xcol,rows,0,46,"_panel_footer.def");
#else
	xcol = wsubform(2,xcol,rows,0,46,"_footer.def");
#endif
	wrefresh(xt[2].form);

	for(i=0;i<MAX_POS;i++)
		memset(gridtitles[i],'\0',MAX_LEN);

	tp = begin->next;

	for(i=0;i<maxtext;i++)
	{
		sprintf(s,"%d",i+1);
		sf_tput(0,i,s);
		wrefresh(ft[0].pt[k].panel);
		wrefresh(ft[0].pos[i].vs);
		if(tp->next != (TextBox *)NULL)
		{
			tp = tp->next;
		}
	}

	for(i=0,k=1;i<ft[0].lcol;i++)
	{
		for(j=0;j<(ft[0].ey-ft[0].sy)+1;j++)
		{
			sprintf(s,"%d",k);
			sf_gput(0,i,j,s);
			k++;
		}
	}

	xcol = wsubform(1,xcol,rows,0,0,"_header.def");
	sprintf(ft[1].cp[0][0].s,"%s","Sample screen for Subform Library v.2.2");
	mvwprintw(ft[1].st[0][0].vs,0,1,"%s",ft[1].cp[0][0].s);
	wrefresh(ft[1].st[0][0].vs);
	wrefresh(xt[1].form);

	ft[0].pos[0].col = 0;
	ft[0].pos[0].line = 0;
	ft[0].st[0][0].col = 0;
	ft[0].st[0][0].line = 0;

	ret = Gret;
	tp = begin->next;

	while(TRUE)
	{
		if(ret == Tret || ret == Pret)　//リターンコードでグリッドかテキストボックスを切り替える。
			ret = grid(0,maxtext,xcol);
		else
#ifdef PANELS
			ret = paneltext(0,maxtext, xcol);
#else
			ret = formtext(0,maxtext, xcol);
#endif
		switch(ret)
		{
		case -1:
			echo();
			endwin();
			exit(0);
			break;

	//for textbox
		case 100: //ESC　キーでプログラムを終了することにする。
			if(popmsg(2+8,(LINES/2)-4,"Exit textbox area in Subform?") == 1)
				goto end;
			ret = Gret;  //２つのウインドウ関数を同時に利用するためリターンコードをセットしておく。
			break;
		case 101: //F1
			ret = Gret;
			break;
		case 102: //F2
			ret = Gret;
			break;
		case 103: //F3　テキストボックス内の文字を左詰にする。
			i = sf_status(0,Textbox,'n');
			sprintf(tmp,"%s",tp->s);
			sf_tcep(0,i,2,tmp);
			ret = Gret;
			break;
		case 104: //F4　999999という数字を999,999としてテキストボックスに書き込む。
			i = sf_status(0,Textbox,'n');
			sf_tvarprint(0,i,"999999");
			ret = Gret;
			break;
		case 105: //F5　テキストボックスに”Put”と文字を書き込む。
			i = sf_status(0,Textbox,'n');
			wrefresh(ft[0].pos[i].vs);
			sf_tput(0,i,"Put");
			ret = Gret;
			break;
		case 106: //F6　テキストボックス内の文字を読み込み、メッセージウインドウに表示する。
			i = sf_status(0,Textbox,'n');
			sf_tget(0,i,tmp);
			popmsg(2+8,(LINES/2)-4,tmp);
			ret = Gret;
			break;
		case 107: //F7　テキストボックスを移動する。
			sf_tlocate(0,7);
			ret = Gret;
			break;
		case 108: //F8　テキストボックスセルの属性をメッセージウインドウに表示。
			sprintf(tmp,"w=%d,x=%d,y=%d,X=%d,n=%d,l=%d,c=%d,a=%d,A=%d,f=%d,s=%d",
					sf_status(0,Textbox,'w'),sf_status(0,Textbox,'x'),sf_status(0,Textbox,'y'),sf_status(0,Textbox,'X'),
					sf_status(0,Textbox,'n'),sf_status(0,Textbox,'l'),sf_status(0,Textbox,'c'),sf_status(0,Textbox,'a'),
					sf_status(0,Textbox,'a'),sf_status(0,Textbox,'f'),sf_status(0,Textbox,'s'));
			popmsg(2+8,(LINES/2)-4,tmp);
			ret = Gret;
			break;
		case 109: //F9　全てのテキストボックス内文字を右に寄せる。
			i = sf_status(0,Textbox,'n');
			sprintf(tmp,"%s",tp->s);
			sf_tcep(0,i,1,tmp);
			wrefresh(ft[0].pos[i].vs);
			tp = begin->next;
			for(i=0;i<maxtext;i++)
			{
				wrefresh(ft[0].pos[i].vs);
				if(tp->next != (TextBox *)NULL)
				{
					tp = tp->next;
				}
			}
			ret = Gret;
			break;
		case 110: //F10　全てのテキストボックスに番号を書き込みセンター寄せする。
			tp = begin->next;
			for(i=0;i<maxtext;i++)
			{
				sprintf(s,"%d",i+1);
				sf_tcep(0,i,3,s);
				wrefresh(ft[0].pos[i].vs);
				if(tp->next != (TextBox *)NULL)
				{
					tp = tp->next;
				}
			}
			ret = Gret;
			break;
		case 111: //F11　全てのテキストボックスに番号を書き込む。
			tp = begin->next;
			for(i=0;i<maxtext;i++)
			{
				sprintf(s,"%d",i+1);
				sf_tput(0,i,s);
				wrefresh(ft[0].pos[i].vs);
				if(tp->next != (TextBox *)NULL)
				{
					tp = tp->next;
				}
			}
			ret = Gret;
			break;

	//for grid
		case 200: //ESC　キーでプログラムを終了する。
			if(popmsg(2+8,(LINES/2)-4,"Exit grid area in Subform?") == 1)
				goto end;
			ret = Pret;
			break;
		case 201: //F1
			ret = Pret;
			break;
		case 202: //F2
			ret = Pret;
			break;
		case 203: //F3　現在のセルの位置を調べた後、セル内文字を読みとりセンター詰めで書き込む。
			i = sf_status(0,Grid,'X');
			j = sf_status(0,Grid,'Y');
			sf_gget(0,i,j,tmp);
			sf_gcep(0,i,2,tmp);
			ret = Pret;
			break;
		case 204: //F4　現在のセルの位置を調べた後、数値“999999”を“999,999”で書き込む。
			i = sf_status(0,Grid,'c');
			j = sf_status(0,Grid,'Y');
			sf_gvarprint(0,i,j,"999999");
			ret = Pret;
			break;
		case 205: //F5
			ret = Pret;
			break;
		case 206: //F6　セル内文字を読みとりメッセージウインドウに表示する。
			i = sf_status(0,Grid,'X');
			j = sf_status(0,Grid,'Y');
			sf_gget(0,i,j,tmp);
			popmsg(2+8,(LINES/2)-4,tmp);
			ret = Pret;
			break;
		case 207: //F7　現在のセルの位置を調べた後、セルカーソルの移動場所を選択する。最後にNUMERIC型のセルに移動
			i = sf_status(0,Grid,'X');
			j = sf_status(0,Grid,'Y');
			sprintf(tmp,"i=%d/j=%d",i,j);
			if(popmsg(2+8,(LINES/2)-4,tmp)== 1)
				sf_glocate(0,8,32);
			i = sf_status(0,Grid,'f');
			sprintf(tmp,"f=%d",i);
			popmsg(2+8,(LINES/2)-4,tmp);
			if(sf_status(0,Grid,'f') == 4)
			{
				sf_glocate(0,8,1);
			}
			ret = Pret;
			break;
		case 208: //F8　テキストボックスセルの属性をメッセージウインドウに表示。
			sprintf(tmp,"w=%d,x=%d,y=%d,X=%d,n=%d,l=%d,c=%d,a=%d,A=%d,f=%d,s=%d",
					sf_status(0,Grid,'w'),sf_status(0,Grid,'x'),sf_status(0,Grid,'y'),sf_status(0,Grid,'X'),
					sf_status(0,Grid,'n'),sf_status(0,Grid,'l'),sf_status(0,Grid,'c'),sf_status(0,Grid,'a'),
					sf_status(0,Grid,'a'),sf_status(0,Grid,'f'),sf_status(0,Grid,'s'));
			popmsg(2+8,(LINES/2)-4,tmp);
			ret = Pret;
			break;
		case 209: //F9　カンマ付き１１桁数値を全てのセルに書き込む。
			for(i=0,k=1;i<ft[0].lcol;i++)
			{
				for(j=0;j<(ft[0].ey-ft[0].sy)+1;j++)
				{
					sprintf(s,"%ld",33335 * 60000);
					sf_gvarprint(0,i,j,s);
				}
			}
			ret = Pret;
			break;
		case 210: //F10　全てのセルに番号を書き込む。
			for(i=0,k=1;i<ft[0].lcol;i++)
			{
				for(j=0;j<(ft[0].ey-ft[0].sy)+1;j++)
				{
					sprintf(s,"%d",k);
					sf_gput(0,i,j,s);
					k++;
				}
			}
			ret = Pret;
			break;
		case 211: //F11　セルに番号を書き込む。
			for(j=0,k=1;j<(ft[0].ey-ft[0].sy)+1;j++)
			{
				for(i=0;i<ft[0].lcol;i++)
				{
					sprintf(s,"%d",k);
					sf_gput(0,i,j,s);
					k++;
				}
			}
			ret = Pret;
			break;

	//for panels
		case 300: //ESC　キーでプログラムを終了する。
			if(popmsg(2+8,(LINES/2)-4,"Exit panels area in Subform?") == 1)
				goto end;
			ret = Gret;
			break;
		case 301: //F1
			ret = Gret;
			break;
		case 302: //F2
			ret = Gret;
			break;
		case 303: //F3
			ret = Gret;
			break;
		case 304: //F4
			ret = Gret;
			break;
		case 305: //F5
			ret = Gret;
			break;
		case 306: //F6
			ret = Gret;
			break;
		case 307: //F7
			sf_tlocate(0,12);
			ret = Gret;
			break;
		case 308: //F8
			ret = Gret;
			break;
		case 309: //F9　パネル内テキストボックスを調査し、文字を右寄せする。
			i = sf_status(0,Panel,'n');
			sprintf(tmp,"%s",tp->s);
			sf_tcep(0,i,1,tmp);
			ret = Gret;
			break;
		case 310: //F10　パネル内テキストボックスに番号をふり、センター寄せする。
			tp = begin->next;
			for(i=0;i<maxtext;i++)
			{
				sprintf(s,"%d",i+1);
				sf_tcep(0,i,3,s);
				wrefresh(ft[0].pos[i].vs);
				if(tp->next != (TextBox *)NULL)
				{
					tp = tp->next;
				}
			}
			ret = Gret;
			break;
		case 311: //F11　パネル内テキストボックスに番号を書き込む。
			tp = begin->next;
			for(i=0;i<maxtext;i++)
			{
				sprintf(s,"%d",i+1);
				sf_tput(0,i,s);
				wrefresh(ft[0].pos[i].vs);
				if(tp->next != (TextBox *)NULL)
				{
					tp = tp->next;
				}
			}
			ret = Gret;
			break;

		default:
			break;
		}
	}

end:
	echo();
	endwin();
}

int main(void)
{
	subform();
}

１０.sf_DBgrid()を使用したサンプル
aseのECPGソース生成機能を利用するとsf_DBgrid()を使用したデータベースアプリケーションを開発出来ます。
生成するソースファイルにはFETCHカーソル、INSERT,UPDATE,DELETEの実用的ソースですので、
少々の変更で大規模アプリケーション作成支援に利用出来ます。

int subform(void)
{
	int i,j,k;
	int ret;
	char f[256];
	int xcol,rows;
	int maxtext;
	char s[MAX_STR];

	int xcol2;
	int maxcol;
	int startline;
	
	int line;
	char key1[MAX_STR];
	char key2[MAX_STR];
	char key3[MAX_STR];

	sprintf(f,"%s","_apschtbl.def");
	initscr();

	xcol = COLS;
	rows = LINES;

	cbreak();
	noecho();
	keypad(stdscr, TRUE);
	meta(stdscr, TRUE);

	if(stat(f,fileptr) != 0)
	{
		popmsg((COLS/2)-24,(LINES/2)-4,"メイングリッドフォーム定義ファイルがありあません。");
		echo();
		endwin();
		exit(0);
	}
	if(stat("_inputwin2.def",fileptr) != 0)
	{
		popmsg((COLS/2)-24,(LINES/2)-4,"入力用テキストボックスフォーム定義ファイルがありあません。");
		echo();
		endwin();
		exit(0);
	}
	if(stat("_header.def",fileptr) != 0)
	{
		popmsg((COLS/2)-24,(LINES/2)-4,"ヘッダータイトル用グリッドフォーム定義ファイルがありあません。");
		echo();
		endwin();
		exit(0);
	}
	if(stat("_footer.def",fileptr) != 0)
	{
		popmsg((COLS/2)-24,(LINES/2)-4,"ファンクションキー用グリッドフォーム定義ファイルがありあません。");
		echo();
		endwin();
		exit(0);
	}
	xcol = wsubform(3,140,24,1,19,"_inputwin.def");	//入力用テキストボックスセル定義ファイルを開く。
	maxcol = wsubform(0,140,44,1,2,f);	//メイングリッドフォーム定義ファイルを開く。
	maxtext = textbox(3,1,19,"_inputwin.def");	//テキストボックスセルを展開する。

	wrefresh(xt[0].form);

	for(i=0;i<MAX_POS;i++)
		memset(gridtitles[i],'\0',MAX_LEN);	//グリッドタイトルを初期化する。

	xcol = wsubform(2,xcol,rows,0,43,"_footer.def");	//フッターウインドウを作成する。xcol はフォームウインドウの幅
	sf_gcep(2,0,0,3,"入力画面へ");	//
	sf_gcep(2,12,0,3,"ESC終了");	//
	wrefresh(xt[2].form);

	xcol = wsubform(1,xcol,rows,0,0,"_header.def");	//ヘッダーウインドウを作成する。
	sf_gcep(1,0,0,1,"v1.0.3");
	sprintf(ft[1].cp[0][0].s,"%s","APscheduler");
	mvwprintw(ft[1].st[0][0].vs,0,1,"%s",ft[1].cp[0][0].s);
	sf_wrefreshcell(1,0,0);
	sf_wrefreshform(1);

	sf_startcell(0);	//グリッドのセルカーソルを左上隅に配置する。

	ret = Gret;

	while(1)
	{
		startline = sf_getstartline(0);	//DBgrid()の持っているスクロールに必要なＤＢグリッドの画面初期行の位置情報。
		if(schdytbl_disp(0,startline,maxcol) == -1)	//*splitDBbuff[][]をグリッドに書き込み表示する。
		{
			popmsg(12,12,"schtbl_disp():error");
		}
		ret = DBgrid(0,maxtext,xcol,0,DBcount,maxcol);	//データベース連結用グリッド。*splitDBbuff[][]を表示する。
		switch(ret)
		{
		case -1:
			echo();
			endwin();
			exit(0);
			break;

		//for grid
		case 200: //ESC　キーでプログラムを終了する。
			if(popmsg((COLS/2)-24,(LINES/2)-4,"Exit grid area in Subform?") == 1)
				goto end;
			ret = Pret;
			break;
		case 201: //F1
		//DBへの入力用ウインドウの作成
			line = sf_status(0,Grid,'D');
			inputwin_write(3,0,line,maxcol);	//入力用ウインドウを表示する。maxcol はテキストボックスセルの調整用に利用可
			sf_gcep(2,0,0,3,"戻る");
			sf_gcep(2,4,0,3,"更新");
			sf_gcep(2,5,0,3,"追加");
			sf_gcep(2,6,0,3,"削除 n+d+t");
			sf_gcep(2,7,0,3,"削除 n+d");
			sf_gcep(2,8,0,3,"削除 < d");
			while(1)
			{
				ret = formtext(3,maxtext, 140);	//入力用ウインドウからの操作の受付(F1 - F12 + ESC)
				switch(ret)
				{
				case -1:
					echo();
					endwin();
					exit(0);
					break;
				case 100:
					if(popmsg((COLS/2)-24,(LINES/2)-4,"終了します。") == 1)
						goto end;
					break;
				case 101:
					goto mainwin;
					break;
				case 105:
					//全てのテキストボックスから必要な項目をmalloc()したsolitDBbuff[]に格納する。
					//ECPG側でUPDATEを行うassputDB()を使用後にsplitDBbuff[]は自動的に開放される。
					sf_tgetDBall(3);
					sprintf(key1,"%s",ft[0].splitDBbuff[line][0]);
					sprintf(key2,"%s",ft[0].splitDBbuff[line][1]);
					if(Update_schtbl(0,key1,key2,sqlcode,line) == -1)
					{
						popmsg((COLS/2)-24,(LINES/2)-4,"データベースが更新出来ません。");
					}
					goto mainwin;
					break;
				case 106:
					//全てのテキストボックスから必要な項目をmalloc()したsolitDBbuff[]に格納する。
					//ECPG側でINSERTを行うassputDB()を使用後にsplitDBbuff[]は自動的に開放される。
					sf_tgetDBall(3);
					sprintf(key1,"%s",ft[0].splitDBbuff[line][0]);
					sprintf(key2,"%s",ft[0].splitDBbuff[line][1]);
					if(Insert_schtbl(0) == -1)
					{
						popmsg((COLS/2)-24,(LINES/2)-4,"データベースが追加出来ません。");
					}
					goto mainwin;
					break;
				case 107:
					if(popmsg((COLS/2)-24,(LINES/2)-4,"名前と日付と実行時間でデータを削除しますか？") == 1)
					{
						sprintf(key1,"%s",ft[0].splitDBbuff[line][0]);
						sprintf(key2,"%s",ft[0].splitDBbuff[line][1]);
						if(Delete_schtbl(key1,key2,sqlcode) == -1)
						{
							popmsg((COLS/2)-24,(LINES/2)-4,"データベースから削除出来ません。");
						}
					}
					else
					{
						goto mainwin;
					}
					goto cleardisp;
					break;
				case 108:
					if(popmsg((COLS/2)-24,(LINES/2)-4,"名前と日付でデータを削除しますか？") == 1)
					{
						sprintf(key1,"%s",ft[0].splitDBbuff[line][0]);
						sprintf(key2,"%s",ft[0].splitDBbuff[line][1]);
						if(Delete_schtbl(key1,key2,sqlcode) == -1)
						{
							popmsg((COLS/2)-24,(LINES/2)-4,"データベースから削除出来ません。");
						}
					}
					else
					{
						goto mainwin;
					}
					goto cleardisp;
					break;
				case 109:
					sf_tget(3,1,s);
					sprintf(tmp,"%s の日付以前の全てのデータを削除しますか？",s);
					if(popmsg((COLS/2)-24,(LINES/2)-4,tmp) == 1)
					{
						sprintf(key1,"%s",ft[0].splitDBbuff[line][1]);
						if(Delete_schtbl(key1,key2,sqlcode) == -1)
						{
							popmsg((COLS/2)-24,(LINES/2)-4,"データベースから削除出来ません。");
						}
					}
					else
					{
						goto mainwin;
					}
					goto cleardisp;
					break;
				}
			}
			cleardisp:
			sf_initgridcell(0);	//全てのグリッドセルをスペースで初期化します。
			mainwin:
			sf_gcep(2,0,0,3,"入力画面へ");
			sf_gcep(2,4,0,3,"          ");
			sf_gcep(2,5,0,3,"          ");
			sf_gcep(2,6,0,3,"          ");
			sf_gcep(2,7,0,3,"          ");
			sf_gcep(2,8,0,3,"          ");
			ret = Pret;
			break;
		case 202: //F2
			ret = Pret;
			break;
		case 203: //F3
			ret = Pret;
			break;
		case 204: //F4
			ret = Pret;
			break;
		case 205: //F5
			ret = Pret;
			break;
		case 206: //F6
			ret = Pret;
			break;
		case 207: //F7
			ret = Pret;
			break;
		case 208: //F8
			ret = Pret;
			break;
		case 209: //F9
			ret = Pret;
			break;
		case 210: //F10
			ret = Pret;
			break;
		case 211: //F11
			ret = Pret;
			break;
		case 299: //F12
			ret = Pret;
			break;

		default:
			break;
		}
		sf_freeDB(0,DBcount,maxcol);	//splitDBbuff[][]を開放する。
	}

end:
	echo();
	endwin();
}

int main(void)
{
	subform();
}


