Опубликован: 17.08.2010 | Доступ: свободный | Студентов: 999 / 59 | Оценка: 4.11 / 3.89 | Длительность: 29:38:00
Самостоятельная работа 5:

Работа с таймерами MFC

Аннотация: В данной лабораторной работе вы создадите приложение с двумя таймерами. Научитесь устанавливать порядок перехода по клавише табуляции, добавлению идентификаторов таймеров. Запуск таймера часов "Текущее время". Обработка события срабатывания таймера. Извлечение текущей даты. Добавление второго таймера к приложению. Управление вторым таймером. Запуск и остановка счетчика второго таймера. Управление блокировкой кнопок "Пуск" и "Стоп". Решение проблемы реентерабельности.
Файлы к данной лабораторной работе, Вы можете скачать здесь.

Цель работы

  1. Использовать и контролировать работу таймеров
  2. Одновременно использовать несколько таймеров со своим интервалом повторения
  3. Определять, какой именно таймер сработал
  4. Применять таймеры в реальных приложениях

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

События таймера ставятся в очередь событий приложения лишь в том случае, если приложение неактивно и его очередь сообщений пуста. Windows ставит в очередь событий только одно сообщение таймера. Если приложение активно и занято, сообщение таймера будет проигнорировано. Чтобы запустить или остановить таймер, нужно указать его идентификатор ID, который может принимать любое целое значение.

Задание

Создать приложение с двумя таймерами. Один таймер применить для поддержки часов приложения, второй - с управляемым пользователем интервалом срабатывания. Для этого нужно:

  1. Добавить элементы управления, необходимые приложению в целом.
  2. Создать неуправляемый таймер для поддержки часов приложения.
  3. Создать таймер, управляемый пользователем.
Создание заготовки приложения
  • Создайте новый проект C++ на основе MFC и назовите его Timers
  • Укажите мастеру, что проект будет диалоговым приложением, остальные настройки мастера оставьте по умолчанию.
  • Установите для ресурсов русский язык
  • Создайте макет диалогового окна, показанный на рисунке. Для этого воспользуйтесь таблицей свойств элементов управления, приведенной ниже
    Таблица свойств главной диалоговой формы Timers
    Элемент управления Свойство Значение
    Главная форма Caption Студент Иванов. Моделирование таймеров
    Font(Size) MS Sans Serif(10)
    Static Text Caption Сегодня
    Static Text Caption Текущая дата
    ID IDC_STATICDATE
    Static Text Caption Интервал таймера
    Edit Control ID IDC_INTERVAL
    Button ID IDC_STARTTIMER
    Caption Пуск
    Button ID IDC_STOPTIMER
    Caption Стоп
    Disabled True
    Static Text Caption Часы:
    Right Align Text True
    Static Text ID IDC_STATICTIME
    Caption Текущее время:
    Static Text Caption Счетчик:
    Right Align Text True
    Static Text ID IDC_STATICCOUNT
    Caption 0
    Button ID IDC_EXIT
    Caption Выход
  • Определите порядок перехода по клавише табуляции между элементами управления
  • Обеспечьте выход по кнопке Exit

Интерфейс окна приложения должен получиться таким


Установка порядка перехода по клавише табуляции
  • Включите режим Format/Tab Order и установите порядок перехода по клавише табуляции, как показано на рисунке

Обеспечение выхода по клавише Exit

  • Выделите элемент IDC_EXIT
  • В панели свойств установите режим Control Evets
  • Добавьте обработчик сообщения BN_CLICKED (то же самое можно сделать двойным левым щелчком по кнопке)
    Обработчик сообщения OnBnClickedExit() класса CTimersDlg файла TimersDlg.cpp
    void CTimersDlg::OnBnClickedExit()
    {
      // TODO: Add your control notification handler code here
      OnOK();
    }

Добавление идентификаторов таймеров

В данном приложении будут использованы два таймера: управляемый и неуправляемый. Чтобы однозначно определить таймер, ему нужно присвоить уникальный идентификатор и добавить в приложение идентификаторы таймеров. Для этого:

  • Выделите в панели ресурсов Resource View узел Timers.rc, затем либо через меню Edit оболочки, либо через контекстное меню узла выполните опцию Resource Symbols (символы ресурсов)
  • В диалоговом окне Resource Symbols щелкните на New (создать)
  • В диалоговом окне New Symbol (создание символа) введите:

    Таймер времени
    Name ID_CLOCK_TIMER
    Value 1
    Таймер счетчика
    Name ID_COUNT_TIMER
    Value 2

Можно увидеть, что оболочка добавит в заголовочный файл ресурсов две строки:

Изменения в заголовочном файле ресурсов Resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Timers.rc
//
#define ID_CLOCK_TIMER                  1
#define ID_COUNT_TIMER                  2
#define IDM_ABOUTBOX                    0x0010
#define IDD_ABOUTBOX                    100
#define IDS_ABOUTBOX                    101
#define IDD_TIMERS_DIALOG               102
#define IDR_MAINFRAME                   128
#define IDC_INTERVAL                    1000
#define IDC_STARTTIMER                  1001
#define IDC_STOPTIMER                   1002
#define IDC_EXIT                        1003
#define IDC_STATICCOUNT                 1004
#define IDC_STATICTIME                  1005
#define IDC_STATICDATE                  1006
  
// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        129
#define _APS_NEXT_COMMAND_VALUE         32771
#define _APS_NEXT_CONTROL_VALUE         1007
#define _APS_NEXT_SYMED_VALUE           103
#endif
#endif

Запуск таймера часов "Текущее время"

  • Чтобы запустить таймер часов, отредактируйте функцию OnInitDialog() следующим образом
    Изменения в функции OnInitDialog() класса CTimersDlg файла TimersDlg.cpp
    BOOL CTimersDlg::OnInitDialog()
    {
      CDialog::OnInitDialog();
    .....................................
      // TODO: Add extra initialization here
      
      // Запустить таймер часов
      SetTimer(ID_CLOCK_TIMER, 1000, NULL);
      
      return TRUE;  // return TRUE  unless you set the focus to a control
    }

Таймер запускается функцией SetTimer(). Первым аргументом является идентификатор таймера. Второй аргумент определяет частоту в миллисекундах. В данном случае таймер каждые 1000 миллисекунд (каждую секунду) будет генерировать сообщение WM_TIMER. Третий необязательный аргумент - адрес функции обратного вызова, которая должна вызываться при каждом срабатывании таймера. Если поставить NULL (пустой указатель), то сообщение WM_TIMER будет отослано в очередь сообщений Windows.

Функция обратного вызова - это созданная разработчиком приложения функция, которая вызывается непосредственно операционной системой.

Александр Даниленко
Александр Даниленко
Стоит Windows 8 Pro, Visual Studio 2010 Express Edition .