位置于:书籍教程首页>>数据库类>>Power Builder>>正文

使用PowerBuilder另外的500个函数(上)

资料:http://xp163.com/
乍 一 看 到 这个 题 目, 我 们 可 能 会 觉 得 很 玄。PowerBuilder 系 统 自 身 提 供的 函 数 大 约 只 有200 多 个( 不 考 虑 多 态 函 数), 我 们 何从 得 到 更 多 另 外 的500 多 个 函 数 呢 ?

       我 们 在 以 前的 专 题 中 讨 论 过 如 何 使 用WindowsAPI 标 准, 调 用 外 部 函 数的 问 题。 而 使 用 过WindowsSDK 编 程 的 开 发 人 员 都 知 道, 在USER.EXE、GDI.EXE 等 可 执 行 文 件 和 动 态 连 接 库 中,Windows 本 身 提 供 了 大 量的 库 函 数, 这 些 函 数 在PowerBuilder 中, 我 们 都 是 可 以 直 接调 用 的。 这 样 我 们 的 函 数 库 就 一 下 子 又 扩 充 了500 多个。

       在 这 些API 函数 中, 相 当 一 部 分 对 我 们 是 非 常 有 用 的, 这 里 我 们 可以 分 类 向 大 家 介 绍 一 些:
       窗 口 函 数
       自 动 卷 滚 条

       缺 省 情 况下,MDI 表 单 是 可 以 重 新 设 定 大 小 的。 这 样 就 可 以 使 用户 将 窗 口 设 成 比 您 原 先 的 设 定 更 小。 这 种 情 况 下, 除非 您 对 窗 口 设 置 了 卷 滚 条 的 属 性, 窗 口 上 的 一 些 控 件用 户 将 不 能 访 问 到。 而 另 一 方 面, 除 非 窗 口 确 实 小 到不 足 以 显 示 所 有 的 控 件, 否 则 没 有 必 要 提 供 卷 滚 条。

       许 多Windows 的MDI 应 用 在 处 理 这 一 问 题 时 是 这 样 做 的; 当 窗 口 小 到 天 法显 示 所 有 控 制 时 打 开 卷 滚 条; 而 窗 口 大 小 合 适 时, 关闭 卷 滚 条。PowerBuilder 系 统 本 身 并 没 有 提 供 自 动 处 理 上 述操 作 的 特 性, 但 是 我 们 自 己 加 上 这 一 特 性 是 很 容 易的, 而 且 实 现 上 述 自 动 卷 滚 条 的 功 能 也 用 不 到WindowsAPI 调 用, 只 需 在MDI 表 单 窗 口 的resize 事 件 中 触 发 另 一 个 事件 以 判 断 在 当 前 窗 口 尺 寸 小 于 某 一 阈 值 时 显 示 卷 滚条( 后 面 您 将 了 解 为 什 么 我 们 要 另 外 的 触 发 一 个 事件, 而 不 直 接 在resize 事 件 中 直 接 做)。 此 后 用 户 在 滚 动卷 滚 条 时, 窗 口 是 会 自 动 随 之 滚 动 的, 当 用 户 再 次 改变 窗 口 大 小 并 大 于 该 阈 值 时, 我 们 应 该 关 闭 卷 滚 条,我 们 仍 然 可 以 不 调 用WindowsAPI 而 做 到 这 一 点。 然 而 在 整个 例 子 中, 真 正 有 难 度 的 是 在 关 闭 卷 滚 条 之 前, 我 们需 要 检 查 用 户 是 否 滚 动 了 卷 滚 条。 如 果 用 户 滚 动 了 卷滚 条, 我 们 则 应 当 首 先 将 窗 口 移 回 原 始 状 态 这 就 要 用到WindowsAPI 函 数 了。 因 为 我 们 需 要 确 定:(1) 卷 滚 条 的 滚 动范 围(2) 滚 动 块 在 卷 滚 条 上 的 当 前 位 置。 为 了 做 到 这 一点, 我 们 需 要 使 用 两 个WindowsAPI 调 用:GetScrollpos 和Getscrollrange。

       为 了 使 用 这两 个API 函 数, 首 先 我 们 在 需 要 使 用 它 们 的 窗 口 中 将 它们 声 明 为localexternal 函 数。 在Localextemal 函 数 对 话 框 中, 加 入如 下 语 句:

 FunctionintGetScrollPos(uintHandle,intBar)Library"USER.EXE"SubRoutineGetScrollRange(uintHandle,intBar,RefintMinPos,&RefintMaxPos)Library"USER.EXE"同时在该窗口中声明如下的实例变量://判断用户是否要最小化窗口Booleanib_minimized=FALSE//判断是否显示卷滚框intii_desired_height=1000intii_desired_width=2000

       其 中 的 两 个整 形 变 量ii_desired_height 和ii_desired_width 是 用 来 决 定 在 窗 口 的什 么 时 候 打 开 或 移 去 卷 滚 条 的 阈 值。 当 然, 每 个 窗 口中 都 必 须 设 置 这 两 个 变 量。 为 了 使 窗 口 更 为 通 用, 我们 也 可 以 定 义 一 个 窗 口 级 的 函 数, 该 函 数 在 窗 口 的open 事 件 中 能 分 析 窗 口 的control[] 属 性 也 就 是 窗 口 内 所 有 控件 的 最 大 值, 以 决 定 应 将 那 两 个 整 形 变 量 设 置 为 多少。

       那 个 布 尔 型的 实 例 变 量ib_minimized 是 用 来 确 定 用 户 是 否 正 要 将 窗 口最 小 化。 如 果 是, 则 我 们 处 理 卷 滚 条 时 会 有 些 不 同,稍 后 我 们 将 讨 论 这 种 情 况。

       我 们 在open 事件 中, 加 入 如 下 的 语 句:

 this.LinesPerPage=10this.ColumnsPerPage=10this.UnitsPerLine=this.ii_desired_height*.009this.UnitsPerColumn=this.ii_desired_width*.009

       接 下 来 我 们要 做 的 是 监 视resize 事 件, 根 据 用 户 改 变 窗 口 大 小 的 不同 方 式, 改 变 卷 滚 条 的 状 态。 这 里 的 问 题 是, 在 移 去或 加 上 卷 滚 条 时 会 引 起 另 一 个resize 事 件。 因 此, 在resize 事 件 中 直 接 改 变 卷 滚 条 的 状 态 会 引 起 递 归 调 用resize 事件, 这 是 我 们 不 希 望 发 生 的。

       为 了 防 止 递归 调 用, 我 们 要 定 义 一 些 的 用 户 自 定 义 事 件, 在 这 些事 件 中 处 理 卷 滚 条 的 移 去 或 加 入。 在 用 户 事 件 对 话 框中, 输 入 如 下 的 值:

 EventNameEventID
addhscrollpbm_custom01
addvscrollpbm_custom02
removehscrollpbm_custom03
removevscrollpbm_custom04
syscommandpbm_syscommand加入前四个自定义用户事件的语句为:ADDHSCROLL事件//加入卷滚条this.hscrollbar=TRUE
ADDVSCROLL事件//加入卷滚条this.vscrollbar=TRUE
REMOVEHSCROLL事件uint WinHandleinteger ScrollPos,MinPos,MaxPos//得到窗口句柄WinHandle=Handle(this)//得到滚动块在卷滚条上的当前位置ScrollPos=GetScrollPos(WinHandle,0)//得到卷滚条的滚动范围GetScrollRange(WinHandle,0,MinPos,MaxPos)//滚动窗口IF ScrollPos > MinPos THEN Send ( WinHandle, 276, 5, 0 )ScrollPos = GetScrollPos ( WinHandle, 0 )//消除滚动条this.hscrollbar=FALSE
REMOVEVSCROLLusereventuint WinHandleinteger ScrollPos,MinPos,MaxPosWinHandle = Handle ( this )ScrollPos = GetScrollPos ( WinHandle, 1 )GetScrollRange ( WinHandle, 1, MinPos, MaxPos )IF ScrollPos > MinPos THEN Send ( WinHandle, 277, 6, 0 )this.vscrollbar = FALSE我们还需要在resize事件中增加下列代码以决定什么时候调用这些自定义用户事件。RESIZEevent//如用户进行的是最小化窗口的操作,则返回。IF ib_minimized THEN ReturnELSE //否则考察是否需要卷滚条 IF this.width ii_desired_width AND this.hscrollbar THEN PostEvent( this, "RemoveHScroll" ) IF this.height > ii_desired_height AND this.vscrollbar THEN PostEvent( this, "RemoveVScroll" )END IF
在SYSCOMMAND 事件中有下列代码:SYSCOMMANDevent//如用户试图最小化窗口,则立即取消卷滚条IF message.wordparm = 61472 THEN ib_minimized = TRUE this.vscrollbar = FALSE this.hscrollbar = FALSEELSE ib_minimized = FALSEEND IF

工 作 原 理

       OPEN 事 件 中 的代 码 是 为 了 调 整 卷 滚 条 的 滚 动 速 度。AddHScroll 和AddVScroll 中的 代 码 分 别 加 入 水 平 和 垂 直 卷 滚 条。RemoveHScroll 和RemoveVScroll 除 分 别 移 去 水 平 和 垂 直 卷 滚 条 外, 还 要 使 用WindowsAPI 调用。

       GetScrollPos 函 数可 返 回 滚 动 块 在 卷 滚 条 上 的 当 前 位 置。 我 们 必 须 告 诉该 函 数 我 们 需 要 的 是 哪 个 窗 口 上 的 哪 个 卷 滚 条 的 信息。 在WindowsAPI 中,“ 指 向” 一 个 窗 口 的 方 法 是 通 过 引 用它 的“ 句 柄”。PowerBuilder 提 供 了 获 得 应 用 中 的 指 定 窗 口句 柄 的 函 数, 这 个 函 数 叫 作Handle()。 因 为 这 些 自 定 义用 户 事 件 是 在 窗 口 自 身 当 中 定 义 的, 所 以 我 们 只 需 要将“this” 作 为 参 数 传 递 给Handle 函 数。0 做 为 第 二 个 参 数,告 诉Handle 函 数 我 们 需 要 知 道 水 平 卷 滚 条 的 值; 而 传 递1 则 表 示 需 要 知 道 垂 直 卷 滚 条 的 值。

       通 过 将 当 前卷 滚 位 置 与 最 小 位 置 相 比 较, 我 们 就 会 知 道 用 户 是 否滚 动 过 窗 口。 如 果 滚 动 过 窗 口, 我 们 就 向 窗 口 发 送 一个 消 息 告 诉 它 将 窗 口 恢 复 原 状。 与WM_VSCROLL 和WM_HSCROLL 消 息相 对 应 的 消 息 号 分 别 是227 和226。 在WM_VSCROLL 中, 我 们 发 送SB_TOP(6),它 使 窗 口 滚 动 到 顶 部。 在WM_HSCROLL 中, 我 们 发 送5 使 窗 口滚 动 到 左 边。

       当 用 户 试 图最 小 化 或 最 大 化 窗 口 时, 卷 滚 条 的 行 为 会 有 不 同。 我们 知 道,PowerBuilder 的resize 事 件 所 映 射 的Windows 事 件 —WM_SIZE 是在 一 个 窗 口 被 改 变 大 小 以 后 触 发 的。 而 当 用 户 试 图 最小 化 一 个 窗 口 时, 我 们 需 要 在 最 小 化 发 生 之 前 关 闭 卷滚 条。 因 此, 在 这 种 情 况 下resize 事 件 中 的 代 码 是 来 不及 起 作 用 了。 在 这 里, 我 们 采 取 的 方 法 是 定 义 了 一 个映 射 到WM_COMMAND 消 息 的 事 件。 当 用 户 试 图 最 小 化 窗 口时, 随 该 消 息 一 起 发 送 的 值 是61472。 因 此, 如 果 该 事 件的 值 是61472, 我 们 只 需 简 单 地 移 去 卷 滚 条。 问 题 是 完 成这 些 操 作 后, 系 统 还 将 激 发 一 个resize 事 件,resize 事 件 中是 引 入 实 例 变 量ib_minimized 的 地 方。 在syscommand 事 件 中 我 们设 定 实 例 变 量, 在resize 事 件 中, 检 查 该 变 量。 该 变 量 告诉resize 事 件 用 户 正 在 最 小 化 窗 口, 于 是resize 事 件 就 不 会处 理 卷 滚 条。 如 果 用 户 将 窗 口 复 原,syscommand 事 件 将 再次 被 激 发, 但 这 次 传 递 给 消 息 的 值 就 不 是61472 了。 因 此syscommand 事 件 中 仅 仅 将 实 例 变 量 标 识 复 位。 于 是resize 事 件 就 又能 处 理 卷 滚 条 了。


 使用PowerBuilder另外的500个函数(上)相关说明
 使用PowerBuilder另外的500个函数(上)相关说明

 

 书籍教程站内推荐信息
 书籍教程网站地图