FUNCky 的使用
张健姿
01-6-26 下午 04:31:30
FUNCky 是 一 个PowerBuilder 应 用 程 序 库, 它 提 供 了16 位 和32 位 两 种 应用 库, 其 中 包 含 了 大 量 的 底 层 函 数, 免 去 了 开 发 人 员亲 自 动 手 使 用C 语 言 编 写 动 态 链 接 库 来 处 理 很 多 常 用的 诸 如 文 件 操 作、 字 符 串 操 作、 位 操 作 等 功 能。 使 用Funcky 能 大 大 提 高 开 发 效 率。 本 篇 简 单 讲 述 一 下 如 何 在PowerBuilder 中 使 用Funcky。
将FUNCky 加 到 您 的 应 用 中
FUNCky 提 供 了16 位 和32 位 的 运 行 库Funcky.dll、Funcky16.pbl 和 Funcky32.dll、Funcky32.pbl,应 用 程 序 调 用 的 函 数 或 过 程 都 在 该 动 态 链 接 库 和PBL 文件 中。 安 装 完FUNCky 后, 两 个 动 态 链 接 库 被 拷 贝 到Windows 的System 目 录 下, 两 个PBL 则 在 安 装 的 目 录 下。 使 用 时 将 用 到 的函 数 在 应 用 的Global External Function 或Local External Function 中 作 相 应的 声 明 即 可, 如 需 使 用 全 部 函 数 则 可 以 将 整 个PBL 文 件加 到 您 应 用 的 搜 索 库 中。 函 数 原 型 定 义 可 以 从 相 应 函数 帮 助 中 获 得。
除 帮助 文 件 中 提 供 的 函 数 以 外, 在funcky.dll 中 还 有 其 它 的 一些 未 公 开 的 函 数 在Funcky.pbl 中 被 调 用, 这 些 函 数 用 户 也可 以 使 用。
使 用Funcky 要 注 意 的 几 点
· 在 应 用 中, 只 将 使 到 的 函 数 加 到 函数 原 型 声 明 中 去, 不 要 声 明 过 多 的 函 数 原 形, 否 则 运行 时 系 统 可 能 会 报 函 数 原 型 不 匹 配 错 误;
· 如 只 需 使 用 少 量 函 数, 用 户 尽 量 不要 将FUNCky.pbl 加 到 应 用 中 使 用, 因 为 那 将 需 要 大 量 的 函数 原 型 声 明 才 能 编 译 通 过;
· 某 些 函 数 原 型 是 以"_" 开 头 的定 义, 这 些 函 数 都 在Funcky.pbl 中 有 定 义, 使 用 者 可 以 直接 使 用 该 函 数, 将Funcky.pbl 中 的 代 码 直 接 拷 贝 到 自 己 的pbl 中, 或 自 己 编 写 相 关 的PowerBuilder 函 数。
Funcky 函 数 分 类
Funcky 一 共 提 供 了12 类 的 函 数:
· 位 操 作 函 数
· 块 和 内 存 操 作 函 数
· 数 据 转 换 函 数
· DBF 文 件 访 问 函 数
· 磁 盘 访 问 函 数
· DOS 环 境 函 数
· 日 期 函 数
· 低 级 文 件 操 作 函 数
· 转 换 函 数
· 字 符 串 操 作 函 数
· 系 统 资 源 函 数
· 时 间 操 作 函 数
举 例 说 明
下 面我 们 举 几 个 例 子, 说 明 一 下 这 些 函 数 的 使 用。 我 们 着重 介 绍 的 是DBF 文 件 访 问, 块 操 作 和 内 存 操 作、 低 级 文件 操 作 等 这 几 类 函 数, 这 是 大 家 在 应 用 中 经 常 要 用 到的, 而PowerBuilder 本 身 却 不 提 供 的 操 作。
1. 我 们 经 常 在PowerBuilder 应 用 中 遇 到 有 关图 象 存 储 和 显 示 的 问 题, 而 在 这 方 面,PowerBuilder 本 身 的处 理 功 能 较 弱, 在 实 际 应 用 中 经 常 无 法 达 到 用 户 的 要求。 我 们 可 以 借 助Funcky 的 函 数 来 处 理 图 象 文 件。
例 如 在 应用 中 需 要 存 储、 查 询、 显 示 和 打 印 照 片, 一 般 开 发 人员 使 用OLE 嵌 入 的 方 法 来 做, 但 是 如 果 获 得 的 每 一 幅 照片 的 规 格 不 完 全 一 样, 这 样 显 示 和 打 印 的 效 果 就 很差, 采 用 这 种 方 法 制 作 通 行 证 或 身 份 证 上 的 照 片 几 乎是 不 可 用 的。 解 决 这 一 问 题, 所 使 用 的 较 简 单 的 方 法是, 以bitmap 格 式 在 数 据 库 中 存 放 图 象 数 据, 显 示/ 打 印时, 将 数 据 取 出 在 本 地 保 存 成 为 临 时 文 件, 根 据 图 象的 尺 寸 进 行 等 比 例 缩 放 显 示 在 图 象 控 件 上, 这 样 既 能达 到 界 面 的 要 求, 又 能 获 得 高 质 量 的 图 象。 我 们 可 以借 助Funcky 函 数 来 解 决 这 样 几 个 问 题:
o bitmap 图 象 文 件 存 储 效 率 不 高, 在 数据 库 中 占 据 的 空 间 过 大, 可 在 存 入 前 使 用fcompress 函 数对 图 象 文 件 进 行 压 缩:
函数 声 明:
FUNCTION long fcompress(string s,string d)
LIBRARY "FUNCky32.DLL"
//定义压缩函数原型
SCRIPT:
retcode = fcompress(ls_path, "_tmp.tmp")
//压缩文件
choose case retcode
...//检查返回值
End choose
...//将压缩后的文件保存到数据库中
fdcompress 的 压 缩 效 率 不 高, 但 速 度 很 快, 还 是 值 得 使 用的。
o bitmap 图 象 的 宽 和 高 保 存 在 该 文 件 的第18 和 第22 个 字 节 中, 不 用Funcky 函 数 很 难 读 出 这 两 个 字节 的 信 息。 下 面 一 段 程 序 是 解 压 缩 和 计 算BMP 图 象 的 宽和 高
函数 声 明:
//定义从二进制数据中读取一个长整形函数原型
FUNCTION long _blob2long(ref blob b, uint o)
LIBRARY "FUNCky32.DLL"
//定义解压缩函数原型
FUNCTION long fdcompress(string s,string d)
LIBRARY "FUNCky32.DLL"
SCRIPT:
... //从数据库中将数据取出保存在文件$fgd.bmp中
status = fdcompress("$fgd.bmp","_fgd.bmp")
//解压缩
choose case status
...//检查返回值
End choose
...//将_fgd.bmp读入blob变量pic
ll_width = _blob2long(pic,18) //读图象宽度
ll_height = _blob2long(pic,22) //读图象高度
//根据指定的宽和高计算缩放比例
bili_width = integer(sle_width.text) / ll_width
bili_height = integer(sle_height.text) / ll_height
//得到显示宽度和高度
p_width = ll_width * min(bili_width, bili_height)
p_height = ll_height * min(bili_width, bili_height)
我 们可 以 看 到Funcky 函 数 的 使 用 非 常 简 单, 能 够 轻 松 做 到 在PowerBuilder 中 很 难 实 现 的 操 作。
2. 在 应 用 中 您 可 能 会 遇 到 直 接 读 取DBF 文 件 的 情 况, 处 理 这 类 问 题 的 方 法 一 般 有 两 种 经 典 的方 法: 一 是 使 用 数 据 窗 口 读DBF 文 件, 二 是 指 定 一 个 磁盘 目 录 作 为 数 据 区, 用ODBC 连 接 这 个 目 录, 使 用 时 规 定用 户 必 须 将DBF 文 件 拷 贝 到 这 个 目 录 下。 但 是 这 两 种 方法 都 缺 乏 灵 活 性, 而 在Funcky 中 却 提 供 了 直 接 读DBF 文 件的 函 数。 在Funcky32.pbl 中 有 一 个dbffieldget() 函 数 可 以 获 取 该DBF 文 件 的 字 段 名 称。 不 过 根 据 我 们“ 尽 量 不 使 用Funcky32.pbl” 的 原 则, 自 己 手 工 编 写 一 个 实 现 该 功 能 的 代 码。
定 义 外 部函 数:
FUNCTION long dbfOpen(string f, int o)
LIBRARY "FUNCky32.DLL"
FUNCTION boolean dbfEof(long d)
LIBRARY "FUNCky32.DLL"
FUNCTION int dbfClose(long d)
LIBRARY "FUNCky32.DLL"
FUNCTION long dbfSkip(long d, long c)
LIBRARY "FUNCky32.DLL"
FUNCTION uint dbfFieldSize(long d, int p)
LIBRARY "FUNCky32.DLL"
SUBROUTINE _dbfFieldGet(long d,int p,ref string b)
LIBRARY "FUNCky32.DLL"
FUNCTION int dbfFieldPos(long d,string n)
LIBRARY "FUNCky32.DLL"
SCRIPT:
//以读写和拒绝其他用户写的方式打开dbf数据库
do while 1 = 1
dbf = dbfopen(ls_file, 2 + 32)
if dbf <> 0 then
exit
end if
loop
//读dbf数据
//ii_xx_count是需要读的dbf字段的总数
//is_dbf[]是字段名称数组
do while not dbfeof(dbf)
for i = 1 to ii_xx_count
p = dbffieldpos(dbf, upper(is_dbf[i]))
//获取字段的位置
ls_tmp = space(dbffieldsize(dbf, p) + 1)
//根据字段的大小初始化存放数据的变量
_dbffieldget(dbf, p, ls_tmp)
//将数据读入到ls_tmp中
next
dbfskip(dbf, 1)
//使dbf操作指向下一条记录
loop
dbfclose(dbf)
//关闭打开的dbf文件
这 样直 接 读 取DBF 信 息, 给 应 用 带 来 的 好 处 是 显 而 易 见 的。
3. 对 于 数 据 库 的 用 户 管 理, 我 们 一 般会 采 用 在 数 据 库 中 建 立 一 个 表, 记 录 用 户 名 称、 口 令等 信 息, 在 用 户 登 录 时, 应 用 检 索 这 个 表 的 信 息, 同用 户 输 入 的 内 容 核 对。 按 照 一 般 系 统 管 理 的 规 定, 每一 个 用 户 的 口 令, 其 他 人 是 无 法 在 系 统 中 查 到 的。 即使 是 系 统 管 理 员 也 只 有 删 除 登 录 用 户 的 权 利, 而 无 法获 取 用 户 的 口 令。 可 是 由 于 系 统 管 理 员 可 以 读 取 数 据库 中 的 每 一 张 表, 因 此 他 是 就 有 机 会 看 到 用 户 的 登 录口 令 的, 因 此 我 们 应 当 在 口 令 字 段 存 入 数 据 库 前 对 其进 行 加 密。Funcky 提 供 了encrypt() 函 数 和decrypt() 函 数 就 可 以 用来 完 成 这 一 工 作, 这 就 避 免 了 程 序 员 手 工 编 写 加 密 算法 的 麻 烦 了。
此 外,Funcky 在16 位Windows 下 还 有 许 多 底 层 的 操 作, 包 括 中断 的 调 用 和 直 接 操 作 磁 盘 的 函 数, 可 以 用 以 软 件 加 密的 工 作, 这 里 就 无 法 详 述 了。 总 之,Funcky 提 供 了 较 多 的函 数 功 能, 有 条 件 的 读 者 可 以 在 以 后 的 应 用 中 尝 试 使用, 相 信 会 给PowerBuilder 的 开 发 带 来 一 定 的 方 便。