Список фильтрации / синтаксического анализа, созданный из EnumWindows в C++

Я использую следующий код, чтобы получить список окон, запущенных на моей машине

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

using namespace std;

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    TCHAR buffer[512];
    SendMessage(hwnd, WM_GETTEXT, 512, (LPARAM)(void*)buffer);
    wcout << buffer << endl;
    return TRUE;
}

int main()
{
    EnumWindows(EnumWindowsProc, NULL);
    return 0;
}

Я хочу получить список того, что обычно называют окном - я говорю это потому, что при запуске приведенного выше кода я получаю список из примерно 40 записей, большинство из которых я не называю окнами.

Вот выдержка из вывода, полученного при запуске вышеуказанного скрипта на моей машине, из 5 записей только Microsoft Visual Studio является окном

...
Task Switching
Microsoft Visual Studio
CiceroUIWndFrame

Battery Meter

Network Flyout
...

Как я могу пойти на фильтрацию / анализ этих данных, так как нет ничего, чтобы использовать в качестве идентификатора.

2 ответа

Решение

Я хотел бы использовать EnumDesktopWindows перечислить все окна верхнего уровня на вашем рабочем столе; Вы даже можете использовать IsWindowsVisible API во время процесса перечисления, для фильтрации невидимых окон.

Этот компилируемый код C++ прекрасно работает для меня (обратите внимание, что здесь я показал, как передать некоторую дополнительную информацию в процедуру перечисления, в данном случае используя указатель на vector<wstring>, в котором заголовки окон сохраняются для последующей обработки):

#include <windows.h>
#include <iostream>
#include <string>
#include <vector>
using std::vector;
using std::wcout;
using std::wstring;

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    if (!IsWindowVisible(hwnd))
    {
        return TRUE;
    }

    wchar_t titleBuf[512];
    if (GetWindowText(hwnd, titleBuf, _countof(titleBuf)) > 0)
    {
        auto pTitles = reinterpret_cast<vector<wstring>*>(lParam);
        pTitles->push_back(titleBuf);
    }

    return TRUE;
}

int main()
{
    vector<wstring> titles;
    EnumDesktopWindows(nullptr, EnumWindowsProc, reinterpret_cast<LPARAM>(&titles));

    for (const auto& s : titles)
    {
        wcout << s << L'\n';
    }
}

Определите, что вы называете окном, и запросите дескриптор окна для правильных свойств. Используйте GetWindowLong() с, например, GWL_HWNDPARENT, чтобы проверить, нет ли родительского окна или родительское окно является окном рабочего стола. Может потребоваться дополнительная проверка, например, вы можете использовать (расширенные) стили окна. Смотрите также здесь для дополнительных идей о пригодных для использования тестов.

Другие вопросы по тегам