Qt/C++ 获取QProcess启动的第三方软件的窗体标题
Qt/C++ 获取QProcess启动的第三方软件的窗体标题,在使用EnumWindows获取窗体句柄(HWND)时,如果返回提前FALSE,则获取到的HWND状态IsWindow正常,但就是获取不到窗体标题。必须正常返回TRUE才能使用HWND获取到窗体标题,要不然获取到的标题内容就是空。
QProcess线程需要在启动后等待几秒的时间再获取打开的窗体句柄,或者一直While(true)获取窗体句柄直到获取HWND不为空为止。
目录
- 使用EnumWindows获取所有窗体句柄和PID
- 写法1
- 写法2
- 获取窗体标题
- 使用 GetWindowTextA 获取窗体标题
- 使用 SendMessage获取窗体标题
- 使用 DefWindowProcA获取窗体标题
- 使用 GetClassNameA获取窗体类名称
- 使用FindWindowEx获取窗体句柄
使用EnumWindows获取所有窗体句柄和PID
写法1
static HWND GHO_HWMD_C=nullptr;
static BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
{
DWORD processId;
GetWindowThreadProcessId(hwnd, &processId);
if (processId == (DWORD)lParam)
{
GHO_HWMD_C=hwnd;
}
///必须返回true 如果返回false 会造成HWND不能获取窗体标题,修改窗体隐藏等属性
return TRUE;
}
static BOOL CALLBACK EnumThreadChildProc(HWND hwnd, LPARAM lParam)
{
DWORD processId;
GetWindowThreadProcessId(hwnd, &processId);
if (processId == (DWORD)lParam)
{
GHO_HWMD_C=hwnd;
}
///必须返回true 如果返回false 会造成HWND不能获取窗体标题,修改窗体隐藏等属性
return TRUE;
}
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
DWORD processId;
GetWindowThreadProcessId(hwnd, &processId);
if (processId == (DWORD)lParam)
{
GHO_HWMD_C=hwnd;
}
///必须返回true 如果返回false 会造成HWND不能获取窗体标题,修改窗体隐藏等属性
return TRUE;
EnumChildWindows(hwnd, EnumChildProc, lParam);
EnumThreadWindows(processId,EnumThreadChildProc, lParam);
}
//在所有线程中查找pid
//process.processId(); QProcess类processId()返回pid
EnumWindows(EnumWindowsProc, (LPARAM)process.processId());
写法2
EnumWindows([](HWND hwndparent, LPARAM lParam)->BOOL{
DWORD processId = 0;
GetWindowThreadProcessId(hwndparent, &processId);
if (processId == (DWORD)lParam)
{
GHO_HWMD_C=hwnd;
}
EnumChildWindows(hwndparent,[](HWND Chwnd, LPARAM lParam)->BOOL{
DWORD CprocessId = 0;
GetWindowThreadProcessId(Chwnd, &CprocessId);
if (CprocessId == (DWORD)lParam)
{
GHO_HWMD_C=hwnd;
}
return TRUE; // 返回TRUE以继续枚举下一个窗体
},lParam);
EnumThreadWindows(processId,[](HWND Thwnd, LPARAM lParam)->BOOL{
DWORD TprocessId = 0;
GetWindowThreadProcessId(Thwnd, &TprocessId);
if (TprocessId == (DWORD)lParam)
{
GHO_HWMD_C=hwnd;
}
return TRUE; // 返回TRUE以继续枚举下一个窗体
},lParam);
return TRUE; // 返回TRUE以继续枚举下一个窗体
},(LPARAM)process.processId());
获取窗体标题
使用 GetWindowTextA 获取窗体标题
char WindowText[256];
GetWindowTextA(GHO_HWMD_C, WindowText, sizeof(WindowText));
qDebug() << "Window title Text: " << QString::fromUtf8(WindowText);
使用 SendMessage获取窗体标题
WCHAR WindowsTitle[MAX_PATH];
if(SendMessageW(GHO_HWMD_C, WM_GETTEXT, MAX_PATH, (LPARAM)WindowsTitle)>0)
qDebug() <<QString::fromWCharArray(WindowsTitle);
//const int bufferSize = 256;
//char buffer[bufferSize];
//SendMessageA(GHO_HWMD_C, WM_GETTEXT, bufferSize, (LPARAM)buffer)
使用 DefWindowProcA获取窗体标题
int len = SendMessageA(GHO_HWMD_C, WM_GETTEXTLENGTH, 0, 0) + 1;
// new一块len大小的内存
char *title = new char(len);
// 初始化内存为0
memset(title, 0, len);
// 发送WM_GETTEXT消息获取控件文本
DefWindowProcA(GHO_HWMD_C, WM_GETTEXT, 1024, (LPARAM)title);
使用 GetClassNameA获取窗体类名称
char className[256];
GetClassNameA(GHO_HWMD_C, className, sizeof(className));
qDebug() << "Window class name: " << QString::fromUtf8(className);
使用FindWindowEx获取窗体句柄
/*! https://linuxcpp.0voice.com/?id=132468*/
/*!
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QProcess process;
process.start("path/to/your/executable");
if (process.waitForStarted())
{
// 获取进程ID
DWORD pid = process.processId();
// 获取进程主窗口句柄
HWND hwnd = nullptr;
do
{
hwnd = FindWindowEx(nullptr, hwnd, nullptr, nullptr);
DWORD windowPid;
GetWindowThreadProcessId(hwnd, &windowPid);
if (windowPid == pid)
{
// 获取窗口类名
char className[256];
GetClassName(hwnd, className, sizeof(className));
qDebug() << "Window class name: " << QString::fromUtf8(className);
break;
}
} while (hwnd != nullptr);
process.waitForFinished();
}
return a.exec();
}
*/