获取 C++ 中所有打开窗口的列表并存储它们

mar*_*o56 1 c++ windows winapi

我目前正在尝试获取所有打开的窗口的列表并将它们存储在一个向量中。我一直在查看代码,以至于解决方案可能非常简单,但如果没有全局变量(我想避免),我似乎无法完成它。

这是代码:

#include "stdafx.h"
#include "json.h"
#include <algorithm>  

using namespace std;
vector<string> vec;


BOOL CALLBACK speichereFenster(HWND hwnd, LPARAM substring){
    const DWORD TITLE_SIZE = 1024;
    TCHAR windowTitle[TITLE_SIZE];

    GetWindowText(hwnd, windowTitle, TITLE_SIZE);
    int length = ::GetWindowTextLength(hwnd);

    wstring temp(&windowTitle[0]);
    string title(temp.begin(), temp.end());



    if (!IsWindowVisible(hwnd) || length == 0 || title == "Program Manager") {
        return TRUE;
    }

    vec.push_back(title);

    return TRUE;
}

int main() {
    EnumWindows(speichereFenster, NULL);
    cin.get();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我想将所有标题存储在向量中,但我不知道如何将向量传递到函数中...

谢谢!!!

gil*_*123 7

获取所有具有非空标题的可见窗口的简单代码

for (HWND hwnd = GetTopWindow(NULL); hwnd != NULL; hwnd = GetNextWindow(hwnd, GW_HWNDNEXT))
{   

    if (!IsWindowVisible(hwnd))
        continue;

    int length = GetWindowTextLength(hwnd);
    if (length == 0)
        continue;

    char* title = new char[length+1];
    GetWindowText(hwnd, title, length+1);

    if (title == "Program Manager")
        continue;

    std::cout << "HWND: " << hwnd << " Title: " << title << std::endl;

}
Run Code Online (Sandbox Code Playgroud)


IIn*_*ble 5

EnumWindows的第二个参数 ( lParam )记录为:

要传递给回调函数的应用程序定义的值。

只需将您的容器传递给 API 调用:

int main() {
    std::vector<std::wstring> titles;
    EnumWindows(speichereFenster, reinterpret_cast<LPARAM>(&titles));
    // At this point, titles if fully populated and could be displayed, e.g.:
    for ( const auto& title : titles )
        std::wcout << L"Title: " << title << std::endl;
    cin.get();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

并在您的回调中使用它:

BOOL CALLBACK speichereFenster(HWND hwnd, LPARAM lParam){
    const DWORD TITLE_SIZE = 1024;
    WCHAR windowTitle[TITLE_SIZE];

    GetWindowTextW(hwnd, windowTitle, TITLE_SIZE);

    int length = ::GetWindowTextLength(hwnd);
    wstring title(&windowTitle[0]);
    if (!IsWindowVisible(hwnd) || length == 0 || title == L"Program Manager") {
        return TRUE;
    }

    // Retrieve the pointer passed into this callback, and re-'type' it.
    // The only way for a C API to pass arbitrary data is by means of a void*.
    std::vector<std::wstring>& titles =
                              *reinterpret_cast<std::vector<std::wstring>*>(lParam);
    titles.push_back(title);

    return TRUE;
}
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 提供的代码使用std::wstring代替std::string。这是必要的,以便可以表示整个字符集。
  • 如所写,代码不正确。有(不可见的)代码路径,没有明确定义的含义。Windows API 严格公开为 C 接口。因此,它不理解 C++ 异常。特别是对于回调,永远不要让 C++ 异常跨越未知的堆栈帧是至关重要的。要修复代码,请应用以下更改:

  • @zett42:可以通过无数种方法来改进此代码。我集中精力回答这个问题:*“如何将数据传递给我的回调并返回?”* (3认同)