我实在想不明白我的问题所以来请教一下您希望能给个明灯。。 其实也就是句柄问题.我的程序上面有一个StatusBar1控件.增加了3个Panels.现在我想再另外写一个软件来实时监控第二个Panels的text。可是我在网上找了很多都没解决掉。也试过用EnumChildWindows(hFrm, @TryGetText, LPARAM(Self))获取父窗口然后列举所有子窗口也没有成功。。 
  所以想请大哥帮帮忙看看如何才能获取得到,晚上可以再加分

解决方案 »

  1.   

    1.用SPY++偷看一下那个Panels的句柄,
      如果SPY++都看不到,你再怎么Enum也是没用的2.那个程序能不能给个下载地址,方便我们试试
      

  2.   

    两个程序都是你写的不好办吗,进程间通讯有很多方法.消息,管道,内存文件,COM...
      

  3.   


    1:用SPY++也看不到~~只看到panels的第一个值.第二个和第三个都看不到。。但是既然程序都能找到相应的方式更新那一个值。应该有相关的句柄才对呀。。难道panels后二个值是画上去的?不明白...
    2:就是在delphi上面增加一个StatusBar1控件,然后建几个子就可以测试了呀。没有下载地址
      

  4.   

    StatusBar的Panel并没有句柄,StatusBar才有。获取本进程或其他进程中StatusBar的Panel文本,可以通过向StatusBar发送SB_GETTEXT消息来搞定,不过需要注意的是,如果是获取其他进程中的StatusBar信息,需要注入到目标进程,开辟缓冲,获取Panel文本后再用ReadProcessMemory读回。
      

  5.   


    谢谢你的思路
    但是我想的是在不改变"被监控"的软件结构就能由监控软件来获取得到他的值
    我也知道除了直接找到他的相关位置然后取他用getwindowtext方式取得他的值之外还可以用读取他的内取来获得相关值。
    我只是想知道为什么没有找不到他的句柄
      

  6.   

    楼主显然没有看到我在6楼的回复。只要成功获取到StatusBar的句柄(通过FindWindow/FindWindowEx/EnumWindows等都可以),读取文本用SB_GETTEXT消息。
      

  7.   


    楼上的朋友不好意思呀刚刚洗了个澡..我看了一下SB_GETTEXT这个参数..但是不知道怎么将值读出来.下面是我写的。如何才能改成我需要的效果呢(是不是要将DLL注入到某窗体上呢?)
    function HandleTEXT(Handlea:THandle):string;
    var
      s:array[0..255]   of   Char;
      dw:DWORD;
    begin
      SendMessage(Handlea,   SB_GETTEXT,Length(S),   Integer(@S));
      Result:=S;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      HWindow,hedit:   THandle;   //句本柄变量
      szText:   string;       //得到的字符串
    begin
      HWindow:=0;
      HWindow:=FindWindow(nil,'学习句柄');
      HWindow:=FindWindowEx(HWindow,0,'TStatusBar',nil);//找Sta句柄
      szText:=HandleTEXT(HWindow); //将sta的pan值取出来
      ShowMessage(IntToStr(HWindow));
      ShowMessage(szText);
    end;
      

  8.   

    上面这个例子只适合读取本进程的StatusBar信息。
    我这里有一段C++的代码,你自己翻译成Delphi代码就可以了:void __stdcall CrnGetStatusBarItem(HANDLE hStatusBar, TStrings *pList)
    {
        DWORD dwProcessID;
        HANDLE hProcess;
        LPVOID lpCommon;
        int nAllocSize = 255;
        int nPnlLen;
        char szBuf[255];
        DWORD dwBytesRead;
        int nPnlCount = SendMessage(hStatusBar, SB_GETPARTS, 0, 0);
        pList->Add("StatusBar的项目数: " + String(nPnlCount));    GetWindowThreadProcessId(hStatusBar, &dwProcessID);
        hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ |
                PROCESS_VM_WRITE, false, dwProcessID);
        lpCommon = VirtualAllocEx(hProcess, NULL, nAllocSize,
                MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);    for(int i=0; i<nPnlCount; i++)
        {
            SendMessage(hStatusBar, SB_GETTEXT, i, LPARAM(lpCommon));
            ReadProcessMemory(hProcess, lpCommon, szBuf, 255, &dwBytesRead);
            pList->Add(szBuf);
        }
        VirtualFreeEx(hProcess, lpCommon, 0, MEM_RELEASE);
        CloseHandle(hProcess);
    }
      

  9.   

    干脆好事做到底,帮你翻译了过来,并做了测试:
    uses commctrl;procedure CrnGetStatusBarItem(hStatusBar: THandle; pList: TStrings);
    var
        dwProcessID: DWORD;
        hProcess: THandle;
        lpCommon: Pointer;
        nAllocSize: integer;// = 255;
        szBuf: array [0..255] of char;
        dwBytesRead: DWORD;
        nPnlCount: integer;
        i: integer;
    begin
        nAllocSize := 255;
        nPnlCount := SendMessage(hStatusBar, SB_GETPARTS, 0, 0);
        pList.Add('StatusBar的项目数: ' + IntToStr(nPnlCount));    GetWindowThreadProcessId(hStatusBar, @dwProcessID);
        hProcess := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ, false, dwProcessID);
        lpCommon := VirtualAllocEx(hProcess, nil, nAllocSize,
                MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);    for i := 0 to nPnlCount - 1 do
        begin
            SendMessage(hStatusBar, SB_GETTEXT, i, LPARAM(lpCommon));
            ReadProcessMemory(hProcess, lpCommon, @szBuf, 255, dwBytesRead);
            pList.Add(szBuf);
        end;    VirtualFreeEx(hProcess, lpCommon, 0, MEM_RELEASE);
        CloseHandle(hProcess);
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
        hTopWnd, hWnd: THandle;
    begin
        hTopWnd := FindWindow('MSPaintApp', nil);
        if IsWindow(hTopWnd) then
        begin
            hWnd := FindWindowEx(hTopWnd, 0, 'msctls_statusbar32', nil);
            if IsWindow(hWnd) then
                CrnGetStatusBarItem(hWnd, Memo1.Lines);
        end;
    end;在窗体上添加一个按钮和一个Memo,然后打开画笔(mspaint.exe),编译并运行这个程序,点击按钮就可以看到效果。
      

  10.   

    谢谢大哥...不过在delphi的sta中用'msctls_statusbar32' 这一个值并不能获取pan。要换成TStatusBar。。嘿嘿。真的很感谢
      

  11.   


    是的,VCL中的状态栏,类名是TStatusBar,而Windows的状态栏原生类名是msctls_statusbar32