解决方案 »

  1.   

    GroupBox的类名怎么是Button呢?你看错了吧。
      

  2.   

    将 "Button" 改为 vbNullString 试试。
      

  3.   

    就是这个界面
    我用SPY++ 查设定变量框的类名,类名是Button。试过用坐标定位的方法,可以取到“设定变量”的句柄,但要获取“设定变量”里面的控件,试过两种方法:1.通过FindWindowsEx来获取框里的控件句柄,结果为零,2.尝试直接用坐标定位,结果是“设定变量”的句柄。还试过用GetDlgItem函数,获取“设定变量”的句柄,但获取出来句柄为零。4楼的朋友,我刚刚也试了,把“Button”改成vbnullstring,结果为零。
      

  4.   

    我也查了一下资料,GroupBox是属于“Button“。
    GroupBox类名为Button的,
     BS_PUSHBUTTON,BS_DEFPUSHBUTTON //按钮
     BS_CHECKBOX //多选、单选
     BS_GROUPBOX //组选框
     BS_RADIOBUTTON // 单选组合框 
      

  5.   

    请先确认 hwnd0 非零!
      

  6.   


    hwnd0是非零,hwnd0取的是B程序运行的窗体句柄。
      

  7.   

    展开 Spy++ 右侧的树结构,确认 “设定变量” 在 hwnd0 下面。
    用 Spy++ 获取的句柄,调用 GetClassName 和 GetWindowText 确认一下类名和标题。
      

  8.   

    仅供参考,尽管是C++
    HWND MyFindListViewWindow()
    {
        const int MyMaxParentWinCount = 4;
        // 父窗口类名数组
        char *A_szClassName[MyMaxParentWinCount] = {
            "ThunderRT6FormDC",
            "ThunderRT6Frame",
            "ThunderRT6Frame",
            "ListView20WndClass"
        };
        // 父窗口标题数组
        char *A_szWinName[MyMaxParentWinCount] = {
            Title,
            "",
            "",
            ""
        };
        // 首先求得顶级父窗口
        HWND hMainWin = FindWindow(A_szClassName[0], A_szWinName[0]);
        if (NULL==hMainWin) {
            return NULL;
        }
        // 逐次用FindWindowEx函数求出各级子窗口
        HWND hNextChildWin=NULL;    HWND hLastWin=NULL;
        for (int i=1; i<MyMaxParentWinCount; i++) {
            if (1==i) {
                hMainWin = FindWindowEx(hMainWin,NULL         ,A_szClassName[i],A_szWinName[i]);
            } else if (2==i) {
                hNextChildWin = FindWindowEx(hMainWin,hNextChildWin,A_szClassName[i],A_szWinName[i]);
                if (NULL==hNextChildWin) break;//
                hNextChildWin = FindWindowEx(hMainWin,hNextChildWin,A_szClassName[i],A_szWinName[i]);
                hLastWin=hNextChildWin;
            } else {
                hLastWin = FindWindowEx(hLastWin,NULL         ,A_szClassName[i],A_szWinName[i]);
            }
        }
        return hLastWin;
    }
    //---------------------------------------------------------------------------
      

  9.   

    我用AccExploer2.0查了一下B程序的结构,如下:B程序[窗口-Visible]
      ┗---B程序[对话框-Visible]
          ┗---NAMELESS[窗口-Visible]
              ┗---NAMELESS[对话框-Visible]
                  ┗---NAMELESS[窗口-Visible]
                      ┗---NAMELESS[对话框-Visible]
                          ┗---应用[窗口-Visible]
                          ┗---NAMELESS[窗口-Visible]  ‘这个是那个设定变量里的ComboBox
                              ┗---NAMELESS[组合框-Visible]
                              ┗---NAMELESS[文字-Visible]
                              ┗---打开[按下按钮-Visible]
                              ┗---NAMELESS[组合框-Visible]
                                  ┗---NAMELESS[列表项目-Invisible]
                                  ┗---NAMELESS[列表项目-Invisible]
                                  ┗---NAMELESS[列表项目-Invisible]
                          ┗---重置[窗口-Visible]
                          ┗---NAMELESS[窗口-Visible]  ‘这个是那个设定变量里的RichTextBox
                              ┗---NAMELESS[可编辑文本-Visible]    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            ‘#32770是窗口或对话框的类名,hwnd0~hwnd4均可获取相应的句柄        Dim hwnd0 As Integer = FindWindow(vbNullString, ListBox1.Text)
            
            Dim hwnd1 As Integer = FindWindowEx(hwnd0, 0&, "#32770", "")        Dim hwnd2 As Integer = FindWindowEx(hwnd0, hwnd1, "#32770", "")        Dim hwnd3 As Integer = FindWindowEx(hwnd0, hwnd2, "#32770", "")        Dim hwnd4 As Integer = FindWindowEx(hwnd0, hwnd3, "#32770", "")        Dim hwnd5 As Integer = FindWindowEx(hwnd4, 0&, "Button", "应用")    End Sub我是先按照B程序的窗体名,用FindWindow函数获取B程序窗体的句柄;然后按照用AccExploer查询出来的结构一层层进入,但到了最后hwnd5还是为零。我想应该是程序没有写对,导致hwnd5为零,请问各大高手,程序该如何写呢?
      

  10.   

    虽然没用过 AccExploer2,但是“NAMELESS[窗口-Visible]”表示没有取到类名没错吧?
    作为一个专业工具会取不到类名?
    首先怀疑杀毒软件之类的屏蔽了某些跨进程操作!
      

  11.   

    句柄变量使用 Long 型。
      

  12.   

    获取控件的句柄已解决。我是用对窗体控件遍历的方法,将句柄取出。现在遇到一个新的问题,就是用SetWindwText设置或更变不了TextBox或RichTextBox里的内容,但可以设置窗体的标题。这就真的很奇怪了,搞不明白怎么回事,还得麻烦各位,帮我看看程序有什么问题。    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
            '_intCboHwnd是设置变量里ComboBox的句柄,_intTxtHwnd是设置变量里RichTextBox的句柄
            SendMessage(_intCboHwnd, CB_SETCURSEL, 0, 0)    '指向指定记录号
            'SendMessage(_intTxtHwnd, WM_SETFOCUS, 0&, 0&)         SetWindowText(_intTxtHwnd, "0537")
        End Sub我当时也怀疑过是不是句柄不正确导致的,我又重新做了两个窗体Form1和Form2,Form1负责控制,Form2负责接收(Form2里有一个RichTextBox和一个TextBox),但结果一样,就只能更改Form2窗体的标题。
    Public Class Form1
        Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Integer, ByVal lpString As String) As Integer
        Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
        Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hwnd1 As Integer, ByVal hWnd2 As Integer, ByVal lpsz1 As String, ByVal lpsz2 As String) As Integer
        Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim hwnd0 As Integer = 0
            
            ‘可以更改Form2的窗体标题
            hwnd0 = FindWindow(vbNullString, "Form2")
            SetWindowText(hwnd0, "更改1")
            
            ‘这是RichTextBox控件,程序执行完后这段后,RichTextBox控件没有任何的变化
            hwnd0 = FindWindowEx(hwnd0, 0&, "WindowsForms10.RichEdit20W.app.0.bf7771", "")
            SetWindowText(hwnd0, "更改2")
            
            ‘这是TextBox控件,程序执行完后这段后,TextBox控件没有任何的变化
            hwnd0 = FindWindowEx(hwnd0, 0&, "WindowsForms10.EDIT.app.0.bf7771", "")
            SetWindowText(hwnd0, "更改3")
        End Sub
    End Class请问各大高手,这该怎么改呢?
      

  13.   

    FindWindowEx 返回值为 0 吧!调用 API 是要用 vbNullString 表示 null,"" 表示长度为 0 的字符串,意义完全不同。
      

  14.   

    仅供参考,尽管不是VB6:
    void MyGetListViewItem(HWND hWindow) {    int          nLVItemCount;
        int          nColumns;
        DWORD        dwProcessID;
        HANDLE       hProcess;
        HWND         hHeaderCtrl;
        LVITEM       lvItemLocal;
        HDITEM       hdItemLocal;
        DWORD        dwBytesRead, dwBytesWrite;
        BOOL         bSuccess,bWriteOK;
        LPVOID       lpTextRemote;
        LPVOID       lpListItemRemote;
        LPVOID       lpHeadItemRemote;
        int i,j;    GetWindowThreadProcessId(hWindow,&dwProcessID);
        hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessID);
        if (!hProcess) goto ABORT0;
        lpTextRemote=VirtualAllocEx(hProcess,NULL,nMaxLen+1,MEM_COMMIT,PAGE_READWRITE);
        if (!lpTextRemote) goto ABORT1;
        lpListItemRemote=VirtualAllocEx(hProcess,NULL,sizeof(LVITEM),MEM_COMMIT,PAGE_READWRITE);
        if (!lpListItemRemote) goto ABORT2;
        lpHeadItemRemote=VirtualAllocEx(hProcess,NULL,sizeof(HDITEM),MEM_COMMIT,PAGE_READWRITE);
        if (!lpHeadItemRemote) goto ABORT3;    nLVItemCount=ListView_GetItemCount(hWindow);
        hHeaderCtrl =ListView_GetHeader(hWindow);
        nColumns    =Header_GetItemCount(hHeaderCtrl);//  init();
        if (nColumns<=0) {
            nColumns=1;
        } else {
            ln[0]=0;
            for (j=0;j<nColumns;j++) {
                ZeroMemory(szBuf,nMaxLen+1);
                bWriteOK= WriteProcessMemory(hProcess,lpTextRemote,(LPVOID)szBuf,nMaxLen+1,(LPDWORD)&dwBytesWrite);
                if (!bWriteOK) goto ABORT4;
                hdItemLocal.mask=HDI_TEXT;
                hdItemLocal.cchTextMax=nMaxLen;
                hdItemLocal.pszText=(LPTSTR)lpTextRemote;
                dwBytesWrite=0;
                bWriteOK=WriteProcessMemory(hProcess,lpHeadItemRemote,(LPVOID)&hdItemLocal,sizeof(HDITEM),(LPDWORD)&dwBytesWrite);
                if (!bWriteOK) goto ABORT4;
                SendMessage(hHeaderCtrl,HDM_GETITEM,(WPARAM)j,(LPARAM)lpHeadItemRemote);
                bSuccess=ReadProcessMemory(hProcess,lpTextRemote,szBuf,nMaxLen+1,&dwBytesRead);
                if (!bSuccess) goto ABORT4;
                if (j>0) strcat(ln,"|");
                strstrip(szBuf1,szBuf);
                strcat(ln,szBuf1);
            }
            add1(ln);
        }
    //  printf("ListView的Columns数: %d\n",nColumns);
    //  printf("---------------------------\n");
        for (i=0;i<nLVItemCount;i++) {
            ln[0]=0;
            for (j=0;j<nColumns;j++) {
                ZeroMemory(szBuf,nMaxLen+1);
                bWriteOK= WriteProcessMemory(hProcess,lpTextRemote,(LPVOID)szBuf,nMaxLen+1,(LPDWORD)&dwBytesWrite);
                if (!bWriteOK) goto ABORT4;
                lvItemLocal.iItem=i;
                lvItemLocal.iSubItem=j;
                lvItemLocal.mask=LVIF_TEXT;
                lvItemLocal.cchTextMax=nMaxLen;
                lvItemLocal.pszText=(LPTSTR)lpTextRemote;
                dwBytesWrite=0;
                bWriteOK=WriteProcessMemory(hProcess,lpListItemRemote,(LPVOID)&lvItemLocal,sizeof(LVITEM),(LPDWORD)&dwBytesWrite);
                if (!bWriteOK) goto ABORT4;
                SendMessage(hWindow,LVM_GETITEMTEXT,(WPARAM)i,(LPARAM)lpListItemRemote);
                bSuccess=ReadProcessMemory(hProcess,lpTextRemote,szBuf,nMaxLen+1,&dwBytesRead);
                //从指定进程存储空间读取文本
                if (!bSuccess) goto ABORT4;
                if (j>0) strcat(ln,"|");
                strstrip(szBuf1,szBuf);
                strcat(ln,szBuf1);
            }
            add1(ln);
        }
    ABORT4:
        VirtualFreeEx(hProcess,lpHeadItemRemote,0,MEM_RELEASE);
    ABORT3:
        VirtualFreeEx(hProcess,lpListItemRemote,0,MEM_RELEASE);
    ABORT2:
        VirtualFreeEx(hProcess,lpTextRemote,0,MEM_RELEASE);
    ABORT1:
        CloseHandle(hProcess);
    ABORT0:
    //  over();
        return;
    }
    //---------------------------------------------------------------------------
      

  15.   


    在setwindowtext 之前确认一下,句柄是否正确
    你确定,那个textbox和richbox 的类名没写错? 貌似这是。net的程序窗口类名
    如果setwindowtext 不行, 可以试试 EM_ReplaceSel,EM_xxx, 最好先spy监看一下消息
      

  16.   

    不要用setwindowtext , 好像不行,我是用PostMessage实现的:    aWnd = FindWindow("notepad", vbNullString)
        If aWnd = 0 Then
            Shell "notepad.exe", vbNormalNoFocus
            aWnd = FindWindow("notepad", vbNullString)
        End If    Dim editWnd As Long
        editWnd = FindWindowEx(aWnd, 0, "edit", vbNullString)
        
        Dim stmp As String, c As String
        stmp = Text1.Text
        For i = 1 To Len(stmp)
            c = Mid(stmp, i, 1)
            call PostMessage(editWnd, WM_CHAR, CLng(Asc(c)), 0)
            'WM_SETTEXT 失败,为乱码
            Sleep 100
        Next