我正在用C ++编写一个小工具,它正在寻找Windows应用程序主窗口的某个子窗口(UI是用QT编写的,但这不应该影响问题)。
#include <windows.h>
#include <winnt.h>
#include <tchar.h>
#include <psapi.h>
#include "MainWindow.h"
#include "ui_MainWindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::addOutputLine(const QString &line)
{
ui->outputPlainTextEdit->appendPlainText(line);
}
QString QStringFromPTCHAR(TCHAR *in)
{
#ifdef UNICODE
return QString::fromUtf16((ushort *) in);
#else
return QString::fromLocal8Bit((char *) in);
#endif
}
BOOL CALLBACK enumerateChildWindows(HWND windowHandle, LPARAM ui)
{
MainWindow *thisUi = (MainWindow *) ui;
TCHAR buffer[4096];
DWORD bufferSize;
ZeroMemory(buffer, sizeof(buffer));
bufferSize = sizeof(buffer) / sizeof(buffer[0]);
GetWindowText(windowHandle, buffer, bufferSize);
QString windowTitle = QStringFromPTCHAR(buffer);
if (!windowTitle.isEmpty() && IsWindow(windowHandle) == TRUE && IsWindowVisible(windowHandle) == TRUE)
{
thisUi->addOutputLine(QString("SUB-WIN: ") + windowTitle);
}
return TRUE;
}
BOOL CALLBACK enumerateWindows(HWND windowHandle, LPARAM ui)
{
MainWindow *thisUi = (MainWindow *) ui;
TCHAR buffer[4096];
DWORD bufferSize;
ZeroMemory(buffer, sizeof(buffer));
bufferSize = sizeof(buffer) / sizeof(buffer[0]);
GetWindowText(windowHandle, buffer, bufferSize);
QString windowTitle = QStringFromPTCHAR(buffer);
if (!windowTitle.isEmpty() && IsWindow(windowHandle) == TRUE && IsWindowVisible(windowHandle) == TRUE)
{
thisUi->addOutputLine(QString("WIN: ") + windowTitle);
EnumChildWindows(windowHandle, enumerateChildWindows, ui);
}
return TRUE;
}
void MainWindow::on_enumerateWindowsPushButton_clicked()
{
ui->outputPlainTextEdit->clear();
EnumDesktopWindows(0, enumerateWindows, (LPARAM) this);
}
目前,我仍然在我的子窗口列表中获得了很多其他UI元素,例如国际电联的“导航栏”,“地址栏”,“地址组合控制”等。
有没有办法过滤所有这些,但那些是“真正的”窗口,即带边框,标题栏等?
答案 0 :(得分:2)
有点天真的检查是使用GetWindowLong()过滤掉没有标题(和边框)的窗口,如下所示:
BOOL CALLBACK enumerateChildWindows(HWND windowHandle, LPARAM ui)
{
LONG styles = GetWindowLong(windowHandle, GWL_STYLE);
if ((styles & WS_CHILD) == WS_CHILD && IsWindowVisible(windowHandle)
thisUi->addOutputLine(QString("SUB-WIN: ") + windowTitle);
return TRUE;
}
正如我所说,这个过滤器非常幼稚,但您可以检查WS_CAPTION
(假设您正在寻找的窗口有标题栏)。最后一点:不要使用IsWindow()
功能,它非常危险,因为你在这里枚举窗口也没用。