用活动的Windows消息钩子调试时VB6退出

Mar*_*rtW 2 vb6 hook winapi message

我们最大的旧版VB6应用程序中包含一些代码,允许其他应用程序(包括一些dotNET)通过Windows消息将ID传递给它 - 然后VB6应用程序使用此ID在常规Windows中加载条目形成.在用户登录并进行身份验证后添加消息挂钩,并在用户注销后将其删除.

Public Sub HookClaimFinderCall()
    lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Public Sub UnhookClaimFinderCall()
    Dim temp As Long
    If gHW <> 0 Then temp = SetWindowLong(gHW, GWL_WNDPROC, lpPrevWndProc)
End Sub

Private Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    If uMsg = WM_FINDCLAIM Then
        MasterFindClaim lParam
    End If
    WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)
End Function
Run Code Online (Sandbox Code Playgroud)

但是,这有两个问题.第一个涉及Visual Studio 6.如果正在调试代码,并且出现错误以显示"继续结束调试帮助"对话框,则按End会立即退出Visual Studio(丢失任何未保存的更改).如果尚未激活消息挂钩,则不会发生这种情况.是什么导致这种情况,有什么办法可以阻止它注释掉加载钩子的代码?

其次,如果用户退出应用程序而没有正确登出(通过任何方式),消息挂钩会发生什么?

我希望我在上面的所有条款都正确......

Kri*_*son 5

  1. 如果启动全局钩子并尝试在VB6中调试,您将崩溃(或消失VB6).VB6有点像模拟器,它并不完全复制VB6应用程序的运行时间,并且挂钩是它失败的地方之一(尽管如果你理解发生的事情,它不会被归咎于).对于我们在应用程序中使用的所有全局钩子,我们检查VB6是否在IDE模式下运行(有几种方法可以执行此操作),如果是,则不要运行全局钩子.如果你必须运行全局钩子,不要在调试器中停止应用程序 - 使用debug.print或其他一些方法,但不要停止应用程序,否则你将在它"消失"之前有几毫秒到几秒.
  2. 虽然你应该在退出应用程序之前取消挂钩,但是当消息泵命中钩子并且钩子发生的应用程序的句柄不再存在时,忽略该钩子是一个相当狡猾的操作.现在,如果您运行应用程序并退出数千次,它可能会累积,但我认为这是您最不关心的问题.