前两天看到一段代码,有点古怪,请大家帮忙看看因代码太长,已作修改,无关的删掉了,两个按钮cmdInstall和cmdUninstall是我加上去的
' ******************************** Form1.frm ********************************Option ExplicitPrivate m_oClass As cClssPrivate Sub Form_Load()
    Set m_oClass = New cClss
End SubPrivate Sub cmdInstall_Click()
    m_oClass.Install Me.hWnd, VarPtr(m_oClass) '??????
End SubPrivate Sub cmdUninstall_Click()
    m_oClass.Uninstall
End Sub' ******************************** cClss.cls ********************************Option ExplicitPrivate Const GWL_WNDPROC = (-4)Private Const WM_RBUTTONDOWN = &H204Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As LongPrivate 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 LongPrivate lpPrevWndProc As Long, hWndTarget As Long, aWndProc(0 To 52) As BytePublic Sub Install(ByVal hWnd As Long, ByVal p As Long)
    aWndProc(0) = &H51    'push   ecx
    aWndProc(1) = &H8D    'lea    edx,[esp]
    aWndProc(2) = &H54
    aWndProc(3) = &H24
    aWndProc(4) = &H0
    aWndProc(5) = &HA1    'mov    eax,[00000000]
    aWndProc(6) = &H0
    aWndProc(7) = &H0
    aWndProc(8) = &H0
    aWndProc(9) = &H0
    aWndProc(10) = &H52   'push   edx
    aWndProc(11) = &H8B   'mov    edx,dword ptr [esp+18h]
    aWndProc(12) = &H54
    aWndProc(13) = &H24
    aWndProc(14) = &H18
    aWndProc(15) = &H52   'push   edx
    aWndProc(16) = &H8B   'mov    edx,dword ptr [esp+18h]
    aWndProc(17) = &H54
    aWndProc(18) = &H24
    aWndProc(19) = &H18
    aWndProc(20) = &H52   'push   edx
    aWndProc(21) = &H8B   'mov    edx,dword ptr [esp+18h]
    aWndProc(22) = &H54
    aWndProc(23) = &H24
    aWndProc(24) = &H18
    aWndProc(25) = &H52   'push   edx
    aWndProc(26) = &H8B   'mov    edx,dword ptr [esp+18h]
    aWndProc(27) = &H54
    aWndProc(28) = &H24
    aWndProc(29) = &H18
    aWndProc(30) = &HC7   'mov    dword ptr [esp+10h],0
    aWndProc(31) = &H44
    aWndProc(32) = &H24
    aWndProc(33) = &H10
    aWndProc(34) = &H0
    aWndProc(35) = &H0
    aWndProc(36) = &H0
    aWndProc(37) = &H0
    aWndProc(38) = &H8B   'mov    ecx,dword ptr [eax]
    aWndProc(39) = &H8
    aWndProc(40) = &H52   'push   edx
    aWndProc(41) = &H50   'push   eax
    aWndProc(42) = &HFF   'call   dword ptr [ecx+1Ch]
    aWndProc(43) = &H51
    aWndProc(44) = &H24
    aWndProc(45) = &H8B   'mov    eax,dword ptr [esp]
    aWndProc(46) = &H44
    aWndProc(47) = &H24
    aWndProc(48) = &H0
    aWndProc(49) = &H59   'pop    ecx
    aWndProc(50) = &HC2   'ret    10h
    aWndProc(51) = &H10
    aWndProc(52) = &H0
    CopyMemory aWndProc(6), p, 4
    
    hWndTarget = hWnd
    lpPrevWndProc = SetWindowLong(hWndTarget, GWL_WNDPROC, VarPtr(aWndProc(0)))
End SubPublic Sub Uninstall()
    SetWindowLong hWndTarget, GWL_WNDPROC, lpPrevWndProc
End SubPublic Function WndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Select Case uMsg
        Case WM_RBUTTONDOWN
            MsgBox "ok"
    End Select
    WndProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, lParam)
End Function

解决方案 »

  1.   

    aWndProc(6) = &H0
    aWndProc(7) = &H0
    aWndProc(8) = &H0
    aWndProc(9) = &H0
    将被原来的窗口处理程序的入口地址(实际是指向入口的指针)取代,而这段汇编代码则被用来取代原来的窗口处理程序
    汇编早忘光了,大概意思吧。但内部操作不知道是什么。
      

  2.   

    我想province_(雍昊)可能弄错了:取代
    aWndProc(6) = &H0
    aWndProc(7) = &H0
    aWndProc(8) = &H0
    aWndProc(9) = &H0
    的是VarPtr(m_oClass),对象变量的内存地址,不是原来的窗口处理程序的入口地址
      

  3.   

    那你看看这个地址的内容是什么呢?
    不信的话,你可以试试把他的Private lpPrevWndProc As Long, hWndTarget As Long, aWndProc(0 To 52) As Byte换个位置吗?具体点就是如果把lpPrevWndProc、hWndTarget换位一下,保证非法操作。
      

  4.   

    to: province_(雍昊)Private lpPrevWndProc As Long, hWndTarget As Long, aWndProc(0 To 52) As Byte换位没有发现
    非法操作,不过public function WndProc(...) as long必须是第三个公有的函数或过程,不能增加公有变量,可以在任意位置增加私有变量、过程或函数,可以在public function WndProc(...) as long后面增加公有的函数或过程