其实很多消息可以用某些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取得密码

解决方案 »

  1.   

    可能获取其他应用的文本矿的文本,只要你知道他的窗口句柄
    比如我有一个应用程序,其中有个文本框,我用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也逃不过,里边其实这是用消息,只是封装一下
      

  2.   

    密码框就是输入框,只是显示给你的是“×”好之类的,用GetWindowText 一样可以获得
    但是从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);