Таймер win32 на С++

358
17 ноября 2017, 08:21

Здравствуйте, выполняю задания на С++ и всё хорошо, только вот проблема с таймером. Вот кусок самого задания:

Необходимо определить в классе view2 статический метод ontimeraction. Этот метод отображает на экране заданный наследник data. Выбрать для этого win32 таймер собственный интервал повторных вызовов. Установить реализованный метод view::ontimeraction(), на вызов в таймере. Таймер должен сработать всего 4 раза. Метод должен выводить на экран данные про текущий ассоциируемый объект данных.

Дата — просто класс с данными, а view — его логика для графического отображения этих данных. Прошу помочь объяснить, как это всё сделать и, если можно, набросать эту функцию ну или хотя бы псевдокод с объяснением что куда. Я гуглил, но как-то не могу понять, как прикрутить сюда тот таймер с англ. статьи на MSDN. Всегда были у меня проблемы со всякими специфическими ф-циями WinAPI.

Answer 1

Вашу задачу можно решить двумя способами:

  1. Оконными таймерами.

    Для использования данного способа требуется владение хотя бы одним окном. Созданный таймер привязывается к этому окну и посылает ему сообщения WM_TIMER.

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

    Для работы с данным видом таймеров вам потребуется:

    • добавить в конструктор view2вызов SetTimer(),
    • в (уже имеющемся) обработчике оконных сообщений (который WindowProc) при приёме 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);
              }
          };
      
  2. Очередями таймеров (timer queues). Однако в данном случае функция обратного вызова исполняется не в главном потоке, что вынуждает создавать довольно громоздкую обвязку для пересылки уведомления в главный поток, где и должен выполняться ontimeraction(). Можно, конечно, обойтись и без пересылки, но тогда придётся огораживать всё примитивами синхронизации, что тоже является излишеством.

READ ALSO
Не запускается проект на Qt? [требует правки]

Не запускается проект на Qt? [требует правки]

Не запускается проект на Qt,после того как начал добавлять свои файлы,написанный на с++

310
В чем ошибка скрипта jquery?

В чем ошибка скрипта jquery?

Задача: скрипт определяет высоту блока в зависимости от наличия отсутствия в теле body другогоЯ использовал следующий вариант:

339
Перестали отображаться иконки font-awesom

Перестали отображаться иконки font-awesom

Ни с того ни с сего перестали отображаться иконкиПо крайней мере я не припомню каких-то особых действий, которые могли к этому привести

339