I am writing an automation for a program. I can get the HWND
of its StatusBar
by FindWindowExA()
, and it has child TextControl
s 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 TextControl
s in its StatusBar
, which is seen in Inspect Object from WinSDK.
In 7zFileManager, the StatusBar
contains TextControl
s. 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.