前 言
当前windods 上的编程工具日新月异,推陈出新;然而因unix运用的局限性,其编程工
具十分贫乏。在unix上要做画面、菜单、查询、输入,编程者往往要从底层入手,重复劳动
,效率极低。笔者为了解决这个问题而尽点力,将本系统介绍给您,如您能读完本文,收获
一定不少。
编者:王光红
email: [email protected]
[email protected]
软件下载:
http://www.csdn.net/cnshare/soft/16/16735.shtm
http://www.ccrun.com/program/down.asp?id=10
一。系统介简
(一)实现功能∶
用于unix上做画面、菜单、查询、输入、修改;可操作数据库。
(二)设计思路∶
将人机对话,可分为基本的输入与输出两大类,在此前提下,为了不同的需要把域分作
多种类型;对涉及数据库的域指明有关的表名、字段名,以进行数据库的读写。将这些
不同功能的域有机的组合在一个form中,来实现一个功能模块。将form编号,按一定的
结构以二进制的形式存入文件,在使用时,系统按编号读入form的数据,按步实现预定
的功能。
(三)软件环境∶
1.操作系统sco unix openserver 5.0、sco unix openserver 3.0、sco unix 3.0。
2.编程语言 c、informix/esql。
说明∶笔者的工作条件仅限于以上环境,如能提供其他的unix、sql数据库(如oracle、
sybase等), 系统只需略加修改。
二。系统的文件与库
(一)集成开发器执行程序∶
/usr/wform/bin/mkform form的定制工具
/usr/wform/bin/netform form的定制工具(网络版)
/usr/wform/bin/net_server form的数据服务器
(二)配置文件∶
form的配置文件的路径由环境变量configpath指定,缺省为/usr/wform/etc/form.cfg
文本文件
它规定unix编辑器、form参数文件的路径;菜单的格式;存储变量的多少;
特殊键的键值。
(三)form参数文件∶
form参数文件的路径在配置文件中声明。
二进制文件
存放dialog结构form的数据,系统读此文件,按步执行。
mkform(netform)的画面的参数文件是 /usr/wform/etc/form.bin.sys
(四)帮助信息文件:
帮助信息文件的路径由环境变量msgpath指定,缺省为 /usr/wform/etc/form_msg.dat
文本文件
(五)系统说明文件:
系统说明文件 /usr/wform/etc/readme.frm
(六)程序库:
/usr/wform/lib/libsetform.a 在sco unix openserver 5.0上生成。
/usr/wform/lib/libnetform.a 在sco unix openserver 5.0上生成(网络版)。
(七)演示例程∶
1.两个form参数文件∶
/usr/wform/data/demo.form
/usr/wform/data/test.form
2.菜单式演示程序∶
/usr/wform/menu/menu
/usr/wform/menu/menu.ec
/usr/wform/menu/print.c
/usr/wform/menu/errhandle.c
/usr/wform/menu/makefile
/usr/wform/menu/mknet 链接libnetform.a的makefile
3.交易式演示程序∶
/usr/wform/trade/trade
/usr/wform/trade/trade.ec
/usr/wform/trade/makefile
/usr/wform/trade/mknet 链接libnetform.a的makefile
4.两个数据库∶
/usr/wform/demo.exp
/usr/wform/test.exp
说明:演示程序menu、trade使用的数据库是test,form参数文件是test.form。
三。系统的基本概念及用途
(一)form的结构:
typedef struct _item_st_ {
char flag; //数据类型(或标志)
char len; //数据长度
char seat_y; //纵坐标
short seat_x; //横坐标
char fun; //form中嵌入的函数指针编号
char field[41]; //复合域
}item;
typedef struct tagofdialog {
unsigned long form_id; //交易号
unsigned long link_form; //连接交易
char mode; //驱动方式
char key; //索引项
short num; //以下item的个数
item *f; //form中域的结构
}dialog;
(二)基本概念及用途
1.[交易号] (dialog.form_id)
form的编号,以此为索引。
2.[连接交易] (dialog.link_form)
form结束后调用的另一个form的交易号,此值=0,则不调用。
3.[驱动方式] (dialog.mode)
以确定form的性质。
m∶菜单
p∶打印
b∶浏览
e∶结束清域
d∶结束删除window
s∶屏幕滚动
c∶综合查询
4.[索引项] (dialog.key)
指定查询条件的字段数, 其值是对应于[序],序号小于等于该值的字段为查询条
件。 仅对查询类form有效。
以下为form中域的结构(dialog.f),域的数量可变。
5.[类型] (dialog.item->flag)
标志符 用 途 数据类型 sqldatetype
(1) 输入输出项
c、c 普通字符串 char char
h 汉字 char char
r 日期(对字符串进行日期合法性检查) char char
a 帐号(对字符串有复制功能) char char
p 密码(不回显) char char
g 选项 char char
f 帮助项 char char
d、d 日期(自1899.12.31起至今的天数) long char
m、m 金额 double money, float
n、n 数值 long intger, smallint
以上大写的字符是输入项、小写的字符是输出项。
可在复合区指明表名和字段名, 形如table.field
(2) 杂项
t 提示
f 菜单格式
b 值域检查(对上一项值进行检查)
b 数据库(指定远程数据库),形式[email protected]
l 标题
i 菜单条目
x 执行 sql语句
- 连接符
| 划线符
# 画背景符
w
当无需指定表和字段时, 复合区前四位存入坐标, 后面的字符可作标题
类型为 'l', 坐标=0, 则作表头用。
6.[长度]
对输出输出项而言是数据长度;对杂项'|','#'是代表颜色。
字符串数据长度<=128。
金额的长度 <=16∶长度是小数点前和小数点后位数总数,小数点后定为二位。
例∶长度=14,
小数点前12位,小数点后2位。
金额的长度 >=20∶
个位是小数点后位数, 个位前是小数点前的位数。
例∶长度=125,
小数点前12位,小数点后5位。
金额的长度 >=17and<20非法.
7.[坐标]
对一般的form后二位是横坐标。前面是纵坐标;纵坐标<24。
对于浏览器的坐标有特别规定:
当坐标值大于2499∶ 后三位是横坐标,前面是纵坐标。
横坐标的最大值512.
例∶坐标值5150表示∶ 横坐标=150,纵坐标=5。
8.[嵌入函数]
form中嵌入的函数指针编号,当程序执行完该域后,调用一个特定的函数,函数
指针须初始化符值。
9.[复合域]
是多用途的域,可用作写标题、sql语句、数据库表名、字段名等。
四。实例讲解(略)
五。本系统的函数及运用
(一) 系统的定义∶
宏及form结构 wform.h
变量定义 wvai.h
嵌套函数指针 fun.h
(二) 系统函数的调用:
1. 菜单的调用: int setmenu(long id)
id是主菜单的编号。
返回值是反映程序执行到菜单第几层的第几项,祥见菜单制作.
2. form的调用: int setupform(long id, short wincode)
id是form的编号。
wincode 是窗口的编号(0-9).
如同时用多个窗口,窗口编号须不同,否则会覆盖。
返回值:
0 取消 (即按[escape]退出)
1 正常 (即按[enter] 退出)
>1 按热键或自定义键返回
对某些特殊键和自定义键,即退出form,返回值如下∶
键 名 返回码
借方键 debit
贷方键 credit
向前键 previoes
向后键 next
热键 hotkey
发送键 finishkey
自定义键 键值+2000
3. 其他函数∶
(1) int msgbox(char type, const char *fmt, .../* args */);
用途∶信息提示。信息长度小于80在屏幕底线显示,否则在当前光标下组成box.
type∶msgerr(0) 错误 msgprom(1) 提示 msgwait(2) 等待 msgwarn(3) 警告
用法同printf函数。
(2) void setformpara(short mode, short para);
用途∶设form参数。
mode:
宏 数值 作 用
winframe 0 para:1 窗口画框 0 窗口无框 缺省值 0
f_color 1 设定前景色 缺省值color_white(白色)
b_color 2 设定背景色 缺省值color_black(黑色)
具体色彩参数见 <tinfo.h>
displaymode 3 para:1 预显示原值
0 不显示
缺省值 0
fieldbound 4 para:1 对输入项划定界符 "[......]"
0 不划
缺省值 1
displaybold 5 para:1 显示的字符为高亮
缺省值 0
enterdefault 6 para:1 输入项只按[enter],复制成原值。
缺省值 0
linetype 7 para:1 双线
0 单线
缺省值 1
patternfront 8 para:1 运行菜单时,输入的字符与菜单选项的
第一个字符相同,能选中并自动回车。
0 不能自动回车。
缺省值 1
(3) void touchform(short wincode)
用途∶重显被覆盖的form.
(4) int sqlmsg(short sqlcode)
用途∶能提供错误信息,反映程序执行到何处(那个文件的那一行)。
通常用于sql执行错误返回。
(5) void deldlgwin(short wincode)
用途∶删除form.
(6) int skipdomain(short step)
用途∶跳过若干个域(step)。用于嵌入函数。
(7) void rfmtdate(date i_date, char *fmt, char *result)
用途∶将informix中的date转成char.
例∶
1899.12.31至1999.12.4的天数是36132.
rfmtdate(36132, "mm-dd-yyyy", result);
result="12-04-1998"
rfmtdate(36132, "mm-dd-yy", result);
result="12-04-98"
rfmtdate(36132, "日期: yyyy年mm月dd日", result);
result="日期: 一九九八年十二月四日".
(8) void rfmtdouble(double money, char *fmt, char *result)
用途∶将double转成char.
例∶
double a=-9030236.035;
rfmtdate(a, "---,---,--9.999", result);
result=" -9,030,236.035"
(9) char *doubletostr(double money, const char *fmt);
用途∶将double转成char返回(char *).
(10) void printform(short wincode, short lin, short col, char *fmt, ...);
用途∶向form输送字符.
(11) int runfunction(int (*fun)(), char *msg);
用途∶运行函数fun时,在屏幕底显示信息msg,隔一秒钟跳动字符 '>'。
例∶
见menu.ec的280行。
runfunction(deletedetail, "正在清理数据");
如果函数deletedetail()不在menu.ec中,
必须声明extern int deletedetail();
(12) int callfunction(int (*fun)(), char *msg);
用途∶同runfunction(),不跳动字符。
(13) char *pntname();
用途∶获得打印输出的设备名。
在主控台上得到"/dev/lp0",在终端上得到相应的终端号"/dev/tty???"
(14) void draws(window *w, int b_y, int b_x, int e_y, int e_x)
用途∶在指定的窗口画线。
起点坐标(b_x, b_y) 终点坐标(e_x, e_y)
b_x=e_x 画垂直线。
b_y=e_y 画水平线。
b_x!=e_x b_y!=e_y 画矩形。
(15) int formpath(char *path);
用途∶
调用该函数设置form的参数的路径, 确省路径在配置文件中设定。
(16) insetfun(n, fun);
用途∶
函数指针初始化。
n 是函数指针的编号,fun是函数名.
(三) 关于嵌入函数的使用:
作用∶当form执行到某一域时调用的函数.
我们通过menu.ec这个程序来说明嵌入函数的运用。
****注意∶以下是test.form中的 110号form.
[命令] g [交易号] 110 [连接交易] 0 [驱动方式] e [索引项] 0
[序] [类型][长度][坐标][嵌入函数] [ 复 合 域 ]
0 c 3 1237 0 bank.exchno
1 c 20 1337 0 bank.officename
2 r 8 1537 1
3 t 0 0 0 日期须本日前一星期内
4 a 7 1737 0
5 m 10 1937 0
6 b 0 0 0
7 i 0 0 0 62.50
8 i 0 0 0 999999.99
9 c 1 2137 0
10 b 0 0 0
11 i 0 0 0 [1,4]
12 l 0 1226 2 受 理 行
13 l 0 1326 0 行 名∶
14 l 0 1526 0 凭证日期
15 l 0 1726 0 号 码
16 l 0 1926 0 金 额
17 l 0 2126 0 联 次
18 l 0 2224 0
第 2、12域有嵌入函数∶1、2是函数指针的编号,分别代表函数checkdate()、pattern().
函数指针初始化∶
insetfun(1, checkdate);
insetfun(2, pattern);
见menu.ec中第217、218行。
当程序执行完第 2域(即输入日期),系统就调用函数checkdate(),以检查日期
是否本日至前一星期内,如日期正确函数返回 0,程序继续执行; 如日期错误函
数返回-1, 程序仍停止在第 2域。如函数返回-3程序退回到第 0域。
设sn为程序执行的序号.
ret=fun[n]();
sn +=ret;
你可根据需要函数返回值,如返回值为2,就会跳过2个域。
当程序执行完第11域,系统就调用函数pattern(),进行凭证配对。
(四)关于form的值∶
1.类型.
类 型 变量名 宿主变量名 form编辑器的代名
字符(char) chars(n) $infstring[n] $cn
整型(long) number[n] $number[n] $nn
金额(double) money[n] $money[n] $mn
日期(long) date[n] $date[n] $dn
注∶
n是顺序号
chars(n)是宏,c语言中chars(n)、infstring[n]都可用;
sql语言中只能用infstring[n],不能用宏chars(n);
2.值的配置.
系统根据配置动态申请内存,按你的需要调整系统配置(或修改form.cfg),
确定值的个数.
3.值的顺序.
用下例来说明∶
[序] [类型][长度][坐标] 对应的变量 注 解
0 c 3 1237 chars(0) 'c'字符型第 1 次出现
1 c 20 1337 chars(1) 'c'字符型第 2 次出现
2 h 8 1537 chars(2) 'h'字符型第 3 次出现
3 a 7 1737 chars(3) 'a'字符型第 4 次出现
4 m 10 1937 money[0] 'm'金额型第 1 次出现
5 b 0 0 控制类与变量无关
6 i 0 0 控制类与变量无关
7 i 0 0 控制类与变量无关
8 c 11 2120 chars(4) 'c'字符型第 5 次出现
9 b 0 0 控制类与变量无关
10 i 0 0 控制类与变量无关
11 m 12 2126 money[1] 'm'金额型第 2 次出现
12 f 1 2146 chars(5) 'f'字符型第 6 次出现
13 i 0 0 控制类与变量无关
14 i 0 0 控制类与变量无关
15 n 6 2170 number[0] 'n'长整型第 1 次出现
六。使用form的用户环境
用户可设置以下环境变量
(1)configpath: form的配置文件的路径。缺省为 /usr/wform/etc/form.cfg
form的参数的路径在配置文件中设定。
用户的程序中可在启动form前,调用formpath(char *path)设定路径。
(2)msgpath: 帮助项信息文件路径。缺省为 /usr/wform/etc/form_msg.dat
(3)netconfigfile:通讯的配置文件,适用于本系统网络版,客户及服务端都
需要,缺省为 /usr/wform/etc/sys.net
七。form生成器(mkform、netform)的使用
_.----..__.'
_ / -._
__ ``-._ ) | ||../// ./ /`-
-'_ `-._ /( `-./ / // |/
/-'' ``-._| /`-. .`. / | |/ // | | /
/_.---.__.| `_/``' `-..-'_/_/ /_/ |/// /
_..--'/ /' -._ .'"(@ ` @`/-._ / /
( ' // `-.` `(| _' ;`-. ` `_ `.
/ / ``-._ _.'| _ ` ,' '_.-` .'
/ /-------- ``'-~-' `;`~'`` . '
'._ // ` // / . '
```` --- .. -. // //'
`/ / // //
`. | || . || ┏━━━━━选择━━━━━┓
/ . || .' `-|| ┃ v 全屏幕编辑_______(0)┃
/ `||' ;|| ┃ t 交易式演示程序___(1)┃
;|| '// ┃ m 菜单式演示程序___(2)┃
_; || // [ ]┃ d 显示系统配置_____(3)┃
/.``||..__.-; ┃ a 调整系统配置_____(3)┃
.'` ``-._|_|.-| ┃ s 清理form_________(5)┃
/ ; ┃ p 改变form参数路径_(6)┃
; ; ┃ l 登记注册_________(7)┃
; ; ┃ e 退出_____________(8)┃
; ,' ┗━━━━━━━━━━━━┛
------------ 图10 --------------
(一)运行mkform(或netform)
mkform的用法∶mkform -d database -f filename
1.打开数据库∶ -d database 可省略(不访问数据库)。
2.指定form参数文件名∶-f filename 如省略则按系统配置文件中指定的路径。
mkform与netform的主要区别:mkform对远程数据库的访问是利用了informix本
身的功能,也就是由sqlexecd提供服务;netform访问数据库的服务程序(net_server)由
作者编写,在数据安全方面进行了控制,所以在运行netform的同时,必须启动net_server
服务程序。
(二)菜单功能
当你运行mkform时,就出现图10,下面就菜单的功能逐一介绍∶
1. v 全屏幕编辑
进入form的编辑、定制程序。(祥见以下关于form编辑的一章)。
2. t 交易式演示程序
演示以交易码驱动的程序。
3. m 交易式演示程序
演示以菜单驱动的程序。
4. d 显示系统配置(图11)
配置文件的路径由环境变量configpath指定,缺省为 /usr/wform/etc/form.cfg
┏━━━━━━━━━━━ 系 统 配 置 ━━━━━━━━━━━┓
┃ 0. form参数路径: ../data/demo.form ┃
┃ 1. 编缉命令: /usr/bin/vi ┃
┃ ┃
┃ 2. 字符型(char)个数: 50 3. 数值型(long)个数: 10 ┃
┃ 4. 金额型(double)个数: 10 5. 日期型(date)个数: 8 ┃
┃ ┃
┃ 6. 菜单最大项数: 100 ┃
┃ 主菜单格式: ( 7. 2 8. 5 ) ┃
┃ 子菜单格式: ( 9. 12 10. 1 ) ┃
┃ ┃
┃ 11.双零键: 46 12.四零键: 47 ┃
┃ 13.五零键: 42 14.六零键: 45 ┃
┃ 15.借方键: 3 16.贷方键: 4 ┃
┃ 17.向前键: 91 18.向后键: 93 ┃
┃ 19.热 键: 26 20.发送键: 10 ┃
┃ ┃
┃ 选择: [ ] (esc取销) ┃
┃ ┃
┃ ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
------------ 图11 --------------
5. a 调整系统配置
只有root用户才能调整系统配置。
编缉命令: 编辑form所调用的文本编辑程序。
主菜单格式: ( 7. 2 8. 5 )
该项配置说明主菜单格式是 2行, 5列。
选择第 7项修改行数,选择第 8项修改列数。
子菜单格式: ( 9. 12 10. 1 )
该项配置说明主菜单格式是12行, 1列。
选择第 9项修改行数,选择第10项修改列数。
6. s 清理form
对作废和删除的form定期清理。
7. p 改变form参数路径
form参数路径在mkform启动时或系统配置文件中指定,如果你需要其他的form
参数文件可由此选项改变。
8. l 登记注册。
9. e 退出系统。
(三)关于form编辑
在图10中的菜单选第 0项,就进入图12。
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ [命令] ┏━━━━━━━┓ [连接交易] 0 [驱动方式] [索引项] ┃
┃ [序] [类型┃a 进入___(00) ┃函数] [ 复 合 域 ]┃
┃ 0 ┃e 退出___(01) ┃ ┃
┃ 1 ┃g 取数___(02) ┃ ┃
┃ 2 ┃h 帮助___(03) ┃ ┃
┃ 3 ┃s 演示___(04) ┃ ┃
┃ 4 ┃u 恢复___(05) ┃ ┃
┃ 5 ┃d 设计___(06) ┃ ┃
┃ 5 ┃v 编辑___(07) ┃ ┃
┃ 6 ┃w 存盘___(08) ┃ ┃
┃ 7 ┃f 单选___(09) ┃ ┃
┃ 8 ┃d 删除___(10) ┃ ┃
┃ 9 ┗━━━━━━━┛ ┃
┃ 10 ┃
┃ 11 ┃
┃ 12 ┃
┃ 13 ┃
┃ 14 ┃
┃ 15 ┃
┃ 16 ┃
┃ 17 ┃
┃ 18 ┃
┃ 19 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
------------ 图12 ------------
图12中的命令菜单功能∶
1. a 进入本系统的form编辑器,编辑的窗口每屏是20项,共 5屏;
当光标到最后一行,再按↓键,就可翻到下一屏。
2. e 退出本编辑器。
3. g 取数
输入交易号就可读到此交易的form参数。
4. h 帮助
显示文本/usr/wform/etc/readme.frm.
5. s 演示form
输入交易号就可此交易的form框架,演示输入、查询的过程。
6. u 恢复被误删除的form.
7. d 设计
利用unix编辑工具,对form进行初步的定制。具体的方法详见form的定制。
7. v 编缉
利用unix编辑工具,对form的参数进行设定。具体的方法详见form的编辑。
9. w 存盘
将编辑或修改完的form存入文件。原来同号的form被作废,故需定期清理
form。
10. f 单选
可单独选出一个指定的form参数,文件名"./f????", ?表示form号。
作用∶有些form的功能通用,可移到其他用户的form参数文件中。
移值方法∶ cat f??? >> other.form
11. d 删除
对弃用的form进行删除。
(四)form的定制:
1. 利用unix编辑工具,对form进行初步的定制。
(1) 选命令 v,输入交易号,(假设交易号是88)。系统就调用unix编辑工具
(如vi),生成文本/tmp/form88,在文本在写的内容如下∶
序号 文 本 内 容
1
2
3
4
5 记 帐
6
7
8 帐 号∶ $a12
9
10 凭证号∶ $n6
11
12 摘 要∶ $c10
13
14 金 额∶ $m12
------------ 图13 ------------
在'$'符后的字符是类型,类型后的数字是长度。
将该文本存盘退出后,即返回系统画面,系统根据文本内容及各个域的
坐标,在内存生成结构为dialog的form,见图14.
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ [命令] g [交易号] 88 [连接交易] 0 [驱动方式] [索引项] 0 ┃
┃ [序] [类型][长度][坐标][嵌入函数] [ 复 合 域 ]┃
┃ 0 a 12 739 0 ┃
┃ 1 n 6 939 0 ┃
┃ 2 c 10 1139 0 ┃
┃ 3 m 12 1339 0 ┃
┃ 4 l 0 437 0 记 帐 ┃
┃ 5 l 0 730 0 帐 号∶ ┃
┃ 6 l 0 930 0 凭证号∶ ┃
┃ 7 l 0 1130 0 摘 要∶ ┃
┃ 8 l 0 1330 0 金 额∶ ┃
┃ 9 0 0 0 ┃
┃ 10 0 0 0 ┃
┃ 11 0 0 0 ┃
┃ 12 0 0 0 ┃
┃ 13 0 0 0 ┃
┃ 14 0 0 0 ┃
┃ 15 0 0 0 ┃
┃ 16 0 0 0 ┃
┃ 17 0 0 0 ┃
┃ 18 0 0 0 ┃
┃ 19 0 0 0 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
------------ 图14 ------------
用命令 w存盘,再用命令 s进行演示,见图15。如果对form不满意,可通过对
文本修改或直接修改form,直至满意。
┏━━━━━━━━━━━━━━┓
┃ 记 帐 ┃
┃ ┃
┃ ┃
┃帐 号∶[ ] ┃
┃ ┃
┃凭证号∶[ ] ┃
┃ ┃
┃摘 要∶[ ] ┃
┃ ┃
┃金 额∶[ ] ┃
┗━━━━━━━━━━━━━━┛
------------ 图15 ------------
(五)form的编辑:
用unix编辑只是form的初步定制,它只能对标题、数据的输入、显示域进行定义。
而对[连接交易]、[驱动方式]、[索引项]、[嵌入函数]以及菜单、数据库的表名、 字段名等等,需本系统提供的编辑功能或直接用vi编辑。
方法一____系统提供的编辑功能:
(1) 用命令 a进入,用光标键移到需改动的域。
(2) 行的复制功能.
把a 行开始的n 条复制到b 行上,方法如下∶
将光标移至a 行按f2键,再按要复制的条数n,再将光标移到b行按 f2键。
连续按两次f2,可在原行下复制一行。
(3) 行的插入功能.
按[insert]键,可增加一行空行。
(4) 行的删除功能.
将删除行的类型改为空格,存盘时,会剔除该行。
(5) 复合域的编辑功能。
f1键向右移,[backspace]键向左移。
命令切换键f3或[delete],x删除字符,i插入字符,功能同vi.
方法二___利用vi编辑功能:
(1) 用命令 v进入、再输入form号。
(2) 如form是新建的,系统生成一个带有说明和一定格式的文本(见图16),由您
填写编辑。
如form已存在,系统生成一个带有原form参数的文本,由您修改。
[交易号] 120 [连接交易] 0 [驱动方式] b [索引项] 3
[类型][长度][坐标][嵌入函数] [ 复 合 域 ]
~~提示:以下值的横坐标必须在对应字段的区域内(以'[]'为界),否则无效!空缺值为零~~
------------ 图16 ------------
九。演示程序
演示程序menu、trade的功能相同;共用数据库test、form参数文件test.form.
你可阅读menu.ec、trade.ec中是如何调用本系统函数的;
你还可参考./menu/makefile、mknet ./trade/makefile、mknet;
十。有关网络版
所谓网络版就是在原版的基础上, 将程序分为前台程序(界面控制程序)和后台程序 (数据服
务器), 前台把form中涉及数据数据库的form, 组织成sql语句通过网络传给后台, 后台把
sql 的着执行结果返回前台, 如图16所示:
┏━━━━━┓ sql语句送后台 ┏━━━━━━━━━┓
┃ ┃ ────────────→ ┃ ┃
┃ 前 台 ┃ ........tcp/ip........... ┃ 后台(net_server) ┃
┃ client ┃ ←──────────── ┃ server ┃
┗━━━━━┛ 查询、更新结果返回前台 ┗━━━━━━━━━┛
------图16-----
查询的核心代码:
select(int tag, char *command)
{
$char *sel, str[128];
$short flag;
$date date;
$long number, b_count, j;
$long prec;
$long type;
$long scale;
$double money;
$char result[128];
int ret, offset=0;
int i=0;
char fmt[32], tag;
if(displayflag) printf("tag=%c/nsql=%s/n", tag, command);
retpacket.txcode=select;
if(tag=='m'){
//多项查询
sel=getfield(command, &offset);
if(strlen(sel)<2) goto exit1;
tag=sel[0];
}
else
tag=tag;
sel=getfield(command, &offset);
if(tag=='m') changecmd(sel);
if(strlen(sel)<10) goto exit1;
if((ret=composebrowse(10, sel))<0){
sqlerrhandle(sqlcode, select);
goto exit0;
}
retpacket.txcode=select;
$get descriptor 'browsdesc' :b_count=count;
if(sqlcode){
sqlerrhandle(sqlcode, select);
goto exit0;
}
$fetch browse using sql descriptor 'browsdesc';
if(sqlcode){
strcpy(retpacket.data, "select error|");
sqlerrhandle(sqlcode, select);
goto exit0;
}
for(j=1;j<=b_count;j++){
$get descriptor 'browsdesc' value $j
$prec=precision, /*money、decimal*/
$scale=scale, /*money、decimal*/
$type=type;
if(sqlcode){
strcpy(retpacket.data, "select error|");
sqlerrhandle(sqlcode, select);
goto exit0;
}
switch(type){
case sqlfloat:
case sqlsmfloat:
case sqldecimal:
case sqlmoney:
if(prec)
sprintf(fmt, "%s%d.%df/0", "%",prec+1, scale);
else
strcpy(fmt, "%f");
$get descriptor 'browsdesc' value $j
$money=data;
sprintf(result, fmt, money);
if(sqlcode==dataisnull) result[0]=0;
break;
default:
$get descriptor 'browsdesc' value $j
$result=data;
}//switch
deltailspace(result);
if(sqlcode==dataisnull) sqlcode=0;
if(sqlcode){
strcpy(retpacket.data, "select error|");
sqlerrhandle(sqlcode, select);
goto exit0;
}
strcat(retpacket.data, result);
strcat(retpacket.data, "|");
}//for
if(displayflag) puts(retpacket.data);
exit0:
$close browse;
$free browse;
$deallocate descriptor 'browsdesc';
exit1:
return true;
}
(一)网络版的作用:
增强安全性。informix能访问远程数据库,但须建立对等关系,会造成不安全。
本版无须建立对等关系,克服了这个弱点。
(二)网络版的用法:
1. 网络通讯使用tcp/ip协议。
2. 前、后台程序也可在同台机器上.
3. form的定制、函数及功能不变.
4. 链接的程序库: /usr/wform/lib/libnetform.a。
5. 通讯的配置文件: $home/etc/sys.net的内容:
(1)数据库名:对后台而设
[database]
database=mobile
(2)后台机器名:前、后台须一致。/etc/hosts中存在,也可以直接写ip地址。
[serverhost]
serverhost=save01
(3)端口号:前、后台须一致。
[netform tcp port]
netformtcpport=8168
(4)socket超时报警时间(秒),确省值60
[socket read & write time out(s)]
sockettimeout=35
(5)查询超时报警时间(秒),确省值60, 仅对前台而设。
[wgetch time out(s)]
wgetchtimeout=30
(6)跟踪标志,仅对前台而设,0屏蔽,1开放。跟踪文件:$home/run/trace
[trace flag]
traceflag=0
(7)connect超时报警时间(秒) 仅对前台而设。
[company server connect time out(s)]
connecttimeout=8
(8) fork()服务子进程同时存在的最大数, 仅对后台而设。
[max user number]
usernum=10
(9)显示部分服务程序接受和发送的数据。0屏蔽,1开放
[display server data flag]
displayflag=1
6. 地址簿文件: $home/etc/hosts.equ 设在后台
记录允许访问数据库的前台机器的ip地址,未记录的机器不能访问。
设置方法:
(1)文件中加入all.hosts,对所有的客户开放。
(2)文件中加入网段地址(如13.7.5),对该网段开放。
(3)文件中加入完整的客户端ip地址(如12.17.23.76),对该客户机开放。
7. 服务器的启动:net_server
8. 服务器的停止:net_server stop
9. 返回值∶ 当sqlcode>-10时是本系统定义,含义如下∶
-1 收数据包出错: 如超时。
-2 拒绝服务∶ 地址簿无本机ip地址
-4 服务进程超过限定的数目。