@Glace
C++ Developer

Как уменьшить загрузку процессора при свернутом окне программы?

Пишу программу на WinApi. Создание окна программы с обработчиком сообщений все как в методичках. ВCE взаимодействие с программой происходит через одну единственную функцию on_message() которая вызывается из функции обратного вызова WndProc(). Пока программа не свернута загрузка процессора находится на приемлемом уровне (~5% и еще видеокарта ~5% т.к. на перерисовку поставил DirectX), но при сворачивании окна нагрузка на процессор резко возрастает (~30%, хотя должна была упасть до нуля). Сначала грешил на обработчик сообщений, поставил логи но кроме сообщений на перерисовку в свернутом режиме туда практически ничего не приходит (остальные сообщения по разу - два). Жестко отсек обработку сообщений на перерисовку return-ом, но ничего не поменялось. Обшарил пол интернета ничего не нашел. Подскажите, пожалуйста, с чем подобное явление может быть связано и в какую сторону можно посмотреть.
  • Вопрос задан
  • 278 просмотров
Решения вопроса 1
@Glace Автор вопроса
C++ Developer
Как бы не было удивительно, но программа в свернутом состоянии действительно захлебывается сообщениями WM_PAINT. Судя по всему в свернутом состоянии в программу прилетает сильно больше сообщений на перерисовку чем в несвернутом (мое предположение которое я даже проверять не хочу). Я попытался запретить перерисовку окна вызывая в case WM_SIZE: { if (wParam == SIZE_MINIMIZED) ... if (wParam == SIZE_RESTORED) ... } функции SendMessage(hWnd, WM_SETREDRAW, (WPARAM)false, NULL) и LockWindowUpdate(hWnd), но первая дала весьма странный результат (при отправке сообщения пропала иконка на панели задач и не только), вторая вообще никакого результата не дала. В результате глобально объявил переменную bool lock_draw = false и выставил ее в case WM_SIZE. Программа оперлась на костыль и пошла. Код стал выглядеть примерно так:
bool lock_draw = false;
bool Core::on_message(UINT message, WPARAM wParam, LPARAM lParam)
{
    if (lock_draw && message == WM_PAINT) return false;
    ...
    switch(message) {
        ...
        case WM_SIZE: 
            if (wParam == SIZE_MINIMIZED) lock_draw = true;
            if (wParam == SIZE_RESTORED) lock_draw = false;
        ...
    }
}
p.s. Задавая вопрос отсекать сообщения отрисовки я пытался функцией IsIconic(hWnd), которая судя по профайдеру занимает процессорного времени не меньше чем функция отрисовки о_О.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Запустите профайлер и смотрите, какая функция отъедает процессореое время.
Ответ написан
Комментировать
@RutreD
У меня это было из-за того, что не указал задержку в бесконечном цикле где вызываются функции отрисовки DirectX и PeekMessage(&msg,.....). Нужно добавить хотя-бы 1мс задержки через WinApi функцию Sleep или с STL - std::this_thread::sleep_for
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы