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.