GetWindowTextA返回带有不相关代码更改的胡言乱语



我尝试过这个代码,它应该获得所有窗口标题和位置,并将它们存储在矢量中(这里打印窗口标题(,但输出似乎完全随机:

#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行(推回窗口的位置(,问题显然已经解决了,但不应该是这样,因为它与GetWindowTextA或我如何保存窗口标题无关。因此,我无法生成一个最低限度的可复制示例,因为看似无关的代码似乎完全改变了输出。

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

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

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

最后,我建议更改rectposs向量以保存实际的RECT对象,而不是单独的int值(不过,您应该考虑定义一个新的struct/class来保存您想要的所有窗口信息,然后使用一个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;
}

最新更新