c++ - 在 winapi CALLBACK 函数上返回 FALSE 时出现意外行为(跳过循环?)

标签 c++ windows winapi callback

我有以下功能。如果函数底部的返回值为 TRUE,则按预期工作。

但如果我将其更改为 FALSE(以了解 regex_match 是否产生结果),它似乎会完全跳过 for 循环并直接返回 FALSE。我对 winapi 非常不熟悉,所以我可能使用了不合适的返回值。

我尝试了 g++ 和 msvc w/o 优化器,但得到了相同的行为。

BOOL CALLBACK enumWindowsProc(HWND hwnd, LPARAM lParam) {

    static const std::wregex rgx(L"(.+) - (?!\\{)(.+)");
    const auto &paramRe = *reinterpret_cast<EnumWindowsProcParam*>(lParam);

    DWORD winId;
    GetWindowThreadProcessId(hwnd, &winId);

    for (DWORD pid : (paramRe.pids)) {
        if (winId == pid) {
            std::wstring title(GetWindowTextLength(hwnd) + 1, L'\0');
            GetWindowTextW(hwnd, &title[0], title.size()); //note: >=C++11 

            std::regex_match(title, rgx);
            std::wsmatch matches;

            if (std::regex_search(title, matches, rgx)) {
                paramRe.song = std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(matches[1]);
                paramRe.artist = std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(matches[2]);
                return TRUE;
            }
        }
    }
    return TRUE;  // <--- HERE
}

Idk,如果其余代码很重要,但如前所述,如果默认返回值为真,代码将按预期工作我只是不知道是否找到了匹配项(我知道我可以检查字符串的值是否更改,或者通过我使用的 lparam 结构的信息,但这仍然提出了为什么会发生这种情况的问题。)

最佳答案

首先,CALLBACK 只是函数调用约定,与枚举何时停止无关。

MSDN 明确表示:

EnumWindows continues until the last top-level window is enumerated or the callback function returns FALSE.

如果您需要记录一些关于查找匹配项的特定信息,那么您应该将其存储在作为 LPARAM 参数传递的结构中。

如果您只关心第一个匹配的窗口,那么您可以在找到该窗口后返回 FALSE,这会中止枚举,而无需检查其余窗口。

关于c++ - 在 winapi CALLBACK 函数上返回 FALSE 时出现意外行为(跳过循环?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56474249/

相关文章:

windows - 创建 CAB 文件 - 基本组件

C++访问DLL加载

c - Internet Explorer 地址空间

c# - 如何在 C# 程序中使用标准 Windows 定义

c++ - win32 中是否有任何其他控件,如 ListView,或者是否有任何方法可以删除 win32 中可用的 ListView 控件的标题区域

c++ - 初学者关于类型转换的问题

c++ - 使用 Qt 的静态版本编译时文件对话框崩溃

c++ - Opencv 膨胀和骨架(c++)

当有长文件名时,Python 的 os.walk() 在 Windows 中失败

c++ - 使用 if (? operator) 语句传递带指针的数组