答案:
如何在VB中使用回调(CallBack)过程 |
---- 回 调(CallBack) 过 程 是 应 用 程 序 内 部 的、Windows 系 统 可 以 调 用 的 过 程。 在windows 编 程 中, 回 调 过 程 的 使 用 是 很 普 遍 的, 最 明 显 的 例 子 是 窗 口 过 程 本 身 就 是 一 个 回 调 过 程, 应 用 程 序 窗 口 对 事 件 的 捕 获 就 是 由windows 调 用 相 应 的 窗 口 过 程 实 现 的。 用 过C 编 程 的 人 都 知 道 函 数 名 本 身 就 是 这 个 函 数 的 指 针, 调 用 它 其 实 就 是 调 用 了 函 数 体。 但 在VB 中 没 有 指 针 这 个 概 念, 如 果 想 在VB 中 使 用 回 调 过 程 可 得 费 一 番 周 折, 幸 好 在VB5 中 新 增 了AddressOf 运 算 符, 用 它 可 以 得 到 过 程 的 地 址, 这 样 就 大 大 简 化 了 在VB 中 使 用 回 调 过 程 的 难 度。 下 面 就 用 一 个 例 子 来 具 体 说 明 如 何 实 现: ---- Windows 提 供 了 定 时 器 这 种 输 入 设 备, 它 可 以 周 期 性 地 在 指 定 间 隔 的 时 间 过 去 时 通 知 应 用 程 序,VB 中 的Timer 控 件 就 是 经 过 封 装 的 定 时 器。SetTimer 函 数 用 来 分 配 定 时 器, 它 有 四 个 参 数:hwnd As Long 是 接 收WM_TIMER 消 息 的 窗 口 的 句 柄; nIDEvent As Long 定 时 器 的ID, 它 是 一 个 非0 数;uElapse As Long 是 指 定 的 一 个 时 间 间 隔, 以 毫 秒 为 单 位; lpTimerFunc As Long 定 时 器 函 数 的 过 程 实 例 地 址, 在 这 里 是 回 调 过 程 的 地 址。KillTimer 函 数 用 来 清 除 定 时 器:hwnd As Long 与 定 时 器 相 关 的 窗 口; nIDEvent As Long 定 时 器 的ID。 我 们 用AddressOf 操 作 符 建 立 回 调 过 程, 用 来 接 收 定 时 器 的 通 知, 需 要 注 意 的 是 回 调 过 程 必 须 建 立 在 标 准 模 块 中, 并 且 一 定 要 具 有 正 确 的 语 法, 由 于VB 不 提 供 语 法 检 查, 也 不 对 错 误 进 行 通 知, 因 此 在 回 调 过 程 中 使 用 错 误 的 语 法 将 会 导 致 致 命 的 错 误, 而 使 程 序 崩 溃。 ---- 创 建 一 新 的EXE 项 目, 在 窗 体 上 放 置 一ProgressBar 和Command 控 件, 添 加 一 模 块, 给 模 块 添 加API 函 数 的 声 明: ---- Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long ---- Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long Public id_timer As Integer 用来存放返回的定时器的ID Const inc_step As Integer = 5 设置ProgressBar值的增量 ---- Starttimer 过 程 调 用SetTimer 函 数 生 成 定 时 器,hwnd 和nIDEvent 送 入0 表 示 在 回 调 过 程 中 不 使 用 它 们,uElapse 置 为100, 让 程 序 每100 毫 秒 就 调 用 一 次 回 调 函 数;lpTimerFunc 参 数 由AddressOf TimerProc 将TimerProc 的 地 址 送 入 函 数。 Public Sub starttimer() Id_timer = SetTimer(0, 0, 100, AddressOf timerproc) Form1.ProgressBar1.Value = 0 Form1.Command1.Caption = "Stop" End Sub Endtimer清除定时器,同时给用户一个信息反馈。 Public Sub endtimer() KillTimer 0, id_timer id_timer = 0 MsgBox "Timer has been killed!", vbExclamation, "Done!" Form1.Command1.Caption = "Start" End Sub Updateprogressbar过程用来更新进程条的显示。 Public Sub updateprogressbar() Dim percentdone As Integer percentdone = Form1.ProgressBar1.Value + inc_step If percentdone > 100 Then Form1.ProgressBar1.Value = 100 endtimer Else Form1.ProgressBar1.Value = percentdone End If End Sub ---- 建 立 回 调 过 程, 这 里 回 调 过 程 只 是 调 用updateprogressbar 过 程 来 更 新 显 示。 Public Sub TimerProc() updateprogressbar End Sub Private Sub Command1_Click() If id_timer > 0 Then endtimer Else starttimer End If End Sub ---- 保 存 并 测 试 该 应 用 程 序,Start 钮 激 活 定 时 器, 系 统 开 始 周 期 性 地 调 用 回 调 函 数, 定 时 器 被 连 续 激 活( 进 程 条 不 断 更 新), 到100 或 按Stop 后 定 时 器 被 清 除, 显 示 终 止。 以 上 代 码 在VB5 专 业 版,Pwin98 操 作 系 统 下 运 行 通 过。 ---- 何 如 在VB 中 使 用 回 调(CallBack) 过 程 |