Назад | Начало урока | Вперед
Содержание

День 5 (продолжение 2)

  • Разблокирование кнопки останова
  • Резюме
  • Вопросы и ответы
  • Практические занятия


    Внимание!
    В данном приложении (смотри вышеизложенный материал) имеется "ошибка". Проявляется она так: При вводе в поле редактирования значения, выходящего за допустимые пределы, всплывает предупреждающее сообщение.

    Не смотря на то, что открыто окно с предупреждающим сообщением, таймер часов запускается и предпринимает попытку обновления значений, отображаемых элементами управления. С этой целью вызывается функция UpdateData.

    Но ведь процесс инициализации переменных значениями, хранящимися в элементах управления еще не завершен! В результате возникает конфликт реентерабельности, который приводит к аварии. Чтобы избежать подобной ситуации, необходимо в диалоговый класс добавить дополнительную логическую переменную.

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

    Итак функция OnEnChangeEinterval должна иметь такой вид:

    void CTimerDlg::OnEnChangeEinterval() {

    //предотвратить обновление (Prevent updating) экрана
    m_bPreventUpdate = TRUE;

    //модифицировать переменные
    UpdateData(TRUE);

    //позволить обновление экрана
    m_bPreventUpdate = FALSE;

    }

    Что касается функции OnTimer,то она могла бы выглядеть следующим образом:

    void CTimerDlg::OnTimer(UINT nIDEvent)
    {

    ...

    if(m_bPreventUpdate)
    UpDateData(FALSE);
    CDialog::OnTimer(nIDEvent);
    }

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

    void CTimerDlg::OnBnClicedBstarttime
    {
    m_bPreventUpdate = TRUE;

    UpdateData(TRUE);

    m_bPreventUpdate = FALSE;

    if(m_iInterval < 1 || (m_iInterval > 100000))
    return;

    ...
    }


    Откомпилируйте и запустите программу.


    Вверх

    Разблокирование кнопки останова

    Запустив приложение вы увидите что работает оно хорошо, но есть одна маленькая проблема. Однажды запустив второй таймер вы его не сможете остановить. Причина в том, что при определении свойств элементов управления, была заблокирована кнопка Stop Timer. Чтобы остановить таймер необходимо ее разблокировать.

    Можно сделать даже еще лучше - после запуска таймера разблокировать кнопку останова и заблокировать кнопку пуска. В случае если таймер еще не запущен, то необходимо проделать все наоборот. Это можно сделать аналогично как было выполнено в главе 3 или воспользоваться несколько иным способом.

    Вспомните когда вы добавляли переменные к элементам управления, были так же добавлены определенные переменные к кнопкам останова и пуска. Эти переменные не являются переменными в обычном понимании. Это переменные элементов управления. Можно непосредственно использовать переменные управления, а не получать указатели на элементы управления, зная их идентификаторы. Попробуем сделать это обновив функцию OnBnClicedBstarttime


    void CTimerDlg::OnBnClicedBstarttime()
    {
    UpDateData(TRUE);

    m_iCount = 0;

    m_strCount.Format("%d",m_iCount);

    UpDateData(FALSE);

    SetTimer(ID_COUNT_TIMER,m_iInterval,NULL);

    m_cStopTime.EnabltWindow(TRUE);
    m_cStartTime.EnabltWindow(FALSE);

    }


    void CTimerDlg::OnBnClicedBstoptime()
    {
    KillTimer(ID_COUNT_TIMER);

    m_cStopTime.EnabltWindow(TRUE);
    m_cStartTime.EnabltWindow(FALSE);

    }


    Скомпилируйте и запустите приложение.Теперь можно запускать и останавливать счетчик-таймер.Задавайте различные значения временного интервала и наблюдайте что происходит.Для сравнения пользуйтесь часами,находящимися над счетчиком.


    Вверх

    Резюме
    Вы научились использовать таймеры операционной системы Windows для запуска ваших приложений через указанное вами время. Вы научились в одном приложении использовать сразу несколько таймеров, запускающих разные действия.

    В следующих главах вы научитесь применять дополнительные диалоговые окна для поддержки обратной связи между пользователем и приложением.Обратная связь будет использоваться для управления поведением ваших приложений. Далее вы научитесь создавать приложения с меню. Затем вы научитесь писать приложения работающие с текстом и графикой.

    Вверх

    Вопросы и ответы
    1. В каком диапазоне можно изменять значения временного интервала таймера?

      Ответ: От 55 миллисекунд снизу до 2 в степени 32 минус 1 сверху (примерно 49,5 дней)

    2. Сколько таймеров можно запустить а приложении одновременно?

    3. Какими двумя способами можно создать и инициализировать объект типа CTime?

      Читай рубрику "Создание и инициализация даты и времени".
      Есть несколько методов создания объекта данного класса. И в них объект инициализируется сразу после его создания.

      Первый метод:

      CTime curTime = CTime::GetCurrentTime();

      Здесь для инициализации нового объекта текущим временем используется метод GetCurrentTime(), который возвращает объект CTime.

      Другим методом создания и инициализиции объекта CTime является использование следующей версии конструктора :

      CTime(int Year, int iMonth, int iDay, int iHour, int iMin, int iSec, int iDst);

      Данный конструктор инициализирует объект значениями года, месяца, дня, часа, минут, секунд.

    4. Существует ли способ заставить простаивающее приложение выполнить определенные действия, при котором не используется таймер для инициирования этих действий в тот момент, когда приложение могло бы быть неактивным?

      Существует.Во всех приложениях Windows можно воспользоваться функцией OnIdle. С ее помощью можно инициировать выполнение определенных действий простаивающим приложением. Функция OnIdle рассматривается в главе 17 "Реализация многозадачности в приложениях"

    Практические занятия
    Вверх
    Вопросы:
    1. К чему привело добавление к символам ресурсов(Resours Simbols) идентификаторов двух таймеров?

    2. Каким еще способом можно добавить к приложению эти идентификаторы?

    3. Как функция OnTimer отличает таймеры один от другого?

    4. Сколько сообщений о событиях таймера получит приложение,в случае если оно было занято на протяжении минуты, вследствии чего получение сообщений о событиях таймера было заблокировано, а временной интервал таймера составляет одну секунду?

    Упражнения:
    Измените приложение таким образом, чтобы в момент запуска таймера-счетчика, временной интервал таймера-часов инициализировался значением временного интервала таймера-счетчика. После остановки таймера-счетчика, установите односекундный интервал для таймера-часов.

  • Приложение (ответы на вопросы и упражнения)

    Назад | Вверх | Вперед
    Содержание

    Hosted by uCoz