Не смотря на то, что открыто окно с предупреждающим сообщением, таймер часов запускается и предпринимает попытку обновления значений, отображаемых элементами управления. С этой целью вызывается функция UpdateData.
Но ведь процесс инициализации переменных значениями, хранящимися в элементах управления еще не завершен! В результате возникает конфликт реентерабельности, который приводит к аварии. Чтобы избежать подобной ситуации, необходимо в диалоговый класс добавить дополнительную логическую переменную.
Эта переменная будет использоваться для того, чтобы предупредить попытку обновления элементов управления, происходящую в результате запуска события таймера, причем запрет на обновление будет оставться в силе до завершения обработки события, связанного с изменением редактируемого поля.
Итак функция OnEnChangeEinterval должна иметь такой вид:
//предотвратить обновление (Prevent updating) экрана
//модифицировать переменные
//позволить обновление экрана
}
void CTimerDlg::OnEnChangeEinterval()
{
m_bPreventUpdate = TRUE;
UpdateData(TRUE);
m_bPreventUpdate = FALSE;
Что касается функции OnTimer,то она могла бы выглядеть следующим образом:
...
if(m_bPreventUpdate)
void CTimerDlg::OnTimer(UINT nIDEvent)
{
UpDateData(FALSE);
CDialog::OnTimer(nIDEvent);
}
Наконец чтобы предупредить запуск таймера,функция OnBnClicedBstarttime могла бы выглядеть так :
UpdateData(TRUE);
m_bPreventUpdate = FALSE;
if(m_iInterval < 1 || (m_iInterval > 100000))
...
void CTimerDlg::OnBnClicedBstarttime
{
m_bPreventUpdate = TRUE;
return;
}
Вверх
Запустив приложение вы увидите что работает оно хорошо, но есть одна
маленькая проблема. Однажды запустив второй таймер вы его не сможете
остановить. Причина в том, что при определении свойств элементов управления,
была заблокирована кнопка Stop Timer. Чтобы остановить таймер необходимо
ее разблокировать.
Можно сделать даже еще лучше - после запуска таймера разблокировать
кнопку останова и заблокировать кнопку пуска. В случае если таймер еще
не запущен, то необходимо проделать все наоборот. Это можно сделать
аналогично как было выполнено в главе 3 или воспользоваться несколько
иным способом.
Вспомните когда вы добавляли переменные к элементам управления, были так
же добавлены определенные переменные к кнопкам останова и пуска.
Эти переменные не являются переменными в обычном понимании.
Это переменные элементов управления. Можно непосредственно использовать
переменные управления, а не получать указатели на элементы управления,
зная их идентификаторы.
Попробуем сделать это обновив функцию OnBnClicedBstarttime
m_iCount = 0;
m_strCount.Format("%d",m_iCount);
UpDateData(FALSE);
SetTimer(ID_COUNT_TIMER,m_iInterval,NULL);
m_cStopTime.EnabltWindow(TRUE);
}
m_cStopTime.EnabltWindow(TRUE);
}
Скомпилируйте и запустите приложение.Теперь можно запускать и
останавливать счетчик-таймер.Задавайте различные значения временного
интервала и наблюдайте что происходит.Для сравнения пользуйтесь
часами,находящимися над счетчиком.
Вверх
В следующих главах вы научитесь применять дополнительные диалоговые окна
для поддержки обратной связи между пользователем и приложением.Обратная
связь будет использоваться для управления поведением ваших приложений.
Далее вы научитесь создавать приложения с меню. Затем вы научитесь
писать приложения работающие с текстом и графикой.
Вверх
Ответ: От 55 миллисекунд снизу до 2 в степени 32 минус 1 сверху
(примерно 49,5 дней)
Читай рубрику "Создание и инициализация даты и времени".
Первый метод:
CTime curTime = CTime::GetCurrentTime();
Здесь для инициализации нового объекта текущим временем используется
метод GetCurrentTime(), который возвращает объект CTime.
Другим методом создания и инициализиции объекта CTime является
использование следующей версии конструктора :
CTime(int Year, int iMonth, int iDay, int iHour, int iMin, int iSec,
int iDst);
Данный конструктор инициализирует объект значениями года, месяца, дня,
часа, минут, секунд.
Существует.Во всех приложениях Windows можно воспользоваться функцией
OnIdle. С ее помощью можно инициировать выполнение определенных действий
простаивающим приложением. Функция OnIdle рассматривается в главе 17
"Реализация многозадачности в приложениях"
Назад |
Вверх |
Вперед
Разблокирование кнопки останова
void CTimerDlg::OnBnClicedBstarttime()
{
UpDateData(TRUE);
m_cStartTime.EnabltWindow(FALSE);
void CTimerDlg::OnBnClicedBstoptime()
{
KillTimer(ID_COUNT_TIMER);
m_cStartTime.EnabltWindow(FALSE);
Резюме
Вы научились использовать таймеры операционной системы Windows для
запуска ваших приложений через указанное вами время.
Вы научились в одном приложении использовать сразу несколько таймеров,
запускающих разные действия.
Вопросы и ответы
Есть несколько методов создания объекта данного класса.
И в них объект инициализируется сразу после его создания.
Практические занятия
Вверх
Вопросы:
Упражнения:
Измените приложение таким образом, чтобы в момент запуска таймера-счетчика,
временной интервал таймера-часов инициализировался значением временного
интервала таймера-счетчика. После остановки таймера-счетчика, установите
односекундный интервал для таймера-часов.
Содержание