其实很多消息可以用某些api替代就不用subclass了,比如你这个WM_GetText 消息我可以用
GetWindowText 来替代Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String) As Long
Private Sub Form_Activate()
Dim MyStr As String
MyStr = String(100, Chr$(0))
GetWindowText Text1.hwnd, MyStr, 100
MyStr = Left$(MyStr, InStr(MyStr, Chr$(0)) - 1)
SetWindowText Text2.hwnd, MyStr
End Subtext1显示密码,text2取得密码
GetWindowText 来替代Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String) As Long
Private Sub Form_Activate()
Dim MyStr As String
MyStr = String(100, Chr$(0))
GetWindowText Text1.hwnd, MyStr, 100
MyStr = Left$(MyStr, InStr(MyStr, Chr$(0)) - 1)
SetWindowText Text2.hwnd, MyStr
End Subtext1显示密码,text2取得密码
比如我有一个应用程序,其中有个文本框,我用spy得到他的句柄是 &H1804A6(当然可以用其他api来获取,不使用spy,我这里仅仅是说明getwindowtext的api)
通过如下代码Private Sub Form_Activate()
Dim MyStr As String
MyStr = String(100, Chr$(0))
GetWindowText &H1804A6, MyStr, 100
end sub
我依然可以得到他的文本,不管怎么说windows是消息驱动的系统,它自己的api也逃不过,里边其实这是用消息,只是封装一下
但是从Windows2000开始,操作系统对这个方法做了防范,只要判断出你是想取出其他进程中密码框中的密码,这个函数调用就会失败
所以很多取密码的工具到了Windows2000下都失效了
就是因为它捕获到外进程发送过来的WM_GETTEXT 消息就扔掉当然我并不认为我一定是对的不过你可以验证一下,正好你有现成的例子。我调用GetWindowText 看是否它收到WM_GETTEXT 消息
Option ExplicitDeclare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public 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
Public Const WM_GETTEXT = &HD '获取文本框内容的消息
Public Const GWL_WNDPROC = (-4) ''建立一个消息处理函数需要的参数
Public OldProc As Long '保存旧的消息处理函数的地址
Public Function wnd(ByVal hwnd As Long, ByVal Msg As Long, ByVal wp As Long, ByVal lp As Long) As Long
If Msg = WM_GETTEXT Then
Form1.Caption = "Gotten"
End If
wnd = CallWindowProc(OldProc, hwnd, Msg, wp, lp) '如果不是我们要的消息则传递下去
End Functionform
----------
Option Explicit
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String) As LongPrivate Sub Command1_Click()
Dim MyStr As String
MyStr = String(100, Chr$(0))
GetWindowText Text1.hwnd, MyStr, 100
MyStr = Left$(MyStr, InStr(MyStr, Chr$(0)) - 1)
SetWindowText Text2.hwnd, MyStr
End SubPrivate Sub Form_Load()
OldProc = SetWindowLong(Text1.hwnd, GWL_WNDPROC, AddressOf wnd)
End SubPrivate Sub Form_Unload(Cancel As Integer)
SetWindowLong Text1.hwnd, GWL_WNDPROC, OldProc
End Sub试验证明它确实发送这个消息
发送消息是最直接高效的,但是用封装的API却容易多了
解决问题的方法不可能是唯一,每种方法也不会永远是最好的,很多情况就是因势利导。
提外话:网上流传获取windows2000密码的方法很简单就是加个延时
char Char;
char PassWord[255];
Char = SendMessage (MainWnd,EM_GETPASSWORDCHAR,0,0);
PostMessage (MainWnd,EM_SETPASSWORDCHAR,0,0);
Sleep (100);
SendMessage (MainWnd,WM_GETTEXT,255,long(PassWord));
PostMessage (MainWnd,EM_SETPASSWORDCHAR,Char,0);