给你一篇文章作为参考啦....
----------------------------------------------------------------如何在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 后 定 时 器 被 清 除, 显 示 终 止。
----------------------------------------------------------------如何在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 后 定 时 器 被 清 除, 显 示 终 止。
我提的问题是,我开了一公司,请相助的那位?
讲的通俗点,就是在VB中写的函数,由API来调用的,而不是在VB中调用的。
先把VB中的函数的地址传到API里面,由API来调用的,主动权在API,VB中的
的回调函数是被动的。
Public Const HTCLIENT = 1
Public Const HTCAPTION = 2
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As LongPublic prevWndProc As LongFunction WndProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
WndProc = CallWindowProc(prevWndProc, hWnd, Msg, wParam, lParam)
If Msg = WM_NCHITTEST And WndProc = HTCLIENT Then
WndProc = HTCAPTION
End If
End Function
Private Sub Command1_Click()
Unload Me
End SubPrivate Sub Form_Load()
prevWndProc = GetWindowLong(Me.hWnd, GWL_WNDPROC)
SetWindowLong Me.hWnd, GWL_WNDPROC, AddressOf WndProc
End SubPrivate Sub Form_Unload(Cancel As Integer)
SetWindowLong Me.hWnd, GWL_WNDPROC, prevWndProc
End SubPrivate Sub Form_Paint()
ForeColor = vbBlue
Cls
Print
Print "我虽然没有标题区,但您可以在工作区按下鼠标,"
Print "然后把我拖曳到其它地方."
End Sub
'把代码拷贝可用