[SOLVED] Get text from StatusBar in Windows by WinAPI

Issue

This Content is from Stack Overflow. Question asked by Al Li

I am writing a automation for one program. I can get HWND of StatusBar by FindWindowExA but it has child TextControls that contains a text which i want to get. How to get text from that child controls?

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

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

__stdcall BOOL f11(HWND p1, LPCSTR p2, HANDLE p3)
{
    char *p = (char *)p3;
    HANDLE h1 = GetPropA(p1, p2);
    std::cout << "enum " << p1 << " " << p2 << " " << p3 << " " << h1 << std::endl;
    return 1;
}

__stdcall BOOL proc1(HWND wnd, LPARAM p)
{
    //
    GetClassNameA(wnd, buf3, 1024);
    GetWindowTextA(wnd, buf, 1024);
    std::cout << "child " << 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!! " << len << " " << buf3 << std::endl;
        EnumPropsA(wnd, f11);
        EnumChildWindows(wnd, proc1, 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!! 0
enum 0x80b72

For example notepad has the TextControls in StatusBar which is seen in Inspect Object from WinSDK.



Solution

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.


This Question was asked in StackOverflow by Al Li and Answered by Anders It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?