| 在PowerBuilder5.0 的PowerScript
语 言 中, 对 于 函 数 和 事 件 的 处 理 有 了 新 的 拓展。 记 得 我 们 曾 在 关 于PowerBuilder 的 面 向 对 象 特 性
中 介 绍过,PowerBuilder 的 对 象 由3 部 分 内 容 组 成: 属 性、 函 数 和 事件。 而 在5.0 中, 对 于 这 部 分 理 论
进 行 了 调 整: 将 函 数和 事 件 进 行 了 同 化, 统 称 为 方 法(Method )。 在Script 中 调用 函 数 和 调 用 事 件
的 方 法 进 一 步 接 近, 事 件 也 可 带 有参 数, 并 具 有 返 回 值。
函 数 和 事 件即 统 称 方 法 调 用 的 语 法 为:
{ objectname.} { type } { calltype } { when } functionname ( {
argumentlist } )
这 些 参 数 的 说 明 如 下:
type 所调用方法的类型 可以是EVENT或FUNCTION,其中FUNCTION为缺省。
calltype 所调用的类型 可以是动态(关键词为DYNAMIC)或静态
(关键词为STATIC),其中STATIC为缺省。
when 调用的时间 POST或TRIGGER,其中TRIGGER为缺省。
当 然, 并 不是 所 有 的 选 项 都 是 有 意 义 的。 比 如 我 们
不 会 去 调 用 一个 动 态 的PowerScript 对 象 函 数。 只 有 在 用 户 自 定 义 函 数中, 我 们 才 可 能 动 态 地 调 用
一 个 函 数。 允 许 对 函 数 的 调 用 采 用Post 方 式是5.0 的 新 特 点。 当 函 数 以 这 一 方 式 被 调 用
时, 系 统 将这 一 函 数 放 在 了 这 个 对 象 的 消 息 队 列 的 末 尾, 当 前 面的 所 有 消 息 都 被 执 行 了 以 后, 这 一
函 数 才 被 调 用。 采用 这 种 方 式 调 用 函 数, 您 仍 可 以 传 递 参 数, 但 是 却 无法 得 到 返 回 值。 如:
// 合 法 语 句
POST wf_calculate(x,y)
// 非 法 语 句
Statue = Woo.cb_1.POST EVENT Clicked()
关 键 词STATIC 是表 示 您 现 在 所 调 用 的 方 法 和 您 所
使 用 的 参 数 在 编 译时 是 存 在 的。 如:
STATIC EVENT ue_validates(ls_name, li_id)
如 果 关 键 词DYNAMIC 出 现 在 这 一 行 调 用 的 函 数
中,PowerBuilder 在 编 译 这 一 行 代码 时 将 不 检 查 这 个 方 法 和 所 用 参 数 的 有 效 性, 只 是 到了 运 行 时,
系 统 才 会 到PBD 的 库 中 去 搜 索 这 个 方 法。
当 我 们 在 运行 时 需 要 根 据 当 前 不 同 情 况 的 上 下 文
调 用 不 同 的 对象 函 数 时, 我 们 会 用 到 这 一 关 键 词。 例 如:
PowerObject lpo
lpo = dw_1
lpo.dynamic show()
在 运 行 前,也 许 我 们 还 无 法 了 解 到 我 们 要 对 哪 个 对
象 进 行show() 的操 作, 只 能 等 到 运 行 时 才 能 确 定 操 作 对 象。 如 果 在 上述 的 语 句 中 我 们 去 掉 关 键
词dynamic, 系 统 编 译 将 出 现 错误, 因 为PowerObject 对 象 类 并 没 有show 这 个 对 象 函 数。 一 般来
说,Dynamic 关 键 词 只 有 在 调 用 多 态 方 法 时 才 可 能 用到, 这 实 际 上 也 是 进 一 步 拓 展
了PowerBuilder 的 面 向 对 象 的特 性。
不 过 我 们 在调 用 方 法 时 使 用STATIC 这 一 关 键 词, 一
般 也 只 是 为 了 系统 在 编 译 时 对 您 所 引 用 的 方 法 进 行 一 下 语 法 检 查, 以确 保 引 用 的 正 确 性。 如 果 我
们 在 运 行 时 改 变 了 方 法 的对 象 名 称, 系 统 将 调 用 改 变 后 的 对 象 的 方 法。
我 们 来 作 这样 一 个 实 验:
在 窗 口 中 我 们 声 明 一 个 实 例 变量:
CommandButton icb
在 窗 口 中 有 两 个 按 钮, 在 第 一个 按 钮cb_1 的constructor 事 件 中 键 入:
icb = this
clicked 事 件 中 键 入:
icb.resize(200,100)
窗 口 的 第 二 个 按 钮cb_2 的clicked 事件 中 编 码 如 下:
icb = this
当 这 个 窗 口运 行 时, 在cb_2 的 构 造 事 件 中 变 量icb
引 用 定 为cb_1, 如 果这 时 我 们 首 先 点 击 第 一 个 按 钮, 这 个 按 钮 的clicked 事 件被 触 发, 调
用icb.resize() 函 数, 这 个 按 钮 的 尺 寸 将 随 之 改变。 我 们 点 击 一 下cb_2 后, 再 按 动 第 一 个 按 钮, 这
时 您会 发 现,cb_2 的 尺 寸 也 改 变 了。 因 为 在 我 们 按 下 第 二 个按 钮 后icb 的 引 用 赋 值 已 经 改 变 为
了cb_2。
在PowerBuilder5.0 所 包 括 的Anchor Bay Nut
Company sample application 这 一 实 例 中 就 使 用了 一 个 动 态 调 用 函 数 的 实
例。m_datareview_framemenu 是 一 个 祖先 菜 单 类, 它 的 后 继 菜 单 类
有m_datareview_custsheet,m_datareview_ordsheet 等, 分 别
为w_datareview_custsheet,w_datareview_ordsheet 等 窗 口 所 拥有, 这 些 窗 口 是MDI 下 的 不 同 表
单, 对 这 些 表 现 不 同 信息 的 表 单 进 行 输 出(export) 操 作 是 各 不 相 同 的, 因 此 各 自的 窗 口 分 别 有 不
同 的 多 态 函 数wf_export 处 理 各 自 的 输 出操 作。 可 是 在 对m_datareview_framemenu 菜 单
的m_export 项 编 码 时,我 们 无 法 知 道 当 前 激 活 的 表 单 是 哪 一 个, 所 以 我 们 只能 动 态 地 调 用 这 个 窗
口 函 数:
guo_global_vars.ish_currentsheet.DYNAMIC
wf_export()
其 中guo_global_vars.ish_currentsheet 的 值 是
当 前 活 动 表 单 的 引 用, 而 这 个 值 在 声 明 时 却 只能 声 明 作 这 些 表 单 共 同 的 祖 先
类w_datareview_frame 的 引 用,因 为 这 个 祖 先 窗 口 是 没 有wf_export 这 个 窗 口 函 数 的, 所以 我 们 必
须 使 用DYNAMIC 这 个 关 键 词。 这 个 例 子 在abnc_rev.pbl 库 中 可 以 找 到, 有 兴 趣 的 人 员 可 以 好 好 理
解 一 下。 如果PowerBuilder 没 有 这 个 调 用 动 态 函 数 的 功 能, 那 么 我 们 只能 采 用 其 它 方 法 替 代 解 决,
如:
1. 在 祖 先 窗 口w_datareview_frame 中 定 义一 个 空 白 的wf_export() 函 数;
2. 使 用SWITCH CASE 语 句 来 决 定 调 用 哪个 窗 口 函 数。
显 然 第 二 种 方 法 不 是 一 个 好 的面 向 对 象 的 程 序 设 计。
在 目 前 为止, 函 数 和 事 件 仍 存 在 着 一 些 差 异, 它 们
表 现 在 事 件只 与 对 象 有 关, 而 函 数 既 包 括 对 象 函 数, 也 有 一 部 分是 全 局 的。
在PowerBuilder 中, 事 件 和 函 数 的 搜索 顺 序 是 不 同 的。
在 运 行 时, 用 户 调 用 了 一 个 未定 义 的 事 件, 系 统 将 不 会 产 生 任 何 错 误, 但 是 调 用 了未 定 义
函 数, 系 统 将 触 发 错 误。
函 数 可 以 重 载, 而 事 件 不 能。
对 自 定 义 的 函 数, 您 可 以 指 定其 访 问 范 围 如public,private,protect 等, 但 是 事 件 不 能,
其访 问 范 围 全 部 为public。
您 可 以 很 容易 地 在 继 承 对 象 中 扩 展 或 覆 盖 祖 先 对
象 事 件 中 的 代码, 但 是 如 您 将 在 后 继 对 象 中 对 函 数 进 行 覆 盖 就 很 困难 了, 您 必 须 要 重 新 定 义 这 个
函 数。
限 于 篇 幅,我 们 只 能 对 第 二 条 进 一 步 引 申 说 明:
由 于 函 数 是 支 持 重 载 的, 当 您的 代 码 调 用 一 个 函 数 时, 系 统 将 本 着 兼 容 匹 配 的 原则, 搜 索
您 将 要 调 用 的 函 数, 因 此 当 您 调 用 重 载 函 数时, 一 定 要 指 明 参 数 的 类 型。 例 如 数 据 窗 口 表 达 式 的返
回 值 是ANY 型 的, 您 应 当 这 样 明 确 指 出:
wf_process_search(string(dw_1.object.name[3]))
而 不 要 笼 统 写 成:
wf_process_search(dw_1.object.name[3])
而 另 一 方面,PowerBuilder 的 事 件 是 不 支 持 重 载
的, 但 是 后 继 对 象 的事 件 却 可 以 扩 展 祖 先 对 象 的 同 一 事 件 的。 系 统 搜 索 到您 将 要 调 用 的 对 象 事 件
后, 还 要 继 续 上 溯 寻 找 它 的 祖先, 直 到 祖 先 事 件 的 代 码 为 空 或 被 覆 盖 了 为 止, 并 要首 先 执 行 其 祖 先
代 码。
究 竟 是 在 函数 中 还 是 在 事 件 里 编 写 您 的 应 用 中 的
复 杂 的 商 业 逻辑, 这 只 是 一 个 编 程 风 格 问 题, 一 般 对 系 统 的 运 行 效率 将 不 产 生 任 何 影 响。
此 外 另 一 点要 说 明 的 是 以 上 所 谈 到 的 在5.0 中 新 增
加 的 语 法 功 能 是4.0 以 下 版 本 的 超 集, 也 就 是 说, 这 种 方 法 兼 容 了 以 往 调用 函 数 和 触 发 事 件 的 语
法, 以 保 证PowerBuilder 新 版 本 的 向上 兼 容 性。PowerBuilder5.0 中 仍 然 支 持 以 往
的TriggerEvent() 函 数、PostEvent() 函 数 和 关 键 词CALL 语 句。 只 是 以 前 的 触 发 事 件 的 方 法 无法
在 其 中 加 入 参 数。
|