Stavros Avramidis
Stavros Avramidis

Reputation: 865

Unexpected behavior when returning FALSE on winapi CALLBACK function (loop gets skipped?)

I have the following function. If the return on the bottom of the function is TRUE works as expected.

But if I change it to FALSE ( to know if regex_match yield a result) it seems to completely skip the for loop and returns FALSE directly. I'm very un-familiar with winapi so i might been using return value unappropriate.

I tried both g++ and msvc w/o optimizer, but got the same behavior.

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, if rest of the code matters, but as said if default return value is true the code works as intended I just don't know if match was found (I know I could check if value of strings change, or pass that info to the lparam struct I use, but that still raises the question why is that happening.)

Upvotes: 0

Views: 89

Answers (1)

Anders
Anders

Reputation: 101746

First off, CALLBACK is just the function calling convention and has nothing to do with when the enumeration stops.

MSDN clearly says:

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

If you need to record some specific information regarding finding a match then you should store that in the struct you pass as the LPARAM parameter.

If you only care about the first window that matches then you can return FALSE once that window is found, this aborts the enumeration without having to inspect the remaining windows.

Upvotes: 1

Related Questions