ПОНЯТНО О Visual Basic NET (том 2)

Делаем секундомер


Размести в проекте второй таймер, дав ему имя Таймер_секундомера. Поместим в рамку с именем Секундомер элементы управления для секундомера и дадим им имена:

  • Циферблат_секундомера (это метка)
  • Кнопка_пуска_паузы_секундомера
  • Кнопка_обнуления_секундомера
  • а также не забудем метку с текстом «Секундомер».

    Таймер нужен секундомеру для того же, для чего и часам, а именно – чтобы вовремя менялись цифры на циферблате, а собственный

    таймер предпочтительно (но в нашем случае не обязательно) иметь для того, чтобы не зависеть от часов. Поскольку нам нужно отслеживать сотые доли секунды, установим ему интервал меньше 10. Когда секундомер считает, таймер секундомера должен работать:

            Таймер_секундомера.Enabled = True

    а когда он в паузе или в нуле, таймер может и отдохнуть:

            Таймер_секундомера.Enabled = False

    Режимы работы секундомера. Если будильник в каждый момент времени может находиться в одном из двух состояний (режимов) – установлен или не установлен, то секундомер – в трех:  считает, стоит в паузе, стоит в нуле. Придумаем переменную и дадим ей имя Режим _секундомера. Объявить ее типом Boolean  явно недостаточно, ведь в типе Boolean всего два возможных значения, а нам нужно три. Здесь напрашивается перечисление:

        Enum Режим

            считает

            пауза



            в_нуле

        End Enum

        Dim Режим_секундомера As Режим

    Для каждого режима нам придется организовать свою переменную для отсчета секунд на секундомере:

        Dim Секунды_на_секундомере As Double

        Dim Секунды_при_запуске_секундомера As Double

        Dim Секунды_на_паузе_секундомера As Double

    Обратите внимание, что эти переменные, хоть и имеют смысл времени, объявлены, как дробные числовые, а не как Date. Почему так получилось и почему переменных три, а не одна, сейчас попытаюсь пояснить.

    Для отсчета времени на секундомере мы будем использовать известную вам функцию

    Timer класса DateAndTime (не путайте с элементом управления Timer), потому что она выдает секунды с дробной частью (нас устроят сотые доли секунды – какой же секундомер без сотых долей). Поскольку она выдает число секунд, прошедших с полуночи, а нам нужно число секунд, прошедших с момента запуска секундомера, да еще с учетом того, что во время паузы на секундомере уже стояли какие-то показания, нам придется поразмыслить, как это сделать.


    Засечем в момент пуска секундомера значение функции Timer оператором
            Секунды_при_запуске_секундомера = DateAndTime.Timer
    Тогда в каждый момент времени после запуска секундомера выражение
    DateAndTime.Timer - Секунды_при_запуске_секундомера
    как раз и будет равняться числу секунд, прошедших с момента запуска секундомера. А если нам удастся правильно засечь Секунды_на_паузе_секундомера (имеющие смысл секунд, прошедших с момента пуска до паузы), то дело решит оператор
            Секунды_на_секундомере = DateAndTime.Timer - Секунды_при_запуске_секундомера  _
    + Секунды_на_паузе_секундомера
    Если поместить его в процедуру таймера, то он будет оперативно выдавать нужные для циферблата секунды.
    Внешний вид показаний секундомера. Переменная Секунды_на_секундомере – это дробное число типа Double. Например, такое –  65.28194. Но на секундомере эти самые цифры, сами понимаете, должны выглядеть по-другому –  00:01:05.28. Для этого нам нужно как-то преобразовать число секунд в стандартный формат времени. Организуем переменную и константу:
            Dim Время_на_секундомере As Date
            Const Полночь As Date = #12:00:00 AM#
    Здесь время   #12:00:00 AM#  обозначает, как ни странно, полночь по-американски.
    Дело решает пара операторов:
            Время_на_секундомере = Полночь.AddSeconds(Секунды_на_секундомере)
            Циферблат_секундомера.Text = Format(Время_на_секундомере, "mm:ss.ff")
    Кнопки секундомера. Теперь нам нужно подумать о том, что должно происходить во время нажатия на кнопки секундомера. Наши размышления должны течь примерно в том же русле, что и размышления о кнопках и метке будильника. Никакой новой идеологии по сравнению с будильником вы не обнаружите. По аналогии с будильником вы, наверное, должны придти к выводу о необходимости создания трех процедур:
        Sub Секундомер_обнулить()
        Sub Секундомер_остановить()
        Sub Секундомер_запустить()
    Я думаю, эти размышления вам полезно будет довести до конца самостоятельно. А проверить себя вы сможете, заглянув в окончательный текст программы ниже. Все процедуры, касающиеся будильника собраны вместе и вы их легко найдете.
    Еще о режиме. Самые дотошные из вас, разобравшись в программе, скажут мне, что нечего было огород городить – создавать перечисление, когда можно было обойтись логической переменной Секундомер_считает. Верно. Но неправильно. Потому что нужно оставлять простор для дальнейшего развития проекта. Например, вы можете в будущем захотеть, чтобы во время паузы цифры на секундомере мигали, а в нуле – нет.

    Содержание раздела