以下是替换窗口过程的代码,如果正常运行是不会有问题的,但在调试的时候,中途退出程序,vb就自动退出。Public Sub HookWindow(ByVal hwnd As Long)
g_pfnPrevProc = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub
Public Sub UnHookWindow(ByVal hwnd As Long)
Call SetWindowLong(hwnd, GWL_WNDPROC, g_pfnPrevProc)
End Sub
Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If uMsg = WM_VSCROLL Then
Dim nRequest As Integer
Dim nPos As Integer
Call DivideDWORD(wParam, nRequest, nPos)
Select Case nRequest
Case SB_LINEUP
wParam = SB_PAGEUP
Case SB_LINEDOWN
wParam = SB_PAGEDOWN
Case SB_THUMBPOSITION
Debug.Print nPos
Case SB_THUMBTRACK
End Select
ElseIf uMsg = WM_MOUSEWHEEL Then
uMsg = WM_VSCROLL
If wParam > 0 Then
wParam = SB_PAGEUP
Else
wParam = SB_PAGEDOWN
End If
End If
WindowProc = CallWindowProc(g_pfnPrevProc, hwnd, uMsg, wParam, lParam)
End Function
Public Sub DivideDWORD(ByVal nTarget As Long, nLowWord As Integer, nHiWord As Integer) Dim strParam As String
strParam = Right$("00000000" & Hex$(nTarget), 8)
nLowWord = CInt("&H" & Right$(strParam, 4))
nHiWord = CInt("&H" & Left$(strParam, 4))
End Sub
g_pfnPrevProc = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub
Public Sub UnHookWindow(ByVal hwnd As Long)
Call SetWindowLong(hwnd, GWL_WNDPROC, g_pfnPrevProc)
End Sub
Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If uMsg = WM_VSCROLL Then
Dim nRequest As Integer
Dim nPos As Integer
Call DivideDWORD(wParam, nRequest, nPos)
Select Case nRequest
Case SB_LINEUP
wParam = SB_PAGEUP
Case SB_LINEDOWN
wParam = SB_PAGEDOWN
Case SB_THUMBPOSITION
Debug.Print nPos
Case SB_THUMBTRACK
End Select
ElseIf uMsg = WM_MOUSEWHEEL Then
uMsg = WM_VSCROLL
If wParam > 0 Then
wParam = SB_PAGEUP
Else
wParam = SB_PAGEDOWN
End If
End If
WindowProc = CallWindowProc(g_pfnPrevProc, hwnd, uMsg, wParam, lParam)
End Function
Public Sub DivideDWORD(ByVal nTarget As Long, nLowWord As Integer, nHiWord As Integer) Dim strParam As String
strParam = Right$("00000000" & Hex$(nTarget), 8)
nLowWord = CInt("&H" & Right$(strParam, 4))
nHiWord = CInt("&H" & Left$(strParam, 4))
End Sub
原因就是,程序启动后替换了目标窗口的窗口过程,但当vb调试是突然中断退出的话,由于没有将窗口过程替换为原来它的本身的窗口过程,结果出错退出。
现在能解决问题的办法是,在vb调试中断前将窗口过程还原,可是vb在调试中断前好像不会给我们的程序任何消息或事件,结果我就无法在vb中断程序之前将窗口过程还原。
exit sub
l:
msgbox"出错"
exit functionl:
msgbox"出错"
一、别在调试模式下运行,编译后再运行
二、写个ActiveDLL专门处理SubClass,可参考:http://www.easthot.net/dl_info.asp?id=133