Как вы убедились выше, добавление к приложению одного таймера представляет довольно простую задачу. Все что необходимо сделать - вызвать функцию SetTimer() внутри инициализирующей функции OnInitDialog, а затем в функции OnTimer() добавить программный код таймера, который обрабатывает сообщение таймера WM_TIMER. Но иногда встречаются ситуации, когда надо использовать в приложении несколько таймеров. Это несколько более сложная задача.
Вверх
Таблица 5.4 Переменные соответствующие элементам управления
Добавление к приложению новых переменных
Для таймера часов необходима лишь одна переменная, которая используется для
обновления текущего времени, отображаемого в окне приложения.
Чтобы использовать второй таймер, необходимо с соответствующими элементами
управления связать дополнительные переменные. Эти дополнительные
переменные перечислены в таблице 5.4
Элемент управления: | Имя переменной: | Категория: | Тип: |
IDC_STATICCOUNT | m_sCount | value | CString |
IDC_STARTTIME | m_сStartTime | Control | CButton |
IDC_BSTOPTIMER | m_cStopTime | Control | CButton |
IDC_EINTERVAL | m_iInterval | value | int |
Добавим переменные. Воспользуемся для этого Мастером добавления переменных (Add Member Variable Wizard) к управляющим элементам формы. Выполните следующие пошаговые инструкции :
Введите имя переменной int m_iInterval, тип - int, доступ -public, категория value. В поле Min Value введите 1 в качестве минимального значения, а в поле Max Value -100 000 в качестве максимального значения.
Таким образом вы определили диапазон изменения интервальной переменной таймера. Теперь если в соответствующем поле пользователь введет значение, выходящее за пределы допустимого диапазона, Visual C++ автоматически выведет подсказку с интервалом значений данной переменной. Вывод подсказки обеспечивает функция UpdataData(), которая вызывается функцией OnEnChangeEinterval.
Последняя из добавленных с помощью рабочей области переменных i_Count фактически используется как счетчик, значение в котором возрастает на единицу с каждым событием таймера.
Все объявленные нами переменные будет автоматически добавлены мастером как в объявление класса, так и в конструктор класса CTimersDlg. Разумеется в конструктор класса не добавлены переменные m_сStartTime и m_сStopTime, так как эти переменные ассоциированы с кнопками и их не надо инициализировать в конструкторе.
CTimersDlg::CTimersDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTimersDlg::IDD, pParent)
, m_sTime(_T(""))
, m_iInterval(0)
, m_sCount(_T(""))
, m_iCount(0)
{
Листинг 5.3
void CTimersDlg::OnEnChangeEinterval()
{
//если это элемент управления RICHEDIT,то элемент управления не будет
//посылать это уведомление, если вы не переопределите функцию
//CDialog::OnInitDialog()
//и не вызовете CRichEditCtrl(). SetEventMask()
// с флагом ENM_CHANGE, объединенным с помощью
операции OR(или) с маской
//здесь вставьте ваш код обрабочика событий от элемента управления
UpdateData(TRUE);
}
Функция void CTimersDlg::OnEnChangeEinterval() вызывается периодически постоянно согласно карты сообщений. Вот карта сообщений:
BEGIN_MESSAGE_MAP(CTimersDlg, CDialog)
Вверх
Чтобы привести второй таймер в рабочее состояние,необходимо выполнить
следующее:
Для этого выполните следующие пошаговые инструкции:
Листинг 5.4
. . . //часть кода пропущена
//инициализировать интервал отсчета
//обновить диалоговое окно
//запустить таймер часов
return TRUE;
Листинг 5.5
//инициализировать счетчик m_iCount
//Форматировать (Format) счетчик для отображения
//обновить диалоговое окно
//Запустить таймер-счетчик
//запустить таймер часов
помещен в функцию инициализации BOOL CTimerDlg::OnInitDialog
а код,запускающий таймер-счетчик :
//Запустить таймер-счетчик
помещен в функцию нажатия кнопки Start Timer:
Причем в первом случае интервал срабатывания таймера указан
константой (1000), а во втором случае интервал срабатывания
второго таймера указан при помощи переменной (m_iInterval).
Эта переменная в первый раз инициализируется программно в функции
//инициализировать интервал отсчета
В дальнейшей работе программы пользователь будет вводить
значение этой переменной интерактивно через управляющий
элемент Edit Box
Вы помните для этой переменной было предусмотрено
ограничение на ввод (защита от некорректного ввода)
Чтобы интервал вводился в разумных пределах.Минимум -1.
максимум 1000.
Листинг 5.6
//Обновленная функция OnTimer
switch(nIDEvent)
case ID_COUNT_TIMER:
}
CDialog::OnTimer(nIDEvent);
)
Анализ :
//инициализировать интервал отсчета
m_iInterval = 100;
UpdateData(FALSE);
UpdateData(TRUE);
Далее инициализируется переменная m_iCount,
которой присваивается 0 в качестве начального значения и форматируется
значение, держащееся в переменной m_sCount типа CString,которое затем
используется для обновления диалогового окна.
//инициализировать счетчик m_iCount
//Форматировать (Format) счетчик для отображения
//обновить диалоговое окно
Наконец функция запускает таймер ID_COUNT_TIMER используя значение
интервала таймера, записанное в переменной m_Interval.
//Запустить таймер
//остановить таймер
CTime curTime = CTime::GetCurrentTime();
Чтобы функция могла так же обрабатывать события от таймера-счетчика,
она должна уметь определять вызвавший ее таймер.
Единственным аргументом функции OnTimer() является
идентификатор таймера. Чтобы определить таймер,вызвавший данную функцию,
и выбрать тот код, который нужно выполнить, можно воспользоваться
оператором выбора switch.
switch(nIDEvent)
case ID_COUNT_TIMER:
}
CDialog::OnTimer(nIDEvent);
)
При этом программный код таймера-часов остается
неизменным.(Листинг 5.2):
CTime curTime = CTime::GetCurrentTime();
Код счетчика-таймера размещается в соответствующей
ветви оператора выбора switch.
Этот код увеличивает значение счетчика
и обновляет значение переменной m_sCount.
m_iCount++;
Теперь можно скомпилировать и запустить приложение.
Задайте значение интервала таймера и запустите таймер.
Приложение работает хорошо. Но в данном приложении имеется "ошибка"
(Смотри далее текст).
Назад |
Вверх |
Вперед
Запуск и остановка счетчика-таймера
BOOL CTimerыDlg::OnInitDialog
{
m_iInterval = 100;
UpdateData(FALSE);
SetTimer(ID_CLOCK_TIMER,1000,NULL);
void CTimersDlg::OnBnClickedBstarttime()
{
UpdateData(TRUE);
m_iCount = 0;
m_sCount.Format("%d",m_iCount);
UpdateData(FALSE);
SetTimer(ID_COUNT_TIMER,m_iInterval,NULL);
SetTimer(ID_CLOCK_TIMER,1000,NULL);
SetTimer(ID_COUNT_TIMER,m_iInterval,NULL);
void CTimersDlg::OnBnClickedBstarttime()
BOOL CTimerыDlg::OnInitDialog
m_iInterval = 100;
UpdateData(FALSE);//вывести значение на экран
Отредактируте функцию OnBnClicedBstoptimer следующим образом.
OnBnClicedBstoptimer
{
KillTimer(ID_COUNT_TIMER);
void CTimersDlg::OnTimer(UINT nIDEvent)
{
CTime curTime = CTime::GetCurrentTime();
{
break;
m_sCount.Format("%d",m_iCount);
break;
m_iCount = 0;
m_sCount.Format("%d",m_iCount);
UpdateData(FALSE);
SetTimer(ID_CLOCK_TIMER,m_iInterval,NULL);
KillTimer(ID_COUNT_TIMER);
она все еще содержит код для обработки события от таймера часов:
m_sTime = curTime.Format("%H:%M:%S");
void CTimersDlg::OnTimer(UINT nIDEvent)
{
CTime curTime = CTime::GetCurrentTime();
{
break;
m_sCount.Format("%d",m_iCount);
break;
m_sTime = curTime.Format("%H:%M:%S");
m_sCount.Format("%d",m_iCount);
Содержание