c++ GetWindowText和子字符串

wnvonmuf  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(106)

我在获取子串时遇到了麻烦,

strstr(a,b);

字符串
要检查“FiveM”名称是否出现在窗口的标题栏中,因为通常在这个游戏中标题栏也包含更新等
所以我在谷歌上找到了GetWindowText函数。
我运行了这个代码:

HWND foreground = GetForegroundWindow();
    char window_title[7];

    if (foreground)
    {
        GetWindowText(foreground, (LPWSTR)window_title, 7);
    }


    auto output = strstr(window_title, "FiveM");

    printf("%d", output);


没有得到输出,一切都是0,但是当我使用函数GetWindowTextA()时,一切都很好,所以我在谷歌上搜索了更多关于这个getwindow函数的信息,我找到了这个链接,我看到了这个

#define GetWindowText GetWindowTextA

in a non-Unicode build, GetWindowText and GetWindowTextA are the same thing. [...]


我的版本是unicode,所以这就是我必须在最后添加A的问题,为什么,也为什么当我使用GetWindowTextW aka GetWindowText获取窗口文本时,一个字符占用更多空间,我猜这是因为我如何正确转换它

char window_title[7];

    if (foreground)
    {
        GetWindowTextW(foreground, (LPWSTR)window_title, 7);
        
    }


我也很困惑,为什么strstr()函数在将输出值打印到控制台时会增加memory violation,而只是简单地阅读它不会引起任何内存冲突

tag5nh1u

tag5nh1u1#

你在处理Unicode(又名宽)和ANSI(又名窄)字符串时非常混乱。你应该选择一个变体并坚持使用它。在这种情况下,因为你是为Unicode构建的,所以宽字符串是自然的选择。
因此,代码应该看起来有点像这样:

HWND foreground = GetForegroundWindow();

if (foreground)
{
    WCHAR window_title[256];
    GetWindowText(foreground, window_title, _countof (window_title));
    const WCHAR *output = wcsstr (window_title, L"FiveM");
    ... 
}

字符串
需要注意的事项(不分先后):

  • 窗口标题肯定会超过6个字符,所以在检索它时要留出足够的空间。
  • 为了避免在代码中出现“幻数”,请在适当的时候使用_countof
  • strstr(或宽等价物wcsstr)的返回类型是char *(或WCHAR *),而不是int,因此相应地处理它。
1aaf6o9v

1aaf6o9v2#

GetWindowTextW以Unicode宽字符串的形式提供输出。注意,由于nMaxCount参数是 * 字符数 *,而不是字节数,因此可能会溢出数组的末尾。这可以解释为什么会看到内存冲突,因为UTF-16宽字符至少包含2个字节;你实际上告诉GetWindowTextW缓冲区可以容纳14个字节,而实际上只有7个字节长。
你需要传递一个wchar_t数组,然后要么完全使用宽字符串(例如wcslen),要么从宽字符串转换为字符串,如下所示:C++ Convert string (or char*) to wstring (or wchar_t*)
您可以使用MSVC ATL方法A2WW2A,尽管我建议尽可能使用std::stringstd::wstring
当你在宽字符串上使用字符串方法时,它们会表现得不正常,因为宽字符串通常包含零作为编码的高位字节,字符串方法将其解释为空终止符(例如,在十六进制内存视图中,你可能会看到类似48 00 45 00 4C 00 4C 00 4F 00 00 00的东西-字符串方法将其解释为“H”)
如果你看一下GetWindowText的声明,你会发现类似这样的东西:

#ifdef UNICODE
        #define GetWindowText GetWindowTextW
    #else
        #define GetWindowText GetWindowTextA
    #endif

字符串
这就解释了为什么在非unicode版本中 * GetWindowText与GetWindowTextA* 相同
另一种可能性是使用GetWindowTextA并使用字符串完成整个操作,但您可能无法选择。

相关问题