VB Code:
  1. 'In Module:
  2. Option Explicit
  3.  
  4. Const GWL_WNDPROC = -4
  5. Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal ndx As Long, ByVal newValue As Long) As Long
  6. 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
  7.  
  8. Private Type mtypWindowInfoUDT
  9.     hWnd        As Long
  10.     OldWndProc  As Long
  11.     MsgHook     As MsgHook
  12. End Type
  13.  
  14. Dim mudtWindowInfo()        As mtypWindowInfoUDT
  15. Dim mlngmudtWindowInfoCount As Long
  16.  
  17. Public Sub HookWindow(ByRef pobjMsgHook As MsgHook, ByVal hWnd As Long)
  18.     If mlngmudtWindowInfoCount = 0 Then
  19.         ReDim mudtWindowInfo(10) As mtypWindowInfoUDT
  20.     ElseIf mlngmudtWindowInfoCount > UBound(mudtWindowInfo) Then
  21.         ReDim Preserve mudtWindowInfo(mlngmudtWindowInfoCount + 9) As mtypWindowInfoUDT
  22.     End If
  23.     mlngmudtWindowInfoCount = mlngmudtWindowInfoCount + 1
  24.     With mudtWindowInfo(mlngmudtWindowInfoCount)
  25.         .hWnd = hWnd
  26.         Set .MsgHook = pobjMsgHook
  27.         .OldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WndProc)
  28.     End With
  29. End Sub
  30.  
  31. Public Sub UnhookWindow(ByRef pobjMsgHook As MsgHook)
  32. Dim lngIndex        As Long
  33.     For lngIndex = 1 To mlngmudtWindowInfoCount
  34.         If mudtWindowInfo(lngIndex).MsgHook Is pobjMsgHook Then
  35.             SetWindowLong mudtWindowInfo(lngIndex).hWnd, GWL_WNDPROC, mudtWindowInfo(lngIndex).OldWndProc
  36.             mudtWindowInfo(lngIndex) = mudtWindowInfo(mlngmudtWindowInfoCount)
  37.             mlngmudtWindowInfoCount = mlngmudtWindowInfoCount - 1
  38.             Exit For
  39.         End If
  40.     Next lngIndex
  41. End Sub
  42.  
  43. Public Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  44. Dim lngIndex    As Long
  45. Const WM_DESTROY = &H2
  46.     For lngIndex = 1 To mlngmudtWindowInfoCount
  47.         If mudtWindowInfo(lngIndex).hWnd = hWnd Then
  48.             WndProc = mudtWindowInfo(lngIndex).MsgHook.WndProc(hWnd, uMsg, wParam, lParam, mudtWindowInfo(lngIndex).OldWndProc)
  49.             If uMsg = WM_DESTROY Then
  50.                 Call mudtWindowInfo(lngIndex).MsgHook.StopSubclass
  51.             End If
  52.             Exit For
  53.         End If
  54.     Next lngIndex
  55. End Function
and...
VB Code:
  1. 'In a class
  2. Option Explicit
  3.  
  4. Event BeforeMessage(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByRef RetValue As Long, ByRef Cancel As Boolean)
  5. Event AfterMessage(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long)
  6.  
  7. Private mlnghWnd As Long
  8.  
  9. Public Sub StartSubclass(ByVal hWnd As Long)
  10.     If mlnghWnd Then
  11.         Call StopSubclass
  12.     End If
  13.     mlnghWnd = hWnd
  14.     If mlnghWnd Then
  15.         Call HookWindow(Me, mlnghWnd)
  16.     End If
  17. End Sub
  18.  
  19. Public Sub StopSubclass()
  20.     If mlnghWnd Then
  21.         Call UnhookWindow(Me)
  22.     End If
  23. End Sub
  24.  
  25. Friend Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal oldWindowProc As Long) As Long
  26. Dim blnCancel   As Boolean
  27. Dim lngRet      As Long
  28.     RaiseEvent BeforeMessage(hWnd, uMsg, wParam, lParam, lngRet, blnCancel)
  29.     If Not blnCancel Then
  30.         lngRet = CallWindowProc(oldWindowProc, hWnd, uMsg, wParam, lParam)
  31.     End If
  32.     RaiseEvent AfterMessage(hWnd, uMsg, wParam, lParam)
  33.     WndProc = lngRet
  34. End Function
  35.  
  36. Private Sub Class_Terminate()
  37.     Call StopSubclass
  38. End Sub