Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > C/C++: Системное программирование и WinAPI > settimer


Автор: maxutov 04.12.23, 11:23
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <iostream>
    #include <Windows.h>
     
    // Объявление функции TimerProc
    void CALLBACK TimerProc(HWND hwnd, UINT message, UINT_PTR idTimer, DWORD dwTime);
     
    int main() {
        // Создание таймера с периодом 1 секунда (1000 миллисекунд)
        UINT_PTR timerId = SetTimer(NULL, 0, 1000, TimerProc);
        if (timerId == 0) {
            std::cout << "Failed to create timer." << std::endl;
            return 1;
        }
     
        std::cout << "Timer created. Timer ID: " << timerId << std::endl;
     
        // Ожидание 5 секунд
        Sleep(5000);
     
        // Остановка таймера
        if (KillTimer(NULL, timerId)) {
            std::cout << "Timer stopped." << std::endl;
        }
        else {
            std::cout << "Failed to stop timer." << std::endl;
        }
     
        return 0;
    }
     
    // Реализация функции TimerProc
    void CALLBACK TimerProc(HWND hwnd, UINT message, UINT_PTR idTimer, DWORD dwTime) {
        std::cout << "Timer event! Timer ID: " << idTimer << std::endl;
    }

сообщение от таймера почему-то не приходит
почему?
spasibo

Автор: macomics 04.12.23, 13:40
Потому что Sleep не обрабатывает очередь сообщений текущей ветви, а просто её замораживает. Используйте вместо Sleep функцию MsgWaitForMultipleObjects. Как хэндл объекта для ожидания можете просто передать хэндл текущего процесса. Тогда ожидание прервётся при получении сообщения по таймеру.

Или используйте обычный цикл обработки сообщений windows. Тогда для завершения цикла можно установить второй таймер.

Автор: Qraizer 04.12.23, 17:59
SetTimer() всё-таки про окна и сообщения. Думаю, что вместо объектов GUI тебе, maxutov, всё-таки больше подходят ожидающие таймеры, которые объекты синхронизации:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <iostream>
    #include <Windows.h>
    #include <chrono>
     
    using namespace std::literals;
     
    // Объявление функции TimerProc
    void CALLBACK TimerProc(LPVOID arg, DWORD, DWORD);
     
    int main() {
        // Создание таймера
        HANDLE timerId = CreateWaitableTimer(NULL, TRUE, NULL);
     
        if (timerId == NULL) {
            std::cout << "Failed to create timer." << std::endl;
            return 1;
        }
     
        // Установка таймера на однократное срабатывание через 1 секунду (в 100-наносекундных единицах)
        LARGE_INTEGER li;
     
        li.QuadPart = -std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count() / 100;
     
        if (SetWaitableTimer(timerId, &li, 0, TimerProc, timerId, FALSE) == 0){
            std::cout << "Failed to set timer." << std::endl;
            CloseHandle(timerId);
            return 1;
        }
     
        std::cout << "Timer created. Timer ID: " << timerId << std::endl;
     
        // Ожидание 5 секунд (с позволением APC)
        SleepEx(5000, TRUE);
     
        // Остановка таймера
        if (CancelWaitableTimer(timerId)) {
            std::cout << "Timer stopped." << std::endl;
        }
        else {
            std::cout << "Failed to stop timer." << std::endl;
        }
     
        CloseHandle(timerId);
        return 0;
    }
     
    // Реализация функции TimerProc
    void CALLBACK TimerProc(LPVOID arg, DWORD, DWORD)
    {
        std::cout << "Timer event! Timer ID: " << arg << std::endl;
    }


Добавлено
P.S. Их ещё и WaitForXXXX() можно.

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)