Неожиданное поведение при возврате FALSE в функции CALLBACK winapi (цикл пропускается?) - PullRequest
0 голосов
/ 06 июня 2019

У меня есть следующая функция.Если возвращаемое значение в нижней части функции равно TRUE, работает как ожидалось.

Но если я изменю его на FALSE (чтобы узнать, даст ли regex_match результат), оно, похоже, полностью пропустит цикл for ивозвращает FALSE напрямую.Я очень незнаком с winapi, поэтому я мог использовать возвращаемое значение неуместно.

Я пробовал и g ++, и msvc без оптимизатора, но получил то же поведение.

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, если остальная часть кода имеет значение, но, как сказано, если возвращаемое значение по умолчанию - trueкод работает должным образом, я просто не знаю, было ли найдено совпадение (я знаю, что могу проверить, изменяется ли значение строк, или передать эту информацию в структуру lparam, которую я использую, но это все еще поднимает вопрос, почему это происходит.)

1 Ответ

1 голос
/ 06 июня 2019

Во-первых, CALLBACK - это просто соглашение о вызове функции, и оно не имеет ничего общего с прекращением перечисления.

MSDN четко говорит:

EnumWindows продолжается до тех пор, пока не будет перечислено последнее окно верхнего уровня или функция обратного вызова вернет FALSE.

Если вам нужно записать некоторую конкретную информацию, касающуюся поиска совпадения, вам следует сохранить ее в структуре, которую вы передаете, как параметр LPARAM.

Если вы заботитесь только о первом соответствующем окне, вы можете вернуть FALSE, как только это окно будет найдено, перечисление будет прервано без проверки оставшихся окон.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...