Здравствуйте, выполняю задания на С++ и всё хорошо, только вот проблема с таймером. Вот кусок самого задания:
Необходимо определить в классе view2 статический метод ontimeraction. Этот метод отображает на экране заданный наследник data. Выбрать для этого win32 таймер собственный интервал повторных вызовов. Установить реализованный метод view::ontimeraction(), на вызов в таймере. Таймер должен сработать всего 4 раза. Метод должен выводить на экран данные про текущий ассоциируемый объект данных.
Дата — просто класс с данными, а view — его логика для графического отображения этих данных. Прошу помочь объяснить, как это всё сделать и, если можно, набросать эту функцию ну или хотя бы псевдокод с объяснением что куда. Я гуглил, но как-то не могу понять, как прикрутить сюда тот таймер с англ. статьи на MSDN. Всегда были у меня проблемы со всякими специфическими ф-циями WinAPI.
Вашу задачу можно решить двумя способами:
Оконными таймерами.
Для использования данного способа требуется владение хотя бы одним окном. Созданный таймер привязывается к этому окну и посылает ему сообщения WM_TIMER.
Так как однократно срабатывающие таймеры создать таким образом невозможно, нам придётся самостоятельно отслеживать количество срабатываний, учитывая при этом, что между последним срабатыванием таймера и его остановкой нам может прийти ещё один WM_TIMER, но не более. Подобное происходит при большом потоке оконных сообщений, так как у WM_TIMER самый низкий приоритет обработки.
Для работы с данным видом таймеров вам потребуется:
view2вызов SetTimer(),WM_TIMER:
KillTimer();view2::ontimeraction;вызывать KillTimer() в деструкторе view2 не надо. Таймер и так будет уничтожен либо явно в WM_TIMER, либо неявно при уничтожении окна и его очереди сообщений.
class view2
{
unsigned timerFiresCount;
HWND hwndView;
static void ontimeraction()
{
// ...
}
static LRESULT CALLBACK WindowProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_TIMER:
if(timerFiresCount < 4)
{
if(++timerFiresCount == 4)
KillTimer(hwnd, 1);
ontimeraction();
}
return 0;
// ...
}
}
public:
view2()
: timerFiresCount(0)
{
// Выполняете здесь инициализацию класса и создание окна для вида.
// Пусть HWND этого вида сохраняется в hwndView.
// Идентификатор таймера может быть любым кроме нулевого (NULL)
SetTimer(hwndView, 1, ИНТЕРВАЛ_СРАБАТЫВАНИЯ, NULL);
}
};
Очередями таймеров (timer queues). Однако в данном случае функция обратного вызова исполняется не в главном потоке, что вынуждает создавать довольно громоздкую обвязку для пересылки уведомления в главный поток, где и должен выполняться ontimeraction(). Можно, конечно, обойтись и без пересылки, но тогда придётся огораживать всё примитивами синхронизации, что тоже является излишеством.
Как развивать веб-проекты в 2026 году: технологии, контент E-E-A-T и факторы доверия
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники