前两天看到一段代码,有点古怪,请大家帮忙看看因代码太长,已作修改,无关的删掉了,两个按钮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
' ******************************** 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
aWndProc(7) = &H0
aWndProc(8) = &H0
aWndProc(9) = &H0
将被原来的窗口处理程序的入口地址(实际是指向入口的指针)取代,而这段汇编代码则被用来取代原来的窗口处理程序
汇编早忘光了,大概意思吧。但内部操作不知道是什么。
aWndProc(6) = &H0
aWndProc(7) = &H0
aWndProc(8) = &H0
aWndProc(9) = &H0
的是VarPtr(m_oClass),对象变量的内存地址,不是原来的窗口处理程序的入口地址
不信的话,你可以试试把他的Private lpPrevWndProc As Long, hWndTarget As Long, aWndProc(0 To 52) As Byte换个位置吗?具体点就是如果把lpPrevWndProc、hWndTarget换位一下,保证非法操作。
非法操作,不过public function WndProc(...) as long必须是第三个公有的函数或过程,不能增加公有变量,可以在任意位置增加私有变量、过程或函数,可以在public function WndProc(...) as long后面增加公有的函数或过程