Home > front end >  Get text from StatusBar in Windows by WinAPI
Get text from StatusBar in Windows by WinAPI

Time:09-20

I am writing an automation for a program. I can get the HWND of its StatusBar by FindWindowExA(), and it has child TextControls that contain text which I want to get. How to get the text from those child controls?

#include <iostream>
#include <windows.h>

char buf[1024];
char buf2[1024];
char buf3[1024];
char buf4[1024];

__stdcall BOOL EnumPropsCAllBack(HWND p1, LPCSTR p2, HANDLE p3)
{
    char *p = (char *)p3;
    HANDLE h1 = GetPropA(p1, p2);
    std::cout << "EnumProps " << p1 << " " << /*p2 << */" " << p3 << " " << h1 << std::endl;//reading p2 fails?
    return 1;
}

__stdcall BOOL EnumChildWindowsCAllBack(HWND wnd, LPARAM p)
{
    //
    GetClassNameA(wnd, buf3, 1024);
    GetWindowTextA(wnd, buf, 1024);
    std::cout << "EnumChildWindows " << wnd << " " << buf << " " << buf3 << std::endl;
    return 1;
}

void doHwndRecursive(HWND wnd, int gl, int fl)
{
    HWND wnd1 = 0;
    for(int i = 0; i < gl; i  )
        buf2[i] = ' ';
    buf2[gl] = 0;
    GetWindowTextA(wnd, buf, 1024);
    GetClassNameA(wnd, buf3, 1024);
    std::cout << buf2 << " " << wnd << " " << buf << " " << buf3 << std::endl;
    if(!strcmp(buf3, "msctls_statusbar32") || fl)
    {
        LRESULT len = SendMessageA(wnd, WM_GETTEXT, 255, LPARAM(buf3));
        std::cout << "Found StatusBar! " << len << " " << buf3 << std::endl;
        EnumPropsA(wnd, EnumPropsCAllBack);
        EnumChildWindows(wnd, EnumChildWindowsCAllBack, 0);
        fl = 1;
    }
    for(int i = 0; i < 1000; i  )
    {
        wnd1 = FindWindowExA(wnd, wnd1, 0, 0);
        if(wnd1 == 0)
            break;
        else
            doHwndRecursive(wnd1, gl   1, fl);
    }
}

int main()
{
    HWND wnd1 = 0;
    HWND wnd = 0;
    wnd = FindWindowExA(0, 0, 0, 0);
    for(int i = 0; i < 2000; i  ) // for not infinite loop
    {
        wnd = FindWindowExA(0, wnd, 0, 0);
        buf[1023] = 0;
        GetWindowTextA(wnd, buf, 1024);
        if(!strcmp(buf, "src.txt – notepad"))
        {
            wnd1 = 0;
            doHwndRecursive(wnd, 0, 0);
        }
        if(wnd == 0)
        {
            std::cout << "end " << std::endl;
            break;
        }
    }
    std::cout << wnd1 << std::endl;
    return 0;
}

Output is:

 0x5d088a src.txt - notepad Notepad
  0x2a0136  Edit
  0x80b72  msctls_statusbar32
Found StatusBar! 0
EnumProps 0x80b72  0x10005 0x10005
EnumProps 0x80b72  0x29a0000 0x29a0000
end
0

For example, Notepad has the TextControls in its StatusBar, which is seen in Inspect Object from WinSDK.

In 7zFileManager, the StatusBar contains TextControls. This method can get text from the first control. How to enumerate those controls by simple WinAPI and get their texts?

CodePudding user response:

The statusbar does not have child windows, the statusbar itself draws the panel sections (known as "parts").

It supports the SB_GETTEXTLENGTH and SB_GETTEXT messages but your memory buffer needs to be in the same process (VirtualAllocEx).

The correct solution is to use MSAA/UI automation where possible.

  • Related