GetWindowTextA returns 乱码与不相关的代码更改

GetWindowTextA returns gibberish with unrelated code changes

我已经尝试过这段代码,它应该获取所有 window 标题和位置并将它们存储在向量中(这里打印 window 标题)但输出似乎完全随机:

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

std::vector<LPSTR> buffs;
std::vector<int> rectposs;

BOOL CALLBACK EnumWindowsProc(HWND hWnd, long lParam)
{
    LPSTR buff;

    if (IsWindowVisible(hWnd))
    {
        GetWindowTextA(hWnd, buff, 254);
        buffs.push_back(buff);
        RECT rect;
        if (GetWindowRect(hWnd, &rect))
        {
            rectposs.push_back(rect.left);
            rectposs.push_back(rect.right);
            rectposs.push_back(rect.top);
            rectposs.push_back(rect.bottom);
        }
    }

    return TRUE;
}

int main()
{
    EnumWindows(EnumWindowsProc, 0);
    for (LPSTR buff : buffs)
    {
        std::cout << buff << std::endl;
    }
    return 0;
}

我希望输出包含 SettingsAlarms and Clock 之类的行,因为我打开了它们,但实际上一切都与 ���$ 类似,让我感到困惑的是,如果我删除了第 20-23 行(推回 windows 的位置)问题显然已解决,但事实并非如此,因为它与 GetWindowTextA 或我如何保存 [=23] 无关=] 标题。因此,我无法生成最小的可重现示例,因为看似无关的代码似乎完全改变了输出。

我怀疑这与覆盖 window 标题的第 20-23 行有关吗?如果是这样或否则我如何确保它不会发生并且仍然有我想要的数据?

您的 buff 变量是一个 未初始化的 指针,它没有指向任何有意义的地方。因此,您对 GetWindowTextA() 的调用正在写入随机内存。要解决这个问题,您需要为其写入分配实际内存。

修复该问题后,您会遇到另一个问题 - 您在每次迭代中将相同的指针推入 buffs 向量。因此,一旦枚举完成,所有条目将指向同一内存,该内存将保存 last 调用 GetWindowTextA() 的结果。要解决此问题,您需要在每次推送时对 buff 数据进行 copy。解决这个问题的最简单方法是更改​​ buffs 向量以保存 std::string 值而不是 LPSTR 指针。

最后,我建议更改 rectposs 向量以保存实际 RECT 对象而不是单个 int 值(不过,您应该考虑定义一个新的 struct /class 来保存你想要的所有 window 信息,然后使用一个 vector 来保存该类型的对象。

试试这个:

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

std::vector<std::string> buffs;
std::vector<RECT> rectposs;

BOOL CALLBACK EnumWindowsProc(HWND hWnd, long lParam)
{
    if (IsWindowVisible(hWnd))
    {
        CHAR buff[255]{};
        GetWindowTextA(hWnd, buff, 254);
        buffs.push_back(buff);

        RECT rect;
        GetWindowRect(hWnd, &rect);
        rectposs.push_back(rect);
    }

    return TRUE;
}

int main()
{
    EnumWindows(EnumWindowsProc, 0);
    for (string& buff : buffs)
    {
        std::cout << buff << std::endl;
    }
    return 0;
}