В этой статье мы подробно разберем, как создать программу-будильник со звуком на C# в Windows Forms.
Для начала создаём форму. Выглядит она вот так:
Здесь у нас Label с вот такими свойствами
:
На нём у нас будет показано текущее время.
Ниже идёт MaskedTextBox. Отличие MaskedTextBox’a от простого TextBox’a в том, что в нём можно задавать маску, которая помогает пользователю вводить правильный тип данных.
Настройка MaskedTextBox’a проходит следующим образом. В данном элементе, при его выделении в правом верхнем углу появляется небольшая стрелка . При нажатии всплывёт окошко, как показано ниже. Нажимаем «Установка маски».
В MaskedTextBox мы будем вводить время для будильника. По всем стандартам время всегда показывается через двоеточие — часы:минуты:секунды. Понятное дело, что пользователю самому каждый раз писать двоеточие между часами и минутами очень неудобно, поэтому мы облегчаем ему ввод данных, В окне, которое откроется после нажатия на «Установку маски» выбираем строку Time. Она сразу переведёт введённые пользователем данные в формат DateTime и позволит не возиться в двоеточиями между часами и минутами.
Нажимаем «ОК». Теперь для того, чтобы поставить время, пользователю надо ввести лишь четыре цифры. Первые две — это часы, последние две — минуты.
Также в «Свойствах» для MaskedTextBox’a мы изменили размер текста:
Под MaskedTextBox’ом у нас спрятался Label2:
Нужен он нам для того, чтобы получать в себя значения из MaskedTextBox’a, и основываясь на нём, один из наших таймеров получит сведения, когда должен зазвонить будильник.
Далее идут два Button’a — первый будет заводить будильник, а второй выключать его, когда звонок сработает.
Также добавляем два Timer’a. Первый будет показывать время, а второй будет отвечать за то, чтобы будильник сработал вовремя.
С дизайном разобрались. Далее нажимаем правой кнопкой мыши на форме и выбираем «Перейти к коду».
Перво-наперво подключаем библиотеку работы со звуком:
1 |
using System.Media; |
Она нам понадобится для воспроизведения мелодии будильника.
Далее мы в теле кода класса Form1 объявляем несколько переменных:
1 2 3 4 5 |
public partial class Form1 : Form { Timer timer01 = new Timer(); SoundPlayer sp = new SoundPlayer("F:\\1.wav"); bool b = false; |
Сначала мы объявляем первый таймер, так как он у нас будет на виду, и ему надо будет придать вменяемый внешний вид.
Далее объявляем переменную, которая запустит нам в нужный момент мелодию. В данном случае мелодия лежит на диске F, а сам файл называется 1.wav.
Обязательно к прочтению: библиотека System.Media может работать лишь с форматом WAV PCM. Иначе в программе будет ошибка. В интернете имеется много программ, которые переводят файлы музыки в этот формат, да и сам этот формат ещё можно найти на просторах сети, главное, чтобы он был оцифрован при помощи PCM.
Также мы объявляем переменную типа bool (имеет только два состояния — true и false). Понадобится она нам для того, чтобы менять принцип работы кнопки «Завести будильник». Позже мы присвоим этой кнопке второе «состояние» — «Убрать будильник», когда тот будет заведен. Так при нажатии на одну кнопку при разных значениях переменной b данная кнопка будет выполнять разную работу.
Эти три переменные мы вынесли в самую основу кода для того, чтобы любые функции, которые будут дальше имели к ним доступ, потому что если, например, объявить переменную bool b в какой-либо отдельной функции, то другие функции не смогут получить к этой переменной доступ, они попросту не найдут её.
Далее мы возвращаемся в форму и дважды нажимаем на неё левой кнопкой мыши, чтобы перенестись в к участку кода загрузки формы. Код, написанный там, будет исполняться при загрузке формы, то есть сразу при запуске программы. Там мы пишем следующее:
1 2 3 4 5 6 7 |
private void Form1_Load(object sender, EventArgs e) { button2.Enabled = false; timer01.Interval = 1000; timer01.Tick += new EventHandler(timer1_Tick); timer01.Start(); } |
Строка button2.Enabled = false закрывает доступ к кнопке «Остановить будильник». Мы сделали это для того, чтобы пользователь не нажимал на неё раньше времени. Позже мы сделаем её кликабельной во время запуска звонка будильника, чтобы можно было его остановить.
Строкой timer01.Interval ==1000 мы объявляем, что наш таймер, отвечающий за текущее время, будет обновляться в форме каждые 1000 миллисекунд (иначе говоря, каждую секунду). Нам это необходимо, так как у нас в Label’e последние два «символа» отведены под секунды.
Следующая строка означает, что таймер будет реагировать и срабатывать при событии “Tick”. Событие Tick будет описано ниже, в нём будет указано, что в Label’e должно показываться текущее время. Иначе говоря, таймер благодаря timer01.Interval будет каждую секунду выполнять событие обновления времени в Label’е, используя timer01.Tick.
Ну, и, наконец, мы запускаем наш таймер. При загрузке формы он сразу же будет показывать текущее время.
Теперь мы опять возвращаемся в нашу форму и дважды нажимаем внизу страницы на .
Вот и открылся участок кода с названием timer1_Tick! Именно тот код, который мы сейчас напишем внутри тела этой функции, будет обновляться каждую секунду в форме.
Как уже было сказано ранее, здесь мы выведем в Label1 наше текущее время. Внутри тела функции timer1_Tick пишем:
1 |
label1.Text = DateTime.Now.Hour.ToString("00") + ":" + DateTime.Now.Minute.ToString("00") + ":" + DateTime.Now.Second.ToString("00"); |
Сначала мы записываем часы, затем минуты, затем секунды. Часть кода, отвечающая за часы выглядит так: DateTime.Now.Hour.ToString(«00»), дословно это примерно переводится как «Время.Сейчас.Часы.Строкой» то есть мы выводим текущее количество часов в виде строки (изначально такие значения имеют тип DateTime, поэтому их все надо переводить в строку). То же самое пишем для минут (только вместо Hour — Minute) и секунд (Second). Между ними мы прописываем двоеточия, чтобы наше время не слипалось в одно число и было читабельно.
Но что же за скобки с нулями? Мы пишем это для того, чтобы время выводилось в привычном нам формате: 00:00:00. Без этих нулей, например, 9 часов, 5 минут и 14 секунд будут выглядеть в программе так: 9.5.14. Это немного режет глаза, поэтому мы добавляем нули в те значения времени, которые записаны одной цифрой (то есть все числа меньше десяти). Таким образом время у нас будет выглядеть как 09.05.14, и это гораздо приятнее. Иначе говоря, если в данный момент время двухзначное,например, 12 часов, то вместо первого нуля пишется 1, а вместо второго — 2. Если же время — 5 часов утра, то первый ноль остаётся нетронутым, а вот вместо второго пишется цифра 5. Таким же образом заполняются и минуты, и секунды.
Итак, наш таймер, показывающий время, работает. Идём дальше -разбираемся с кнопкой «Завести будильник». Для этого в форме два раза кликаем на ней.
Тут нам понадобится наша буллевая перемена b. Мы сделаем так, что при нажатии на эту кнопку можно было и завести будильник, и снять его с завода.
Выглядеть в форме это будет так:
Эта кнопка в зависимости от определённой ситуации будет выполнять два противоположных действия. Сейчас мы напишем первый случай, когда нам надо будет завести будильник. При нажатии на кнопку у нас запустится второй таймер, который начнёт отсчитывать часы, минуты и секунды до момента времени, который будет указан в maskedTextBox’e, доступ к maskedTextBox’у будет закрыт до повторного нажатия на кнопку(чтобы нельзя было менять уже указанное время, пока будильник заведен), а текст на кнопке будет изменен на «Убрать будильник».
1 2 3 4 5 6 7 8 |
if (b == false) { label2.Text = maskedTextBox1.Text; timer2.Start(); maskedTextBox1.Visible = false; button1.Text = "Убрать будильник"; b=true; } |
Как мы помним, изначально b у нас был в состоянии false, поэтому при нажатии на кнопку в первый раз у нас сработает именно этот код.
Мы заносим в скрытый Label2 значение из MaskedTextBox’а. Запускаем таймер. Скрываем MaskedTextBox (у нас остаётся значение в Label’e). Затем мы меняем текст на кнопке на «Убрать будильник», и, очень важно, меняем значение b на true. Итак, при первом нажатии на Button1 у нас в программе произойдут описанные выше изменения.Теперь мы напишем код под стать кнопке «Убрать будильник».
1 2 3 4 5 6 7 8 |
else if(b==true) { label2.Text = "00:00"; timer2.Stop(); maskedTextBox1.Visible = true; button1.Text = "Завести будильник"; b = false; } |
Мы обнуляем Label2, останавливаем таймер, возвращаем MaskedTextBox (теперь пользователь его снова видит), меняем текст на кнопке обратно на «Завести будильник» и присваиваем переменной b значение false. То есть если мы нажмём кнопку ещё раз (третий), то опять сработает завод будильника. Благодаря переменной b у нас один раз будет срабатывать код для false, второй раз для true, третий — для false, четвертый — для true, и так через раз.
Теперь нам надо настроить Timer2, отвечающий за срабатывание звонка будильника. В окне, где у нас форма, дважды нажимаем на второй таймер, он находится рядом с первым.
Пишем для него следующий код:
1 2 3 4 5 |
if (label1.Text == label2.Text + ":00") { button2.Enabled = true; sp.Play(); } |
Если текст из первого Label’a будет таким же, как текст из второго Label’a, к которому прибавляется «:00», то мы разблокировываем кнопку «Остановить будильник» и включаем мелодию из переменной sp.
Может возникнуть вопрос: а почему мы ко второму Label’у прибавляем двоеточие и два нуля?
Дело в том, что иначе у нас никогда не совпадут значения в Label’ах, ведь в первом имеются часы, минуты и секунды, а во втором только часы и минуты(заводить будильник с секундами как-то глупо), поэтому мы как бы добавляем эти секунды двоеточием и двумя нулями. То есть, если мы завели будильник на 12:43, то для компьютера это время будет выглядеть как «12:43:00», и как только такое же время будет показано на первом Label’e, зазвенит будильник.
Нам остаётся лишь настроить код кнопки «Остановить будильник», которая выключит звонок. Дважды нажимаем на эту кнопку в форме и пишем:
1 2 3 4 5 |
sp.Stop(); button2.Enabled = false; maskedTextBox1.Visible = true; button1.Text = "Завести будильник"; b = false; |
При нажатии на эту кнопку останавливается мелодия, затем кнопка «Остановить будильник» снова становится недоступной (до нового завода будильника и нового проигрывания мелодии), возвращается MaskedTextBox1, которого не было, потому что, как мы помним, при заводе он скрывается, а вместо него остаётся Label2, текст на кнопке завода/снятия будильника меняется на «Завести будильник», и b становится в значении false (чтобы при нажатии на кнопку «Завести будильник», сработал нужный нам код.
Вот и всё, работу кода можно проверить по ссылке ниже:
Скачать исходникПоделиться в соц. сетях:
Подскажите пожалуйста как ограничить MaskedTextBox до 23:59?
Автоматического пути сделать это нету. Автоматически можно только уведомить пользователя о неправильном вводе — здесь написано, как это сделать.
Ограничить ввод вы можете только вручную, проверяя его правильность при каждом изменении значения в MaskedTextBox.
Почему он мне выдает ошибку, он что может воспроизводить файлы только в PCM формате, а в WAV не может?
Диниил, в статье же написано, что используемая библиотека работает только с форматом WAV PCM. Обязательно нужно, чтобы WAV-файл был оцифрован при помощи PCM.
А как на visual basic код написать к такой форме в Visual Studio?