среда, 27 апреля 2011 г.

Урок 6. Не много ли два таймера в одной программе?! (компонент TTimer)


Мой любимый сатирик Михаил Михайлович Жванецкий в одном из своих произведений сказал такую фразу: «У меня в доме все по два, по четыре, по шесть, по восемь...» Но, как бы я не относился к творчеству и личности замечательного писателя, но для разработки начатой нами несколько уроков назад программы, мы все же не будем пользоваться его советом.
Тем не менее, забегая вперед, отмечу, что обойтись одним компонентом «Таймер» нам вряд ли удастся.
Итак, открываем палитру компонентов, находим раздел «System» и перетаскиваем на форму компонент Ttimer.






В свойствах этого элемента нужно указать:
Enabled=False         иначе таймер начнет отсчет сразу после запуска приложения, а мы такой цели себе не ставили
Interval= любое целое число, например: 3000 (что соответствует 3 секундам). Этого вполне достаточно для отладки.
Если дважды щелкнуть на нем, то оболочка создаст заготовку процедуры, обрабатывающей момент срабатывания таймера. В этот самый момент нам нужно:

  • прекратить отсчет времени, остановить таймер,
  • перевести элементы управление (кнопки, пункты меню, если необходимо) и т.п. в положение при котором будет воспроизводиться звуковой сигнал
  • вывести сообщение оператору об окончании отсчета,
  • воспроизвести звуковой сигнал заданное количество раз,
  • вернуть элементы управления в стартовое состояние.
Наполним процедуру операторами и комментариями (в тех местах алгоритма, которые еще остаются непонятными).
procedure TForm1.Timer1Timer(Sender: Tobject);
begin

// Остановить таймер
Timer1.Enabled:=False;
// Кнопки в положение “Проигрывание”

// Вывод сообщения оператору
MyLabel4.Caption:='Отсчет завершен';

// Воспроизвести звук несколько раз или бесконечно
// Вернуть элементы управления в стартовое состояние
end;

Теперь для заготовленного нами действия «Start» напишем процедуру: пора запустить, наконец, наш таймер.
procedure TForm1.Do_StartExecute(Sender: TObject);
begin
// Старт таймер
Timer1.Enabled:=True;
end;

Если Вы все сделали правильно, то через три секунды, заданные в качестве интервала срабатывания таймера, вы увидите надпись “Отсчет завершен”.
“Ну и что?” - скажете Вы. “Не красиво”, - отвечу я.
Хочется, чтобы что-то мелькало, чтобы видно было, что ведется отсчет. Т.е. каждую секунду, мы хотим видеть, как уменьшается заданный интервал времени, как ведется обратный отсчет. Ключевая фраза - “каждую секунду”. Какой же еще компонент, кроме TTimer способен отсчитать секунду? Но, один единственный компонент, уже имеющийся в нашем приложении занят отсчетом “от забора и до обеда”. Вот тут-то и понадобится наличие второго компонента TTimer. Скорее разместите его на форме, установив также в False его свойство Enabled.
Добавьте строчку в программу Timer1Timer:
Timer2.Enabled:=False; // После окончания отсчета основного времени второй таймер тоже должен остановиться.
А затем так же дважды щелкните по изображению компонента Timer2.
Нам хотелось бы, чтобы в надписи на форме отображался обратный отсчет времени, как в фильмах про бомбы с часовым механизмом :-).
MyLabel4.Caption:=IntToStr(А что же здесь?????);
Для решения этого вопроса ,как и для решения многих других существует несколько путей. Можно завести глобальную переменную, а можно воспользоваться вспомогательным скрытыс полем по имени Sec, которое я организовал на предыдущем видео уроке, тогда процедура примет вид:
procedure TForm1.Timer2Timer(Sender: TObject);
begin
Sec.Value:=Sec.Value-1;
MyLabel4.Caption:=IntToStr(Sec.Value);
end;
Предвижу законный вопрос: “А откуда же возьмется начальное значение в этом поле?”
Давайте с этой целью создадим процедуру, не забыв дать ее объявление в разделе Private:
procedure TForm1.SetMyLabel();
begin
Sec.Value:=3;                                   // В секундах
MyLabel4.Caption:=Sec.Value;
end;

Чтобы вспомогательное поле было готово выполнять свою функцию, в него нужно занести значение в момент создания формы (процедура FormCreate):

SetMyLabel();
Не забудьте добавить в процедуру Do_StartExecute строчку, визуализирующую изменения, и строчку, запускающую второй таймер:
SetMyLabel();
Timer2.Enabled:=True;
Нужно еще “научить” программу прерывать все отсчеты при нажатии кнопки “Стоп”:
procedure TForm1.Do_StopExecute(Sender: TObject);
begin

// Остановка таймера
Timer1.Enabled:=False;
MyLabel4.Caption:='Таймер остановлен';
Timer2.Enabled:=False;

end;
Теперь, когда все готово, компилируем приложение и получаем настоящий таймер: секунды мелькают на экране.

вторник, 19 апреля 2011 г.

Урок 5. Установка компонентов сторонних производителей (библиотека EhLib)


Изобретая велосипед, всегда полезно оглядеться: может, кто-то уже...  остается просто попросить его дать покататься?! В какой бы Вы ни работали среде разработки, уверен, что стандартная поставка не удовлетворит всех Ваших запросов. Рано или поздно, Вас что-то перестанет устраивать и Вы начнете поиск решений. Так и в нашем случае.
Для программы требуется компонент, с помощью которого можно было бы вводить целые числа (минуты или секунды). В стандартном наборе есть два компонента TEdit и TMaskEdit, про которые Вы можете почитать в книгах или вот здесь:http://www.beluch.ru/progr/100comp/3_3_3.htm
Можно, конечно, и их использовать... Приспособить... Но они имеют ряд недостатков для решения нашей конкретной задачи. Работая с компонентом TEdit, нужно будет писать код проверки на предмет: не ввел ли пользователь по ошибке букву вместо цифры? А затем для математических вычислений не забывать переводить текстовую информацию в число.
Про TMaskEdit на том же сайте написано, цитирую “ К сожалению, среди файлов стандартных масок, поставляемых с Delphi, отсутствует маска, соответствующая российским стандартам.“ Грустно...
Там же говорится об ограничениях: “Рассмотрим еще пример. Если с помощью EditMask надо ввести, например, целое число без знака, состоящее не более, чем из двух цифр, можно задать маску 99;0; . Если число обязательно должно быть двузначным, то маска должна иметь вид 00;0;“ А ,если мы не знаем заранее, сколько знаков будет в числе?
В таком случае можно поискать, не написал ли кто-то уже полезный нам компонент, пока мы еще не умеем делать этого сами?
Прежде, чем что-то искать, посмотрите на набор установленных компонентов, может, по волшебству у Вас уже есть все необходимое:






Если же никаких признаков Вам обнаружить не удалось, предлагаю ссылку на сайт производителя довольно популярного набора полезных компонентов библиотеки EhLib: http://www.ehlib.com/RUS/default.htm.

Пусть Вас сильно не смущает, что набор компонентов предназначен для работы с данными. Не обязательно использовать эти возможности.
EhLib = Shareware, т.е. - штуковина не бесплатная. Вот, к примеру, информация о стоимости одного из пакетов:
“Ehlib - версия с исходными кодами для физических лиц при оплате через Яндекс.Деньги - 1300 руб.”
Но, там же, на сайте производителя в разделе “Регистрация”, есть ссылка, дающая возможность качать  бесплатную версию 3,6.
Это - архив. Скачайте файл и запустите его. Пароль приведен на том же сайте (ФЕВРАЛЬФЕВРАЛЬ - буквы большие). Распакуйте содержимое в ту же папку, куда был скачан архив. Архив после этого можно удалить.
Откройте файл readme.txt.
Найдите в нем раздел “2. Delphi 4.x - 7.x, Delphi 9.X Win32:”
Первое, что рекомендуется сделать - удалить предыдущую версию. Это нужно уметь делать, если вдруг понадобится переустановка. Но, давайте поговорим об этом позже, так как, скорее всего, многие из Вас это делают впервые.
Второе - организовать отдельную папку для установки EhLib. Например: C:\Delphi\EhLib, но я бы рекомендовал “запрятать это дело подальше”: C:\Program Files\Borland\BDS\4.0\lib\EHLib - вот так. Адрес этой папки нужно запомнить, он еще понадобится.
Скопировать все файлы из папки Common в новую папку C:\Program Files\Borland\BDS\4.0\lib\EHLib.
Скопировать все файлы из папки Delphi9.Vcl (или другой аналогичной) в новую папку C:\Program Files\Borland\BDS\4.0\lib\EHLib.

Далее нужно открыть среду разработки и загрузить проект DclEhLib90.dpk (порядковый номер может отличаться от указанного здесь, это зависит от Вашего выбора на предыдущем шаге).
Далее в окне Управления проектом (Project Manager) щелкните по заголовку проекта правой кнопкой и выберите в контекстном меню пункт “Install”.

Если Вы все сделали правильно, Вы получите сообщение, что проект “has been installed” - установлен.
Проверьте установку ,выполнив меню Component - Install Packages:


ВЫЖНО: После того, как Вы закроете предыдущие окна кнопками “ОК”, нажмите на пиктограммку с изображением дискет, чтобы сохранить изменения и выполните пункт “File - Close All”.
Проверьте, чтобы путь к библиотеке EhLib был указан в настройках среды разработки, для чего выполните меню Tools - Options:






Выберите раздел, указанный на рисунке и нажмите кнопку с тремя точками. Если путь по каким либо причинам не добавился автоматически, то добавьте его (в данном случае это будет путь  C:\Program Files\Borland\BDS\4.0\lib\EHLib).
Теперь среда разработки Delphi готова предоставить Вам все прелести установленных компонентов библиотеки EhLib.
Хотите в этом убедиться?
Добро пожаловать на следующие уроки.
Наглядный видео урок Вы можете посмотреть или скачать, пройдя по ссылке.
Задать вопросы Вы можете, выбрав удобный способ на странице Обратная связь.
Подведем итог:
в этом уроке Вы научились
  • Устанавливать компоненты сторонних разработчиков
Что же дальше?
- размещение новых компонентов на форме и настройка их,
- знакомство с компонентом TTimer,
- ответ на вопрос: зачем в программе MyTimer нужны два компонента TTimer?

четверг, 14 апреля 2011 г.

Урок 4 . Список действий и элементы управления формы (компонент TActionList)



Привет.
С Вами Веселов Александр.
Один из моих учителей, а было у меня их за всю жизнь не то, чтобы много, но каждый - личность, использовал такую практику: новичка он сталкивал в пропасть "нового, незнакомого, не найденного", а сам какое-то время наблюдал. Выберется тот, сможет научиться и разобраться - будет хороший специалист, профессионал. Ну, а не поднимется, увы...
Мы с Вами, мой дорогой читатель, только начинаем свой нелегкий путь. Смелее вперед!
Список необходимых нам действий является прямым следствием технического задания и алгоритма, которые мы обсуждали на предыдущем уроке:
  • Вывести окно «О программе»,
  • Настроить быстрые кнопки,
  • Выбрать звуковой файл,
  • Запустить таймер,
  • Остановить таймер,
  • Увеличить количество минут,
  • Уменьшить количество минут,
  • Увеличить количество секунд,
  • Уменьшить количество секунд.
Поэтому, первое, что необходимо сделать - разместить в любом месте на форме компонент TActionList (список действий), перетащив его с вкладки "Стандартные" "Tool Palette" (Панели компонентов). Если кому-то стало 
дурно
 сложно, посмотрите видео урок по этой теме - там наглядно и просто показано, как это сделать.  Чтобы начать наполнять список действий, щелкните по нему дважды мышкой.



ActionList AND MainMenu
Как видно из рисунка, я положил на форму еще ряд компонентов - элементов управления (Controls): надписи (Label), различные кнопки (Button)и статус бар внизу (StatusBar). Подробно, как это сделать, смотрите в одноименном видео уроке.
Добавьте в ActionList действия в соответствии с рисунком и алгоритмом работы программы, распределив действия по категориям. Подробно, как это сделать, смотрите в одноименном видео уроке.




жмите на кнопку добавления нового действия (New Action), а затем в Инспекторе объектов заполните свойства, как показано на рисунке выше.
Затем в Инспекторе  объектов переключитесь на вкладку событий (Events) и дважды щелкните на событии onExecute.



В модуль программы будет сгенерирована заготовка для записи кода, реализующего нажатие кнопки.
Сделайте заготовки кода под каждый Action. Пусть пока это будет вывод на экран простого уникального сообщения, чтобы убедиться в рабоспособности нашей конструкции.
На следующем шаге необходимо связать набор действий с элементами управления формы. Здесь необходимо сделать небольшое отступление. Зачем вообще нужен этот компонент "ActionList", что в нем пользы, если можно под каждую кнопку написать кусочек программы, чтобы кнопка выполняла необходимые нам действия? Обращаю Ваше внимание, что практически в любой программе одинаковые действия выполняются при кликании на различных элементах управления: пунктах меню, кнопках и т.п. Чтобы избавиться от повторного написания (или копирования) частей программы и необходим этот замечательный компонент. К тому же, если повторяющиеся фрагменты программы довольно объемны, то такая организация программы (с использованием ActionList) существенно снизит объем конечного исполняемого файла.
Чтобы связать элемент управления формы (пункт меню или кнопку) с определенным действием, перейдите на вкладку визуального конструктора (Design), выберите элемент управления, а затем в Инспекторе объектов, на вкладке Events выберите необходимое действие Action, как показано на двух следующих рисунках для одного из пунктов меню и кнопки "Старт":







Обращаю Ваше внимание, что подписи пунктов меню и кнопок изменились, и приняли значения, указанные в назначенном им действии (Action). И еще: чтобы при наведении на элемент управления мышки, показывалась всплывающая подсказка (Hint), свойство Show Hint (показывать подсказку) должно быть установлено в True (Истина).
Скомпилируйте проект. Если Вы не наделали ошибок, и не потеряли ни одного символа разделения операторов - точки с запятой, то на экране появится окно программы. Выбрав пункт меню "Действия - Старт", нажав быструю клавишу F5, или нажав просто кнопку "Старт", Вы получите отклик программы на свое действие, т.е. сообщение:

"Старт таймера"


Наглядный видео урок Вы можете посмотреть или скачать, пройдя по ссылке.
Подведем итог:
на этом уроке Вы научились
  • Располагать на форме различные элементы управления (Controls),
  • Работать со списком действий (ActionList),
  • Создавать действия (Actions), распределяя их по категориям,
  • Назначать действия элементам управления


Что же дальше?
На следующем уроке я предлагаю не на долго оставить нашу разработку.
Дело в том, что, несмотря на обилие поставляемых вместе со средой разработки различных компонентов, не всегда в их числе находится нужный, обладающий всеми необходимыми свойствами.
Есть три пути решения таких вопросов:
1. Внести изменения в поставляемый вместе с оболочкой Delphi компонент
2. Разработать свой компонент с необходимыми свойствами.
3. Купить или найти бесплатный компонент стороннего разработчика.
Первые два пути предполагают наличие довольно глубоких знаний и достаточный лимит времени. Не буду отвергать их. В процессе наших уроков я расскажу, как это сделать, т.е. мы поучимся изменять существующие компоненты и разрабатывать свои собственные.
А на следующем уроке я предполагаю поговорить о процессе установки в среду разработки Delphi компонентов сторонних производителей.
До встречи.

Урок 3. О ТЗ и алгоритме


Мне пришло в голову, что многие из Вас, знакомясь со вторым уроком, могли задаться вопросом: «О чем, собственно, речь, о каком программном продукте говорит автор?» Я как- то так вскользь упомянул, что в продолжении нескольких следующих уроков буду рассказывать о разработке программы бытового таймера, не сказав ничего более конкретного. Так вот, уважаемый читатель, любая программа, которую Вы будете создавать не для собственных нужд, должна быть описана в документе, называемом «Техническое задание». Такой документ обязательно нужно получить от заказчика, иначе Вы рискуете попасть в ситуацию, когда заказчик откажется оплатить Ваш труд, сославшись на то, что Вы написали совсем не то, о чем он Вас просил (все ж — живые люди: ну, забыл, устал, не с той ноги встал и вообще: «Я вам этого не говорил» - любимая фраза заказчиков...).
Не хотелось бы пугать тех, кто еще не сталкивался с заказчиками, но «предупрежден — значит вооружен». Я хочу предупредить моего читателя, что общение с заказчиком — дело очень непростое. Заказчика нужно уметь слушать, слышать и понимать, проявляя максимум выдержки и терпения.

Ну, достаточно, перейдем к делу, не претендуя на абсолютную полноту изложения данного непростого вопроса, просто, чтобы показать в первом приближении, как это может выглядеть.
Техническое задание на создание программы «Бытовой таймер»
Назначение программы: программа предназначена для выполнения обратного отсчета времени от значения, задаваемого оператором.
Требования к программе:
  • Программа «Бытовой таймер» (рабочее название MyTimer) должна быть сформирована в виде законченного запускаемого модуля.
Примечание. Не претендуя на полноту, я постараюсь дать понять, какие моменты нельзя упустить. Например, в данном пункте дается подрядчику «вольная» на выбор среды разработки, одновременно с исключением:
а) транслируемых языков, требующих запуска некоей оболочки для работы программы
(к таким относится, например, Basic)

б) языка Java, требующего установки и запуска ява-машины для работы готовой программы.
  • Обратный отсчет времени должен начинаться с установленного стартового значения. Оператору должна быть предоставлена возможность  устанавливать стартовое значение вручную или выбирать из нескольких заранее заданных значений.
Примечание: требование иметь возможность выбирать  стартовое значение из набора заранее заданных говорит о необходимости хранить эти значения. Вряд ли есть необходимость применять базу данных, так как количество этих значений конечно. Можно использовать для их хранения текстовый файл.
  • После окончания обратного отсчета программа должна подавать звуковой сигнал.
  • Оператор должен иметь возможность прервать подачу звукового сигнала в любой момент.
  • Программа должна иметь простой, интуитивно понятный  дружественный интерфейс.
Так или примерно так может выглядеть (в самых общих чертах)  ТЗ на программу, выполняющую функции бытового таймера. Лучше, конечно, обсудить с заказчиком варианты интерфейса, нарисованные предварительно на бумаге, но... Это - если получится.
В прошлом уроке мы начали создавать главное меню программы, однако, есть еще один момент, без которого нельзя приступать к написанию ни одной программы. Я предлагаю коротко обсудить алгоритм работы будущей программы. Дело в том, что не имея точного алгоритма в голове, а лучше, конечно, на бумаге, Вы рискуете запутаться, наделать ошибок, багов, написать лишнего. Ничто не отнимает так много времени у программиста, как поиск алгоритмической ошибки, поверьте моему опыту. Проще и быстрее написать заново, чем разбираться с плохо написанным кодом, выискивать ошибки.





Первое, что должна сделать программа — обратиться к некоему хранилищу за всеми необходимыми данными для своей работы и считать их из этого хранилища, разместив в массивах и переменных при   необходимости.
Забегая вперед, скажу, что в качестве хранилища настроек программы я выбрал не обычный текстовый файл, а файл типа «ini». В отличии от простого текстового файла, файлы данного типа имеют определенную структуру  и более пригодны на мой взгляд для хранения подобных данных. Меня могут спросить, почему бы эти данные не разместить в реестре Windows?  Ничего нет плохого, если все необходимые данные для работы своей программы Вы разместите в реестре операционной системы. Но в этом случае, Вам придется позаботиться о написании деинсталлятора программы, чтобы в случае удаления программы из компьютера, в реестре не осталось ненужных записей. К сожалению, многие программисты забывают об этом или относятся к работе с реестром не с должным вниманием, что приводит... в общем, к нехорошему это приводит... Урок мой не об этом, и в данной серии уроков я не ставлю себе целью описывать работу с реестром операционной системы.
Примем во внимание, что наша программа не будет требовать инсталляции.

Далее, программа должна визуализировать полученные настройки, и вывести на экран главное меню.
В результате, получились три ветви алгоритма: А, В и С. (Ветвь «Файл-Выход» не стоит принимать во внимание в силу ее простоты: она приводит к завершению работы программы).
Двинемся от простого к сложному.
Ветвь «С» должна выводить окно «О программе».
Ветвь «В» - давать возможность настраивать быстрые кнопки (их предполагается 6 штук, каждая из которых может иметь свои отличные настройки) и выбирать исполняемый таймером в качестве звукового сигнала файл.
Наконец, ветвь «А».
В порядке эргономической важности:
  • запуск таймера,
  • остановка таймера,
  • Увеличение количества минут
  • Уменьшение количества минут
  • Увеличение количества секунд
  • Уменьшение количества секунд


вторник, 5 апреля 2011 г.

Урок 2. Оформление проекта или то, до чего руки не доходят… (создание иконки приложения ico в AWicons)



На компьютерной заре достаточно было написать программу, главное - чтобы она работала, решала поставленные задачи. С тех пор прошли не года - века....
Пользователь стал искушенным и капризным. Ему хочется красоты, удобства, изюминки....В эпоху потребления едва  ли не основным становится не суть, а упаковка.
И плох тот программист, который отстал от этой реальности и не заботится хотя бы немного об оформлении своей программы.
Завершенность в оформлении - это еще и  самоуважение (мол, не хуже, чем у других).
Поэтому я решил поговорить о подготовке иконки, которая должна будет заменить стандартную иконку Delphi, вот такую:





Для этого существует множество различных программ. Я остановил свой выбор на AWicons.  Триал-версия, которой, доступна на сайте производителя: http://www.awicons.com/icon-editor/
После загрузки, установки и запуска AWicons, окно программы выглядит, как показано на следующем рисунке:


Окно редактора иконок
с той лишь разницей, что при помощи нехитрых манипуляций я создал на рабочем поле вот такую иконку (подробнее, как это сделать с помощью данной программы смотрите в соответствующем видео уроке).
После выполнения пункта меню “Файл - Сохранить объект”, нужно выбрать каталог с Вашим проектом и дать файлу с расширением *.ico осмысленное имя.
Теперь можно заняться установкой иконки в проект.
В качестве примера, в последующих нескольких уроках я буду рассказывать о проекте MyTimer. Это проект, в рамках которого создается программный бытовой таймер. Очень полезная штуковина для тех, у кого не выключается ноутбук: чтобы яйца сварить всмятку, пельмени чтоб не выкипели, передачу любимую через 15 минут чтоб не пропустить и т.п.
Для этого откройте среду разработки Delphi, создайте новый проект и зайдите в настройки проекта. Затем в колонке слева укажите Application.




Окно настроек проекта
В поле “Title” введите название Вашего приложения.
О файлах справочной системы мы обязательно поговорим, но несколько позже, когда будем знакомиться с полноценным приложением “Rashod.exe”. Оставьте поле “Help file” на данном этапе пустым.
Для установки иконки приложения нажмите кнопку “Load Icon”, выберите подготовленный Вами файл *.ico и загрузите его.
Прежде, чем нажимать кнопку “ОК”, я бы посоветовал Вам выбрать в колонке слева пункт “Version Info” (информация о версии программы).


Окно настроек проекта
Отметьте галочками “Include...” и “Auto-inc...”. Первая отметка нужна для включения информации о версии в Ваш проект, вторая - для автоматического увеличения на единицу счетчика после выполнения команды “Build project”. Эти данные нам понадобятся, когда мы будем говорить о создании формы, а затем и компонента “О программе”.
Далее, определите в свойствах формы подпись, позицию и другие необходимые свойства (подробности см. видео урок).
Положите на форму компонент TMainMenu и, дважды щелкнув по нему, составьте меню, как показано на рисунке
Подробно о том, как это сделать, смотрите соответствующий видео урок.
(Я вычеркнул сочетания клавиш, поскольку о них мы поговорим позже.)