Отправляет email-рассылки с помощью сервиса Sendsay

Программирование на Delphi

  Все выпуски  

Программирование на Delphi (выпуск 72)


Программирование на DELPHI
Выпуск #72 (29 июня 2007 г.)

Разделы сайта:

Delphi.int.ru

Новости сайта
Регистрация »
Файловый архив
Статьи
Компоненты
Plug-in's
Документация
Исходники
Изображения
Игры
Программы
Рассылки сайта
Дружеств. сайты

IRC-канал сайта:

Сервер: irc.tic-tac.ru
(либо irc.dalnet.ru)
Порт: 6667
Канал: #delphiintru

Ждём Вас на нашем канале!

Доброго времени суток, уважаемые читатели!

На сайте практических никаких изменений (кроме появления новых файлов и статей), однако немного о планах:

∙ Разработка новой версии Delphi.int.ru Expert идёт довольно активно и очень скоро эта версия будет запущена.
∙ На основном сайте планируется полное обновление системы комментариев к файлам и статьям.
∙ Многие операции на сайте планируется реализовать с помощью технологии AJAX (выполнять операции станет возможно без полной перезагрузки страницы).
∙ Планируется добавление раздела "Юмор" на сайт.

Также не лишним будет напомнить, что работает IRC-канал сайта. На канале Вы сможете пообщаться с другими участниками (ведь форума на сайте в данный момент нет). Данные для подключения см. в блоке слева под ссылками на разделы сайта.

Если Вы ещё не зарегистрированы на www.delphi.int.ru, не стоит откладывать это на потом. Регистрация »

Приятного чтения и до скорой встречи!

Статистика Delphi.int.ru Expert на 29.06.2007, 12:00 (предыдущий подсчёт - 19.06.2007, 17:00):

Зарегистрированных экспертов: 90 (+1), из них в активном режиме 59 (+1).
Участниками задано вопросов: 676 (+35).
Всего отправлено ответов: 1107 (+52).
Всего сообщений на форумах вопросов: 1032 (+86).
Максимальное число разосланных в день писем (за июнь '07): 544 (18.06.2007).
Максимальное число разосланных в день писем (за всю историю): 608 (24.04.2007, +0).

Разделы рассылки:

» Авторское слово
» Обучение Delphi
» Delphi.int.ru Expert
» Статья по Delphi
» Файловый архив
» Юмор

Delphi.int.ru Expert - решите свою проблему, а также помогайте другим, став экспертом!

Количество читателей рассылки (29.06.2007, 12:00):
5482+1242+379= 7103 (+29)

Связь по e-mail:

admin@delphi.int.ru
expert@delphi.int.ru
info@delphi.int.ru

Если Вы хотите где-нибудь разместить материалы, представленные на www.delphi.int.ru или в данной рассылке, свяжитесь, пожалуйста, с автором или администратором.
Обучение Delphi

» Найти все предыдущие уроки можно на www.delphi.int.ru в разделе "Статьи".
Последние 3 урока:

8. Pascal - первое знакомство
9. Pascal - базовые конструкции и переменные
10. Логические выражения

События

Автор:
Ерёмин Андрей
Стоит стюардессе разнести пассажирам кофе, как самолет начинает вибрировать...
Номер урока:
11
 

События в программировании, как и события реального мира - это какие-либо операции, происходящие в установленное время. Установленное время - это не конкретное время с точки зрения часов, это просто отклики на какие-то другие действия и изменения. События присущи объектно-ориентированному программированию и являются одной из важных черт операционной системы Windows. Работа программ с визуальным (графическим) интерфейсом немыслима без событий. Delphi предоставляет полный доступ для работы с событиями и немного упрощает программирование обработчиков событий. Целью урока является знакомство с наиболее часто используемыми событиями, а также с приёмами написания обработчиков для них.

Где найти события?

В одном из первых уроков было упомянуто, что каждый объект имеет свойства и события и всё это доступно через Object Inspector. Список всех событий, которые поддерживает объект, находится на вкладке Events Инспектора Объектов. Формат данных аналогичен закладке со свойствами: слева указывается название события, а справа - обработчик, который присвоен событию. Обратите внимание, что всем событиям обычно даются названия, начинающиеся со слова "On" (англ. - "на"). Это хороший тон и довольно устоявшаяся традиция. Такие названия позволяют быстро отличить события от свойств. По аналогии со свойствами, событиям дают вполне логичные имена. Увидев незнакомое событие, в 95% случаев только по названию можно догадаться, когда событие происходит. Если же событие не совсем понятно, либо хочется больше узнать о нём, можно воспользоваться встроенной справочной системой Delphi. Для этого нужно установить курсор на строку с интересующим событием и про сто нажать F1 - справочная система откроется на странице с информацией о выбранном событии (если, конечно, оно описано в справке). Для всех стандартных компонент в справочной системе информации предостаточно. Если используется какой-либо сторонний компонент, то описание следует искать в документации, которая идёт вместо с самим компонентом. Некоторые компоненты (в основном - крупные пакеты из большого числа компонент) самостоятельно интегрируют свою документацию в справочную систему Delphi при установке.

Автоматическое создание обработчиков событий

Обработчик события - это набор команд, которые выполняются при вызове события. Создавать обработчики можно двумя способами: прямо в среде Delphi - автоматически, и программным путём, т.е. во время выполнения программы. Создать обработчик очень просто: достаточно дважды щёлкнуть по полю рядом с названием события в Инспекторе Объектов и откроется редактор кода с заготовкой обработчика. Остаётся лишь написать требуемый код между begin и end (курсор уже будет стоять в том месте) и обработчик готов. Как видите, всё довольно просто и быстро. Однако в предыдущих уроках Вы видели, что обработчик создавался и просто при двойном щелчке по объекту на форме... Да, действительно, в этом случае тоже создаётся обработчик. Но этот способ ничем не отличается от только что описанного, просто для каждого объекта задано событие по умолчанию, для которого создаётся обработчик при двойном щелчке. Как правило, это самые используемые события. Например, для кнопки это конечно же б удет щелчок по ней. Для нестандартных компонент, если событие по умолчанию не обозначено, берётся первое попавшееся из всех, а если событие всего одно, то выбор тем более очевиден.
После того, как обработчик создан, на вкладке Events рядом с названием события появится название обработчика для него. Это название также можно вписать и вручную или выбрать из списка, в котором содержатся названия всех обработчиков. Имена обработчикам даются также не случайно: берётся имя объекта и к нему дописывается название события. Например, если есть кнопка Button1 и её событие OnClick, то обработчик получит название Button1Click. Опять-таки, по имени обработчика можно догадаться о событии, к которому он относится.

Событие может иметь только один обработчик! Тем не менее, если требуется задать несколько обработчиков, можно сделать следующим образом: единственный указанный обработчик просто программно запускает другие обработчики. Такой приём часто используется.
Однако, обратного запрета не существует: один обработчик может быть привязан к разным событиям объекта и даже к разным объектам. Для этого нужно в строке интересующего события у объекта выбрать имя обработчика из списка.

Обработчик с точки зрения программного кода

Обработчик в программном коде

Теперь посмотрим, что из себя представляет обработчик в программном коде. А представляет он из себя процедуру, т.е. набор команд и является мини-программой.
Обработчик содержит раздел реализации - он расположен между begin и end (на рисунке выделен рамкой цвета    ). В этом блоке, как Вы уже знаете, следует писать код, который и будет выполнен.
Самая верхняя строка обработчика - это его заголовок (выделен цветом    ). Элементы заголовка:
- Ключевое слово procedure (процедура);
- Имя объекта, которому принадлежит данная процедура (в данном случае она принадлежит форме - поэтому TForm1);
- Имя обработчика (цвет    );
- Переданные параметры (цвет    ).

Между именем объектам (TForm1) и именем обработчика (Button1Click) находится точка - это символ указания на то, что Button1Click принадлежит TForm1. При работе с любыми структурами точка указывает на принадлежность элемента этой структуре. Сейчас это не играет большой роли - просто небольшое отступление. К примеру, в языке C++ таким разделителем служит комбинация "минус и знак больше": ->

Раздел описаний здесь тоже присутствует, просто он является пустым. Как и положено, расположен он между заголовком обработчика и разделом реализации, т.е. между первой и второй строкой. При необходимости объявления переменных или констант этот раздел описывается обычным образом - добавление ключевого слово var или const и описанием переменных или констант.

 
События в Object Inspector (для TButton)

Создан обработчик события OnClick для Button1

Выбор обработчика события из списка всех созданных обработчиков

Пример обработки событий №1

Результат работы Первый пример будет простым, но будет рассмотрен один приём создания обработчиков.
Наша цель: на форме будет 3 кнопки и по нажатию на каждую из них должно появляться сообщение о том, какая кнопка нажата.
Первый способ: для каждой кнопки создаём обработчик OnClick и пишем код для вывода сообщения (ShowMessage('текст') - выводит окошко с кнопкой ОК и указанным текстом):

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage('Нажата Button1')
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ShowMessage('Нажата Button2')
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  ShowMessage('Нажата Button3')
end;

Конечно, работать будет... Но настоящие программисты так не делают... Судите сами: а если бы было 100 кнопок - что тогда? 100 обработчиков? Конечно нет!

Можно создать один обработчик сразу для всех кнопок. Выше было сказано, что это можно сделать, если выбрать в Инкспекторе Объектов обработчик события из списка... Но в случае, если 100 кнопок, такой способ тоже непригоден - уйдёт много времени. Есть ещё один: если выбрать на форме сразу несколько объектов, то в Инспекторе Объектов среди свойств и событий останутся только те, которые есть у всех выбранных объектов. Этим и следует воспользоваться.

Итак, выбираем на форме все 3 кнопки (очерчивая область мышью, либо удерживая Shift), далее переходим на вкладку Events в ИО и создаём обработчик события OnClick. Что происходит: открывается редактор кода, но создаётся только один обработчик, хотя он присваивается всем трём кнопкам.

Вывод сообщения также реализуется одной строкой, в которую подставляется имя кнопки, которая была нажата.

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage('Нажата '+(Sender as TButton).Name)
end;

Как именно это работает и что делает оператор as сейчас объяснить довольно сложно. Всему своё время. Пример создан с целью показать, что дублирования всегда можно каким-то способом избежать.

Параметры, передаваемые обработчикам

У событий есть параметры. У многих событий параметр один, но у некоторых их бывает и больше - зависит от типа события. Из переданных параметров можно узнать дополнительные данные и условия, при которых произошло событие. Например, если мы знаем, что пользователь передвинул курсор мыши, это ещё ни о чём не говорит и полезной информации практически не несёт. А вот если мы знаем, что курсор был передвинут в точку экрана с некоторыми известными координатами (x;y) - это уже что-то.
Параметр, который встречается практически во всех событиях - Sender. Он указывает на объект, который данное событие инициировал. Использовать его удобно в случае с несколькими объектами, у которых установлен один обработчик одного и того же события (как в нашем примере №1).

События

Вот теперь, когда мы достаточно много знаем о событиях, можно наконец рассмотреть стандартные и наиболее часто используемые из них.

OnClick - щелчок мышью по объекту. У кнопки событие также срабатывает, если нажать Enter или Пробел в тот момент, когда фокус ввода находится на кнопке.

OnDblClick - двойной щелчок мышью.

OnContextPopup - при вызове контекстного меню объекта, т.е. при щелчке правой кнопкой мыши. Среди параметров есть MousePos - координаты курсора в момент щелчка. Координата по X доступна как MousePos.X, а по Y - как MousePos.Y.

OnEnter - момент, когда объект получает фокус ввода (фокус ввода обычно изображается пунктирной рамкой на объекте; в поле ввода - это курсор; фокус один на всё приложение, т.е. работать одновременно можно лишь с одним объектом).

OnExit - момент, когда объект теряет фокус ввода.

OnMouseDown - при нажатии кнопки мыши (не обязательно левой). Параметр Button - нажатая кнопка (mbLeft - левая кнопка, mbRight - правая, mbMiddle - средняя). Shift - множество, указывающее, какие функциональные клавиши были зажаты при щелчке. Таким образом можно отслеживать, например, нажатия при зажатых Ctrl+Alt и т.п. X, Y - координаты курсора во время нажатия (относительно левого верхнего угла самого компонента, а не формы!).

OnMouseUp - событие, аналогичное OnMouseDown. Происходит при отпускании кнопки мыши. Пример комбинации этих двух событий - графический редактор: когда кнопка мыши нажата, происходит рисование, а когда отпущена - не происходит.

OnMouseMove - ещё одно событие мыши, происходящее при перемещении курсора над объектом. X, Y - координаты нового положения, Shift - множество нажатых функциональных клавиш.

OnKeyDown - при нажатии какой-либо клавиши клавиатуры в тот момент, когда фокус ввода находится на объекте. Key - код нажатой клавиши, Shift - всё то же множество функциональных клавиш (этот параметр встречается во многих событиях).

OnKeyUp - при отпускании клавиши (антипод OnKeyDown).

OnKeyPress - при нажатии клавиши, которая печатает какой-либо символ (буква, цифра, знак). Key - уже не код клавиши, а сам символ (тип данных: Char - один символ).

OnResize - при изменении размеров объекта.

OnPaint - при отрисовке объекта на экране (например, формы).

У самой формы также есть множество событий. Отметим некоторые из них:

OnCreate - при создании формы. Обычно в обработчик этого события помещают действия, которые должны произойти при запуске программы. Но при запуске это выполнится только если форма является главной в приложении и при условии, что форма создаётся автоматически. Если в приложении одна форма - она и является главной.

OnClose - при закрытии формы.

OnCloseQuery - при попытке закрыть форму. Это событие можно использовать, если нужно заблокировать закрытие формы. В обработчике присутствует параметр CanClose (англ. - "можно закрыть"): логическое значение, тип данных - Boolean. Если после выполнения обработчика значение переменной CanClose окажется False, то закрытие формы произведено не будет. Значение этой переменной устанавливается программно. Пример использования этого события - текстовый редактор. Если пользователь ввёл текст, но не сохранил его в файл, при выходе из программы нужно спросить, следует ли сохранить изменения.

Пример обработки событий №2

Цель: запретить "прямое" закрытие формы, а спрашивать, действительно ли пользователь хочет закрыть программу. Используем событие формы OnCloseQuery. В обработчике выведем диалоговое окно и, если пользователь ответит "Нет", заблокируем закрывание. Для вывода окна диалога воспользуемся функцией MessageDlg. Подробнее о ней и о её параметрах Вы узнаете в одном из следующих уроков. Наш обработчик:

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  if MessageDlg('Вы действительно хотите выйти?',mtWarning,[mbYes,mbNo],0) = mrNo then
    CanClose:=False
end;

Проверяемое условие - нажата ли кнопка "Нет". Если она нажата, блокирум закрытие присвоением переменной CanClose значения False. В результате при закрытии увидим следующее:

Диалоговое окно при попытке закрыть программу
Диалоговое окно при попытке закрыть программу

События (продолжение)

OnDestroy - при уничтожении формы (после закрытия форма уничтожается и освобождается занятая ей память).

OnShow - при показе формы на экран.

OnHide - при скрытии формы с экрана.

OnActivate - момент, когда форма становится активной, т.е. когда ей передаётся фокус ввода (например, когда пользователь щёлкнул по форме).

OnDeactivate - соответственно, когда форма теряет фокус.

OnChange - при изменении чего-либо (например, у поля ввода TEdit это событие срабатывает, когда изменяется текст в этом поле).

OnDragDrop, OnDragOver, OnEndDock, OnEndDrag, OnStartDock, OnStartDrag - все эти события связаны с технологией Drag&Drop (т.е. когда объект "захватывается" мышью и переносится в другое место), а также с Dock-технологией. Суть этой (Dock) технологии во встраивании одних объектов в другие. Например, если взять Object Inspector за заголовок и переместить на нижнюю часть Object TreeView, а затем отпустить, то окна объединятся, а если переместить его в центр Object TreeView, то закладок станет 3 (Object TreeView станет третьей закладкой).

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

Заключение

Мы рассмотрели работу с событиями - одни из принципов объектно-ориентированного программирования. Таким образом, разработка визуальной программы для Windows сводится к написанию обработчиков на события, в которых описывается взаимодействие объектов друг с другом.

Оцените данный урок по пятибалльной шкале:
1 2 3 4 5
Комментарии и замечания приветствуются.

 

Delphi.int.ru Expert
(текущая версия системы: 1.68
последнее обновление: 08.05.2007)

Если Вы не являетесь зарегистрированным пользователем сайта, зарегистрируйтесь прямо сейчас! Регистрация »

Delphi.int.ru Expert - это автоматизированная система экспертной помощи, призванная помочь в решении проблем, возникающих как у начинающих, так и опытных программистов, а также способствующая обмену информации между участниками лично и публикации этой информации в массовых рассылках в дальнейшем. Система полностью автоматизирована и постоянно развивается и обновляется. Если у Вас есть какие-то либо вопросы или Вы столкнулись с какой-либо проблемой при программировании на Delphi/Pascal - задайте свой вопрос. Кроме того, Вы сами можете войти в состав экспертов и помогать другим.

Задать вопрос экспертам » | Справочное руководство » | Перейти в состав экспертов » | Эксперты »

В рассылку попадают вопросы вместе с ответами (каждый вопрос действителен в течение одной недели).

* Администраторы сайта за наличие грамматических ошибок в сообщениях ответственности не несут.

Delphi.int.ru Expert  – вопросы и ответы (#266 - #280)
Вопрос № 266

Текст вопроса:

Доброго вам здравия.
Вопрос такой:
Как мне получить разницу между полем даты таблицы БД и нынешней датой!
Принци такой необходимо чтобы оно высчитывало года (типа стаж работы). Когда пришел на работу - минус нынешняя и получение остатка.
Заранее благодарен!

Автор вопроса: BLOOD_OMEN (статус: Посетитель)
Дата и время отправки вопроса: 15.01.2007, 20:08
Получено ответов на вопрос: 1
Сообщений в форуме вопроса: 3
Страница данного вопроса >>


» Ответы на данный вопрос:

1. [Отвечает: Вадим К (статус: Высокий уровень), 15.01.2007, 20:31]:

Здравствуйте, BLOOD_OMEN!
Это дело можно решить двумя способами. Первый - вычисляемые поля. Можно в Table добавить новое поле и написать формулу, по которой его считать.
А можна, так как я делал в своё время. Через SQL запрос. Многие БД имеют функцию получения текущей даты/время и работы с ней. И их имена типа DATE, NOW (читаем доки). Теперь выбираем записи к примеру таким запросом
Select X,Y, (NOW-DT) from table
где X,Y - какие-то поля. DT - поле с датой. NOW - функция взятия текущей даты.
Такой способ наиболее правильный. Не думайте, что на клиенте вы быстрей сосчитаете! Сервера БД специально оптимизируют под это.

Оценка за ответ: 5.



Вопрос № 267

Текст вопроса:

Уважаемые эксперты. Мне необходимо вычислить строку вида: "5+3*sin(3*x-8*cos(y)/2)*5^2+8*cos(5)", соответсвенно подставив туда x и y.
Для вычисления я создал пару функций, первая создает дерево вычислений (см. в прилажении), второя подставляем необходимое значение аргумента. А вот как вычисть строку по готовому дереву не могу понять (запутался с указателями). В общем должен работать алгоритм: спуститься по всем ветвям вниз и начать вычисления к веришине, но как это реализовать?

Приложение:

Автор вопроса: SMaks (статус: Посетитель)
Дата и время отправки вопроса: 15.01.2007, 22:00
Получено ответов на вопрос: 2
Сообщений в форуме вопроса: 2
Страница данного вопроса >>


» Ответы на данный вопрос:

1. [Отвечает: Матвеев Игорь Владимирович (статус: Средний уровень), 16.01.2007, 08:49]:

Здравствуйте, SMaks!

Вычислять выражение нужно рекурсивно, так же как Вы заменяете x и y на числа в SetFormula().

Кроме того, было еще две ошибки:
1. Calculate() по умолчанию должна возвращать левый параметр, а не ноль, чтобы правильно обрабатывались скобки.
2. SetFormula(), параметр Formala должен быть объявлен как var-параметр, иначе Formala не изменится.

Все это в виде готового проекта: http://expert.delphi.int.ru/download_37.

Приложение:

Оценка за ответ: 5.
Комментарий: То что нужно, большое тебе спасибо!

2. [Отвечает: min@y™ (статус: Средний уровень), 16.01.2007, 10:24]:

Посмотри, как этот алгоритм реализован в RxLib (модуль Parsing.pas, класс TRxMathParser).
Замена х и у на значения - это совсем просто.

Оценка за ответ: 2.
Комментарий: Я спрашивал по конкретной задачи!



Вопрос № 268

Текст вопроса:

Господа Эксперты!
Как импортировать учётные записи Outlook Express?
Иными словами я хочу сказать как получить учётные записи Outlook Express (именно Outlook Express). Мне нужны следующие данные:
- сервера исход. сообщений
- сервер вход. сообщений
- Адрес Электронной почты
- Пароль

Автор вопроса: Len.A.R. (статус: Посетитель)
Дата и время отправки вопроса: 15.01.2007, 22:01
Получено ответов на вопрос: 0
Сообщений в форуме вопроса: 0
Страница данного вопроса >>


» Ответы на данный вопрос:

К сожалению, ответов на данный вопрос не поступило...



Вопрос № 269

Текст вопроса:

Здравствуйте, уважаемые! Решил поработать со списками. Подскажите как правильно освободить памать по завершении работы.

Автор вопроса: hdrus (статус: Посетитель)
Дата и время отправки вопроса: 16.01.2007, 06:39
Получено ответов на вопрос: 2
Сообщений в форуме вопроса: 5
Страница данного вопроса >>


» Ответы на данный вопрос:

1. [Отвечает: Матвеев Игорь Владимирович (статус: Средний уровень), 16.01.2007, 14:46]:

Здравствуйте, hdrus!

Списки TList, TStringList и т.д. поддерживают методы:

.Clear - очистка данных;
.Destroy - виртуальный деструктор от TObject, перегруженный для каждого конкретного класса - освобождает память, занятую объектом;
.Free - метод от TObject, вызывающий Destroy.

Обычно рекомендуют использовать Free, поскольку в нем есть проверка на nil, т.е. если объект не создан Free просто ничего не сделает, тогда как Destroy вызовет исключение.

2. [Отвечает: Вадим К (статус: Высокий уровень), 16.01.2007, 15:05]:

Какие именно списки вы использовали? Если TList, то незабывайте, что он не чистит память за вашими объектами. Тоесть вы должны сделать сами. Предыдущий эксперт об этом умолчал. Наиболее правильным считается такое удаление
Пусть TMyClass - это наш класс, экземпляры которого хранятся в списке. Тогда, если добавление выглядит так
m:TMyClass;
...
m:=TMyClass.Create;
List.Add(m);

то в конце зачищаем память так:
for i:=list.count-1 downto 0 do
begin
TMyClass(list).free;
list.delete(i);
end;
Почему сзаду наперёд? Количество элементов уменьшается, и когда вы перейдёте за середину списка, то будут удалятся уже не те элементы и будет большой Access Violation

Если же вы создали свои структуры и их организовали в виде связаных списков, то тут нужно смотреть, что именно вы создали. В одних случаях лучше сзаду начинать (с хвоста)



Вопрос № 270

Текст вопроса:

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

Автор вопроса: Сагынов Байсак Найсабекович (статус: Посетитель)
Дата и время отправки вопроса: 16.01.2007, 17:12
Получено ответов на вопрос: 2
Сообщений в форуме вопроса: 0
Страница данного вопроса >>


» Ответы на данный вопрос:

1. [Отвечает: Ласковый 3лоумышленник (статус: 3-ий класс), 16.01.2007, 18:38]:

Здравствуйте, Сагынов Байсак Найсабекович!
Из личного опыта могу присоветовать изучить MS Access, на мой взглять понять суть реляционный БД даст только Эксесс. Потом любая СУБД будет по зубам

2. [Отвечает: Вадим К (статус: Высокий уровень), 17.01.2007, 11:50]:

По поводу Access соглашусь с предыдущим экспертом - очень удобно. Но только не нужно через BDE.
А В общем вопрос насколько широк, что и сайта не хватит.
А Самое лучшее ищем книгу по делфи и смотрим что бы там был описан доступ через ADO



Вопрос № 271

Текст вопроса:

Нужно перенести вкладку компонентов QReport из пятой версии в седьмую. Это возможно?

Автор вопроса: Тамара (статус: Посетитель)
Дата и время отправки вопроса: 16.01.2007, 19:41
Получено ответов на вопрос: 3
Сообщений в форуме вопроса: 0
Страница данного вопроса >>


» Ответы на данный вопрос:

1. [Отвечает: Ласковый 3лоумышленник (статус: 3-ий класс), 16.01.2007, 19:55]:

Здравствуйте, Тамара!
У меня получилось так:
1. Запуск D7
2. Выбирай в меню Component|Install Packages...
3. Жмём кнопку Add...
4. В появившемя диалоговом окне нужно выбрать файл dclqrt70.bpl (а находится он в \Delphi 7\Bin - это по умолчанию в Program Files\Borland)
Вот и всё, вкладка появится

Оценка за ответ: 5.

2. [Отвечает: Матвеев Игорь Владимирович (статус: Средний уровень), 17.01.2007, 04:20]:

Здравствуйте, Тамара!

Все зависит от поставки Deplhi 5, знаю что в Enterprise нет исходных текстов QReport. Как известно DCU/BPL от одной версии Delphi не подходят к другой, поэтому их поставить не получится.

Пакет dclqrt70.bpl также поставляется не со всеми комплектациями и представляет собой те же самые QReport без исходников, компилированные на Delphi 7.

Оценка за ответ: 5.

3. [Отвечает: Вадим К (статус: Высокий уровень), 17.01.2007, 11:52]:

Но ещё лучше перейти на альтернативное средство, к примеру FastReport (можно FreeReport - чуть меньше функций, но бесплатно!) - вы будете поражены набором функций

Оценка за ответ: 5.



Вопрос № 272

Текст вопроса:

Доброе время суток, господа Эксперты. Я ярый сторонник Дельфи. я хочу научиться писать скрипты в Дельфи. У меня стоит винда ХРень. Как мне написать скрипт. На сайте у меня есть строка ввода и кнопка. По нажатию на кнопку я обращаюсь к скрипту и у меня должна перезагрузиться страница, только содержимое строки ввода должна быть внизу после всего.(типо гостивой книги). Скачавать готовые скрипты гостевой книги не хочу, хочу во всем разоброться. Я понимаю, что ни кто мне тут исходник не вылажет, тогда хотя бы ссылку дайте на литер-ру в инете, потому что в сети и так мало статей(в смысле скрипты на дельфи). Хорошию трудно найти. Заранее благодарен.

Автор вопроса: Geron (статус: 1-ый класс)
Дата и время отправки вопроса: 17.01.2007, 02:30
Получено ответов на вопрос: 1
Сообщений в форуме вопроса: 0
Страница данного вопроса >>


» Ответы на данный вопрос:

1. [Отвечает: Матвеев Игорь Владимирович (статус: Средний уровень), 17.01.2007, 05:01]:

Здравствуйте, Geron!

Я не буду писать Вам готовые исходники, потому что разбираться здесь нужно самому. Но расскажу основное.

Итак, во-первых никакой скрипт Вы на Delphi не непишите, это называется CGI-BIN приложения (CGI - Common Gateway Interface, BIN - потому что представляет собой бинарный код, а не какой-нибудь там скрипт).

CGI-BIN приложения, генерируемые Delphi, будут работать только на Windows платформе, под управлением IIS (WinNT), Personal Web Server (Win98), порта Apache под Windows или другим Windows Web сервером. Кроме того, BIN приложения, как Вы понимаете, обладают значительно большей "властью" над системой, чем PHP, Perl и др. web языки, поэтому полномочия таких приложений часто ограничиваются, вплоть до полного запрета их выполнения.

Delphi позволяет создавать несколько типов CGI-BIN приложений, от использования обычного консольного вывода (тапие приложения можно и в ассемблере писать), до ASP.NET (Delphi 2005).

Рассмотрим некоторые подробнее:

1. Обычный console-exe.
Обычное консольное приложение может выступать в качестве CGI-BIN, используя Write/WriteLn можно выводить в браузер любую информацию. Параметры командной строки можно парсинговать, получая POST данные запроса. Как получить GET смотите, например, здесь: www.delphiworld.narod.ru/base/cgi_apps.html.
Недостаток - при каждом запросе приложение загружается в память, выполняется, затем выгружается, что сильно замедляет работу сервера.

2. WebSnap Application.
Набор компонентов и классов для быстрого создания динамических web страниц. Ориентирован в основном на работу с базами данных. Выберите New\WebShap\WebSnap Application. Появится диалог выбора типа приложения. Как понятно из названий, ISAPI/NSAPI представляет собой Dll библиотеку, т.е. не загружается в память вновь при каждом обращении. CGI Stand-alone executable - то же самое, что console-exe, только Вы можете работать визуально и имеете множество вспомогательных классов и компонент под рукой. Apache Shared Moduleы - Dll, подключаемые как модули к Apache - работают побыстрее ISAPI/NSAPI, но сложнее отлаживать.

3. ASP.NET (Delphi 8/2005).
Технология Microsoft, позволяющая вести разработку Web приложений визуаально, т.е. вы располагаете контент страницы как компоненты на форме. Посмотрите например сайт Microsoft, он весь (или почти весь) написан на ASP.NET.

Оценка за ответ: 5.



Вопрос № 273

Текст вопроса:

Всем Привет!
Помогите сделать докачку в этом коде.
Спасибо

Приложение:

Автор вопроса: Vit2 (статус: Посетитель)
Дата и время отправки вопроса: 19.01.2007, 15:51
Получено ответов на вопрос: 1
Сообщений в форуме вопроса: 0
Страница данного вопроса >>


» Ответы на данный вопрос:

1. [Отвечает: Вадим К (статус: Высокий уровень), 19.01.2007, 16:24]:

Наиболее просто - сделать так, как в HTTP протоколе. А именно, на сервере добавляете возможност, что файл можно запрашивать не весь а часть и для этого его емя нужно задать в виде<имяфайла>?<с какого байта>-<по какой>
Клиент же запрашивает не весь файл, а по кускам. Правда прийдётся добавить комманду запроса размера файла.

Такая система будет совместима сверху вниз и наоборот. Тоесть старый сервер сможет обслуживать новых клиентов (просто не будет докачки) и наоборот

Оценка за ответ: 5.



Вопрос № 274

Текст вопроса:

Команда кнопке : Memo1.text:= 'Первое слово';
как сделать так чтобы нажав второй раз
высветилась другая фраза например:'второе слово',
нажав третий раз 'третье слово' и так далее.

Автор вопроса: Толков Геннадий Викторович (статус: Посетитель)
Дата и время отправки вопроса: 20.01.2007, 01:06
Получено ответов на вопрос: 2
Сообщений в форуме вопроса: 1
Страница данного вопроса >>


» Ответы на данный вопрос:

1. [Отвечает: Матвеев Игорь Владимирович (статус: Средний уровень), 20.01.2007, 03:46]:

Здравствуйте, Толков Геннадий Викторович!

Очень просто - ставите глобальную переменную счетчик, увеличиваете его каждый раз при вызове обработчика, и выводите текст в соответствии в значением этого счетчика.

Приложение:

Оценка за ответ: 5.

2. [Отвечает: Дима Гусаков (статус: 2-ой класс), 20.01.2007, 09:01]:

Здравствуйте, Толков Геннадий Викторович!

Приложение:

Оценка за ответ: 5.



Вопрос № 275

Текст вопроса:

Как сделать чтобы программа запускалась по паролю. Чтобы пароль задавался в коде программы (програмка исключительно для себя)

Автор вопроса: Pokemonchyk (статус: Посетитель)
Дата и время отправки вопроса: 20.01.2007, 22:08
Получено ответов на вопрос: 4
Сообщений в форуме вопроса: 10
Страница данного вопроса >>


» Ответы на данный вопрос:

1. [Отвечает: Сергей Устинов (статус: 2-ой класс), 20.01.2007, 22:36]:

Здравствуйте!

Самый простой вариант - в файл проекта перед строкой Application.CreateForm(TForm1, Form1); введите:
if InputBox('Внимание!','Введите пароль!','')<>'pass' then exit;

(не забудьте перед этим в Uses добавить модуль Dialogs).

Если же нужно будет пароль при вводе делать со звездочками - проще всего создать отдельную форму, которая будет грузиться первой. В нее Вы будете вводить пароль, если не правильный - закрываете приложение, если правильный - открываете нужную форму.

Удачи

Приложение:

Оценка за ответ: 5.

2. [Отвечает: Матвеев Игорь Владимирович (статус: Средний уровень), 21.01.2007, 03:07]:

Здравствуйте, Pokemonchyk!

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

Если интересно, могу поделиться рабочим кодом.

Есть еще очень простой и удобный вариант - воспользоваться PE Password Encryptor от SMT - эта малюсенькая программка подобно протектору шифрует часть кода в точке входа и вставляет туда загрушку в виде диалога ввода пароля. Если пароль введен верно - программа нормально запускается.

См. http://expert.delphi.int.ru/download_39.

Оценка за ответ: 4.

3. [Отвечает: Alex Van Glukhman (статус: 7-ой класс), 21.01.2007, 12:02]:

Добрый день!

Создаём отдельную форму для авторизации (см. код ниже)
При создании главной формы приложения на событие OnCreate пишем вызов формы авторизации

FPass:=TFPass.Create(Application);
try
if FPass.ShowModal=mrOk then ;
finally
FPass.Free;
FPass:=nil;
end;

Удачи

Приложение:

Оценка за ответ: 5.
Комментарий: Здравствуйте! Большое спасибо за ответ. Все работает {с даного примера я также понял что все компоненты лучше называть своими именами, а не Edit1,Edit2,...а потом сидеть и голову ламать где что :)} Если не трудно, то подскажите еще где надо покопаться чтобы звездочками показывало пароль (я думаю это как-то звязано с MaskEdit) Я конешно могу и монитор выключать на если доведется ввести пароль при посторонних, но все же... :)

4. [Отвечает: min@y™ (статус: Средний уровень), 22.01.2007, 08:20]:

Чтоб пароль показывало звёздами - поставь свойство Edit.PasswordChar := '*';.



Вопрос № 276

Текст вопроса:

Вопрос неординарный :)
Можно ли сделать такую прожку, чтобы при записи диска записывала на него .тхт-файл, где будут хранится номера всех поврежденных секторов DVD-диска(или как-то еще пометить эти сектора)?
Потом похожая программа оценит этот файл и не будет считывать с этих секторов информацию
(и не будет показывать ошибок).
Таким образом РВ-диски можно будет использовать много раз, и можно быть уверенным что информация не будет "записываться" на поврежденные сектора.

Приложение:

Автор вопроса: Pokemonchyk (статус: Посетитель)
Дата и время отправки вопроса: 21.01.2007, 01:02
Получено ответов на вопрос: 3
Сообщений в форуме вопроса: 2
Страница данного вопроса >>


» Ответы на данный вопрос:

1. [Отвечает: Сергей Устинов (статус: 2-ой класс), 21.01.2007, 01:20]:

Здравствуйте!

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

Вот только один момент: а есть ли в этом смысл?
Смотрите: Вам нужно получить физический доступ к ДВД диску - считать посекторно, создать модуль записи на ДВД (при этом я думаю будет какая - то разница для разных видов ДВД, разных видов болванок и т.д. не зря же, например за NERO Burning Rom денежки берут...) ну и еще куча всяких запарок...
Может проще новую болванку купить? :)

Удачи!

Оценка за ответ: 5.
Комментарий: Значит все-таки возможно... :)

2. [Отвечает: Матвеев Игорь Владимирович (статус: Средний уровень), 21.01.2007, 03:44]:

Здравствуйте, Pokemonchyk!

Вопрос действительно "неординарный"...

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

Кстити, если кому нужна запись CD/DVD - есть пакет Magic CD DVD Burner - http://www.binarymagics.com, правда платный.

Оценка за ответ: 5.

3. [Отвечает: Бубырь Александр Николаевич (статус: 4-ый класс), 22.01.2007, 08:55]:

Несколько месяцев назад в одной из рассылок (сейчас уже не помню в какой) приводился даже исходник. Идея в следующем: создается файл контейнер, в который пишутся данные и кодируются с избыточным кодом (наподибие Raid), в случае повреждения данных в одном месте, они берутся из другого.
Минусы: полезная емкость диска уменьшается (хотя надежность важнее), доступ к файлам контейнера только через оболочку, нет 100% гарантии целостности данных (зависит от степени избыточности кодирования и количества ошибок на диске).
Плюсы: на ДВД не так уж много ошибок (обычно)(поэтому даже при появлении новых ошибок, появившихся уже после записи, большая вероятность что данные уцелеют).
Так что советую поискать в инете (извиняюсь за плохую память, но сама идея надеюсь поможет).



Вопрос № 277

Текст вопроса:

Здравствуйте!
А можно ли с помощью Delphi написать свой ToolBar для Internet Explorer и для других интернет-браузеров?

Может есть какие-нибудь статьи по данной тематике, или кто-то может помочь?

В инете искал, ничего не нашел!

За ранее большое спасибо за ответ!

Автор вопроса: Евгений В (статус: 1-ый класс)
Дата и время отправки вопроса: 21.01.2007, 21:33
Получено ответов на вопрос: 2
Сообщений в форуме вопроса: 2
Страница данного вопроса >>


» Ответы на данный вопрос:

1. [Отвечает: Вадим К (статус: Высокий уровень), 21.01.2007, 22:25]:

Конечно можно!
Вот здесь можно почитать как добавить кнопку в IE http://www.delphiworld.narod.ru/base/own_ie_button.html
С панельками - посмотрите готовые решения на http://www.torry.net/quicksearchd.php?String=Internet+Explorer+ToolBar&Title=No
Там есть готовые библиотеки. Половина с них триальная, но разве это большая пробелема?

С Opera будет посложней. Там тоже можно добавить кнопку, но вот с панельками - даже не знаю.

Наиболее легко с FireFox - идете на их сайт - там всё подробно написано, только Делфи тут уже мало поможет - там на java пишеться.

Оценка за ответ: 5.

2. [Отвечает: min@y™ (статус: Средний уровень), 22.01.2007, 08:25]:

Набрал в гугле "toolbar для IE на delphi" - куча ссылок.

Оценка за ответ: 3.



Вопрос № 278

Текст вопроса:

Здравствуйте.
Как можно определить количество заполненных строк компонента StringGrid1?
Сколько разрядов в стандартной записи вещественного числа? И ещё назовите, пожалуйста, стандартную функцию с ее параметрами для преобразования вещественного числа в строку с указанием формата записи числа.
С уважением, Сергей Анатольевич.

Автор вопроса: Полушин Сергей Анатольевич (статус: Посетитель)
Дата и время отправки вопроса: 21.01.2007, 21:56
Получено ответов на вопрос: 2
Сообщений в форуме вопроса: 0
Страница данного вопроса >>


» Ответы на данный вопрос:

1. [Отвечает: Вадим К (статус: Высокий уровень), 21.01.2007, 22:42]:

>>Как можно определить количество заполненных строк компонента StringGrid1?
А что же сложного? Для начала определимся, что такое "заполненая строка"
для этого напишем функцию
function LineFull(sg:TStringGrid,l:integer):boolean;
var i:integer;
begin
result:=false;
for i:=0 to sg.ColCount-1 do
if Trim(sg.Cells[i,l])='' then exit;
result:=true;
end;
Я предположил, что заполненая строка не должна содержать незаполненых строк. ячейки с одними пробелами считаются пустыми.
Теперь фунцция, которая считает количество заполненых строк.
functio CountFullLine(sg:TStringGrid):integer;
var i:integer;
begin
result:=0;
for i:=0 to sg.RowCount-1 do
if LineFull(sg,i) then inc(result);
end;
Вызываем так count:=CountFullLine(StringGrid1);
------------
>>Сколько разрядов в стандартной записи вещественного числа?
Всё зависит от типа переменной: Single(около 7), Extendet(18),Double(15). Но ответить точно на этот вопрос нельзя. Нельзя в десятичной системе счисления, но можно в двоичной. Достаточно посмотреть в хелпе, скоко розрядов отводиться под мантису. Просто поищите в хелпе по словам Real Double. Там всё есть!
----------------
>>И ещё назовите, пожалуйста, стандартную функцию с ее параметрами для преобразования вещественного числа в строку с указанием формата записи числа.
Как не странно, это
function FloatToStrF(Value: Extended; Format: TFloatFormat; Precision: Integer; Digits: Integer): string; overload;
первый параметр собственно само число.
второй - константа, которая указывает способ форматирования числа ffGeneral, ffExponent, ffFixed, ffNumber, ffCurrency
третий и четвёртый указывают сколько чисел отвести под дробную часть и под число в целом.

Оценка за ответ: 5.

2. [Отвечает: Николай Рубан (статус: 4-ый класс), 21.01.2007, 22:49]:

1) Как можно определить количество заполненных строк компонента StringGrid1?

Вот процедура:
procedure TForm1.BitBtn1Click(Sender: TObject);
var i,j,kol,rez:integer;
b:boolean;
begin
kol:=0;//количество НЕ заполненных строк
with StringGrid1 do
for i:=0 to RowCount-1 do
begin
b:=true;
for j:=0 to RowCount-1 do
if Cells[j,i]<>'' then
begin b:=false; break; end;
if b then inc(kol);
end;
rez:=StringGrid1.ColCount-1-kol;//количество заполненных строк
end;

2) И ещё назовите, пожалуйста, стандартную функцию с ее параметрами для преобразования вещественного числа в строку с указанием формата записи числа.

Рекомендую Вам пользоваться функцией Format().
function Format(const Format: string; const Args: array of const) : string;

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

Второй параметр функции Format называется списком аргументов. Он и содержит "вставляемые" в форматирующую строку параметры. Обратите внимание, что этот открытый массив имеет тип array of const, и в нем может передаваться переменное число разнотипных параметров.

Более подробно о параметрах и возможностях функции можно прочитать по ссылкеhttp://psf.grsu.by/UchProc/konspekt/delphi/ch05/ch03.

Удачи!!!

Оценка за ответ: 5.



Вопрос № 279

Текст вопроса:

Стоит задача создать сервис, который при старте запустит другое приложение через СОМ. И чтоб это приложение висело в памяти до остановки службы.
Дайте что-то почитать про использование обработчиков OnExecute,OnStart etc.

Приложение:

Автор вопроса: Вакуленко (статус: Посетитель)
Дата и время отправки вопроса: 22.01.2007, 22:19
Получено ответов на вопрос: 2
Сообщений в форуме вопроса: 10
Страница данного вопроса >>


» Ответы на данный вопрос:

1. [Отвечает: Вадим К (статус: Высокий уровень), 23.01.2007, 01:51]:

Вы используете COM объекты, поэтому ваше приложение должно сообщить операционной системе об этом. Делается это вызовом процедуры CoInitialize в самом начале вашей проги. Это общеизвестная проблема.
По поводу почитать могу порекомендовать только MSDN. В часности, замечу, что обработчик OnStart должен быть как можно быстр. Если он будет выполнятся долго, то Операционная система вправе "прибить" ваш сервис. И во вторых, непытайтесь делать активное взаиводействие с пользователем - типа MessageBox'ов - для этого сервис должен быть интерактивным и соответственно накладываются определённые особенности.

2. [Отвечает: Лукьяненко Алексей Валериевич (статус: 1-ый класс), 23.01.2007, 11:46]:

Здравствуйте, Вакуленко!

По поводу COM вам рассказали, добавлю лишь, что при окончании работы нужно вызвать CoUninitialize. Эту пару вызовов необходимо делать для каждого потока, использующего COM. Приложение с сервисом использует 2 потока - поток запустивший сервис (события OnStart, OnStop, OnShutdown) и собственно поток сервиса (OnExecute).
Реализация вашего кода, если это сервис, должна быть записана в обработчике OnExecute. При этом нужно помнить:
1. При выходе из OnExecute сервис завершает свою работу и останавливается.
2. Чтобы сервис мог реагировать на системные ссобщения (типа остановить, перезапустить и др.) в коде сервиса нужно периодически вызывать ServiceThread.ProcessRequests(Wait: Boolean);
Параметр Wait указывает, ждать ли сообщений системы, или только обработать то, что есть в очереди и вернуть управление вызывающему.
В Вашем случае для организации работы сервиса после запуска COM-серверов нужно создать бесконечный цикл, вызывающий ServiceThread.ProcessRequests(True);

Оценка за ответ: 5.



Вопрос № 280

Текст вопроса:

Здравствуйте!
По условию, существует некий файл *.dat, в котором записаны фамилии работников(string) и их зарплаты(real).
Создана структура данных типа "Запись" для обработки требуемых сведений:
Type sotrudn = record
surname:str;
zarpl:real;
end;

Из этого файла нужно считать данные(фамилии работников и их зарплаты) и вывести их в компонент StringGrid1.
Проблема в том, что я не знаю как работать с файлами *.dat, не умею ни записывать их, ни считывать.
Знаю что файл нужно определять по структуре записи, в смысле ff:file of sotrudn;
Кстати, в ходе задачи создавался динамический массив для сохранения сведений о сотрудниках(Type massiv=array of sotrudn;)
Заранее благодарю, с уважением Сергей Анатольевич;

Автор вопроса: Полушин Сергей Анатольевич (статус: Посетитель)
Дата и время отправки вопроса: 23.01.2007, 17:19
Получено ответов на вопрос: 3
Сообщений в форуме вопроса: 5
Страница данного вопроса >>


» Ответы на данный вопрос:

1. [Отвечает: Виталий Лещенко (статус: 3-ий класс), 23.01.2007, 19:15]:

Здравствуйте, Полушин Сергей Анатольевич!
1. Не смотря на расширение файла его можно использовать как обычный текстовый файл.
2. Первой строкой пишеш туда (writeln(file,...)) кол-во сотрудников.
3. Затем для каждого сотрудника в новой строке пишеш данные о нем... хочеш в одну строку, хочешь в несколько.

Считывание происходит в аналогичном порядке.
1. Считываешь кол-во записей. Делаешь массив на столько записей.
2. В соответствии и выбранным форматом, для каждого сотрудника читаешь данные.

Оценка за ответ: 4.
Комментарий: По моему, просто записать кол-во сотрудников не получится, так как файл определяется по типу дданных. var ff:file of sotrudn;

2. [Отвечает: Николай Рубан (статус: 4-ый класс), 23.01.2007, 20:58]:

Начнем с того, почему Вы прицепились к расширению *.dat - вообще не важно какое расширение у типизированного файла, самое главное знать его структуру. Только тогда возможно полноценно с ним работать.

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

Для полноценной работы на форму проекта необходимо разместить две кнопки (TButton), одно поле ввода(TEdit) - в которое вводиться КОЛИЧЕСТВО записей которые нужно ВВЕСТИ. А также таблица (TStringGrid) - с такими настройками:
ColCount = 3
RowCount = 2
FixedCols = 1
FixedRows = 1 (но это все только для красоты) :)

Удачи!!!

Приложение:

Оценка за ответ: 5.
Комментарий: Большое Человеческое спасибо, вы единственный, от кого я получил то, что надо.

3. [Отвечает: Иусов Сергей Ник. (статус: 2-ой класс), 24.01.2007, 07:03]:

Здравствуйте, Полушин Сергей Анатольевич!

Смотри во вложении пример работы с типизарованными файлами.

Оценка за ответ: 4.




Статьи  >>

Рисуем график функции в Delphi

В этой статье мы рассмотрим несколько способов нарисовать график какой-нибудь функции. Рисовать график мы будем на канве компонента Image.

Рисование по пикселям

Рисовать на канве можно разными способами. Первый вариант - рисовать по пикселям. Для этого используется свойство канвы Pixels. Это свойство представляет собой двумерный массив, который отвечает за цвета канвы. Например Canvas.Pixels[10,20] - соответствует цвету пикселя с координатами (10,20). С массивом пикселей можно обращаться, как с любым свойством: изменять цвет, задавая пикселю новое значение, или определять его цвет, по хранящемуся в нем значению. На примере ниже мы зададим черный цвет пикселю с координатами (10,20):

Canvas.Pixels[10,20]:=clBlack;

Теперь мы попробуем нарисовать график функции F(x), если известен диапазон ее изменений Ymax и Ymin, и диапазон изменения аргумента Xmax и Xmin. Для этого мы напишем пользовательскую функцию, которая будет вычислять значение функции F в точке x, а также будет возвращать максимум и минимум функции и ее аргумента.

function Tform1.F(x:real; var Xmax,Xmin,Ymax,Ymin:real):real;
begin
F:=Sin(x);
Xmax:=4*pi;
Xmin:=0;
Ymax:=1;
Ymin:=-1;
end;

Не забудьте также указать заголовок этой функциии в разделе Public:

public
{ public declarations }
function F(x:real; var Xmax,Xmin,Ymax,Ymin:real):real;

Здесь для ясности мы просто указали диапазон изменения функции Sin(x) и ее аргумента, ниже эта функция будет описана целиком. Параметры Xmax, Xmin, Ymax, Ymin - описаны со словом Var потому что они являются входными-выходными, т.е. через них функция будет возвращать значения вычислений этих данных в основную программу. Поэтому надо объявить Xmax, Xmin, Ymax, Ymin как глобальные переменные в разделе Implementation:

implementation
var Xmax,Xmin,Ymax,Ymin:real;

Теперь поставим на форму кнопку и в ее обработчике события OnClick напишем следующий код:

procedure TForm1.Button1Click(Sender: TObject);
var x,y:real;
PX,PY:longInt;
begin
for PX:=0 to Image1.Width do
begin
x:=Xmin+PX*(Xmax-Xmin)/Image1.Width;
y:=F(x,Xmax,Xmin,Ymax,Ymin);
PY:=trunc(Image1.Height-(y-Ymin)*Image1.height/(Ymax-Ymin));
image1.Canvas.Pixels[PX,PY]:=clBlack;
end;
end;

В этом коде вводятся переменные x и y, являющиеся значениями аргумента и функции, а также переменные PX и PY, являющиеся координатами пикселей, соответствующих x и y. Сама процедура состоит из цикла по всем значениям горизонтальной координаты пикселей PX компонента Image1. Сначала выбранное значение PX пересчитывается в соответствующее значение x. Затем производится вызов функции F(x) и определяется ее значение Y. Это значение пересчитывается в вертикальную координату пикселя PY.

Рисование с помощью пера Pen

У канвы имеется свойство Pen - перо. Это объект, в свою очередь имеющий ряд свойств. Одно из них - свойство Color - цвет, которым наносится рисунок. Второе свойство - Width - ширина линии, задается в пикселах (по умолчанию 1).

Свойство Style определяет вид линии и может принимать следующие значения:

psSolid Сплошная линия
psDash Штриховая линия
psDot Пунктирная линия
psDashDot Штрих-пунктирная линия
psDashDotDot Линия, чередующая штрих и два пунктира
psClear Отсутствие линии
psInsideFrame Сплошная линия, но при Width > 1 допускающая цвета, отличные от палитры Windows

Все стили со штрихами и пунктирами доступны только при толщине линий равной 1. Иначе эти линии рисуются как сплошные.

У канвы имеется свойство PenPos, типа TPoint. Это свойство определяет в координатах канвы текущую позицию пера. Перемещение пера без прорисовки осуществляется методом MoveTo(x,y). После вызова этого метода канвы точка с координатами (x,y) становится исходной, от которой методом LineTo(x,y) можно провести линию в любую точку с координатами (x,y).

Давайте теперь попробуем нарисовать график синуса пером. Для этого добавим перед циклом оператор:

Image1.Canvas.MoveTo(0,Image1.height div 2);

А перед заключительным end цикла добавим следующий оператор:

Image1.Canvas.LineTo(PX,PY);

Таким образом у Вас должен получиться такой код:

procedure TForm1.Button1Click(Sender: TObject);
var x,y:real;
PX,PY:longInt;
begin
Image1.Canvas.MoveTo(0,Image1.height div 2);
for PX:=0 to Image1.Width do
begin
x:=Xmin+PX*(Xmax-Xmin)/Image1.Width;
y:=F(x,Xmax,Xmin,Ymax,Ymin);
PY:=trunc(Image1.Height-(y-Ymin)*Image1.height/(Ymax-Ymin));
image1.Canvas.Pixels[PX,PY]:=clBlack;
Image1.Canvas.LineTo(PX,PY);
end;
end;

Как Вы уже успели заметить, если запустили программу, качество рисования графика пером, намного лучше, чем рисования по пикселям.

Как обещал сейчас напишу пример программы которая находит максимум и минимум функции. Я маленько изменил структуру процедур и функций, чтобы было яснее. Вот готовый код программы:

...
type
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
procedure Button1Click(Sender: TObject);
private
{ private declarations }
public
function F(x:real):real;
procedure Extrem1(Xmax,Xmin:real; var Ymin:real);
procedure Extrem2(Xmax,Xmin:real; var Ymax:real);
{ public declarations }
end;

var
Form1: TForm1;

implementation
Const e=1e-4;//точность одна тысячная
var Xmax,Xmin,Ymax,Ymin:real;
{$R *.DFM}
function Tform1.F(x:real):real;
begin
F:=Sin(x);
end;

//поиск минимума функции
procedure TForm1.Extrem1(Xmax,Xmin:real; var Ymin:real);
var x,h:real; j,n:integer;
begin
n:=10;
repeat
x:=Xmin;
n:=n*2;
h:=(Xmax-Xmin)/n;
Ymin:=F(Xmin);
for j:=1 to n do begin
if f(x)<Ymin then Ymin:=f(x);
x:=x+h;
end;
until abs(f(Ymin)-f(Ymin+h))<e;
end;

//поиск максимума функции
procedure TForm1.Extrem2(Xmax,Xmin:real; var Ymax:real);
var x,h:real; j,n:integer;
begin
n:=10;
repeat
x:=Xmin;
n:=n*2;
h:=(Xmax-Xmin)/n;
Ymax:=F(Xmin);
for j:=1 to n do begin
if f(x)>=Ymax then Ymax:=f(x);
x:=x+h;
end;
until abs(f(Ymax)-f(Ymax+h))<e;
end;


procedure TForm1.Button1Click(Sender: TObject);
var x,y:real;
PX,PY:longInt;
begin
//здесь необходимо указать диапазон изменения x
Xmax:=8*pi;
Xmin:=0;

//вычисляем экстремумы функции
Extrem1(Xmax,Xmin,Ymin);
Extrem2(Xmax,Xmin,Ymax);

//рисуем график функции
Image1.Canvas.MoveTo(0,Image1.height div 2);
for PX:=0 to Image1.Width do
begin
x:=Xmin+PX*(Xmax-Xmin)/Image1.Width;
y:=F(x);
PY:=trunc(Image1.Height-(y-Ymin)*Image1.height/(Ymax-Ymin));
image1.Canvas.Pixels[PX,PY]:=clBlack;
Image1.Canvas.LineTo(PX,PY);
end;
end;
end.

Ну вот и всё, программа построения графика функции готова.

Вы можете отправить свои статьи по адресу info@delphi.int.ru и они будут опубликованы в ближайших выпусках рассылки и на сайте.


Файловый архив  >>

Разделы: Статьи | Компоненты | Plug-in's | Документация | Исходники | Программы | Игры | Изображения

Уважаемые читатели! Отправляйте полезные компоненты/модули, интересные исходники, собственные программы/игры и мы разместим их на сайте. Отправить можно здесь »

Название
Описание
Раздел
Объём
Ссылки
TDropper Невизуальный компонент, предназначение которого - возможность использования OLE технологии Drag&Drop, а конкретно - перетаскивание файлов, но не на окно Вашей программы, а из Вашей программы в окно проводника или других программ.
Например для файловых менеджеров, архиваторов и т.д.
5.46 Кб
CustomMessage TCustomMessage позволяет выводить диалоговые окна с произвольными кнопками и заданным текстом.
2 Кб
CanvasButton Графическая кнопка, на которой можно разместить изображение (само изображение может автоматически растягиваться под размеры кнопки), отобразить текст, изменить вид самой кнопки (цвет, два вида градиента). Одним словом, настраиваемая кнопка.
3.5 Кб
TClock Аналоговые часы с большим количеством настроек (в т.ч. использование изображения в качестве фона и автоматические напоминания).
613 Кб
SelectOnRunTime С помощью этого инструмента Вы сможете сделать компоненты в режиме run-time такими же, как и в design-time. Достаточно выбрать компонент и его можно перемещать по форме и даже изменять размеры. Всё в точности как в Delphi IDE.
630 Кб
Основы SQL Учебник по структурированному языку запросов (SQL) с примерами. Отлично подойдёт для изучения SQL при работе с реляционными базами данных.
209 Кб
 
Всего новых файлов: 6  
1.43 Мб
 

Если у Вас есть книги по Delphi (в электронном виде, разумеется) или другая полезная документация - сообщите и её можно будет разместить на сайте.

Отправить файл »   

Юмор

Ведущий раздела: Bruder

Что думают американцы о русских программистах

1. Русские программисты никогда не читают руководств и редко пользуются online подсказкой - они легко понимают новые программы, потому как они ранее уже испробовали все программы подобного рода.

2. Русские программисты никогда не платят за софт. Они или крэкают его или покупают wonderful CD ( не стал переводить - так красивше ) за 5 баксов с кучей софта. В любом крупном городе России.

3. Русские программисты всегда используют самые последние разработки в программном обеспечении - самые последнии версии лучших программ - потому как не надо за них платить.

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

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

6. Русские программисты программируют на всех уровнях, и на процессорных кодах тоже, таблицы которых у них находятся постоянно на рабочем столе. Они помнят назубок список функций прерывания 21h.

7. Русские программисты помнят всю раскладку английской и русской клавиатуры. Вы можете спросить посреди ночи, какая клавиша находится между A и L, вы будете удивлены ответом: "Какую из семи назвать?"

8. Русские программисты ненавидят Майкрософт и Майкрософтовские программы, но используют их.

9. Русские программисты предпочитают Borland, а Microsoft компиляторы инсталлируют только из-за того, что в них хороший help для Windows API.

10. Русские программисты в Интернете чувствуют себя очень комфортно. Они предпочитают всегда быть online, хотя бы просто потому, что может срочно что-то понадобиться.

11. Русские программисты всегда в настроении попрограммировать.

12. Есть два вида Русских программистов - первые ненавидят Windows и программируют под Unix, вторые ненавидят Windows и программируют под них. Макинтошевские программисты - не настоящие программисты - им больше подходит название - "юзеры".

13. Русские программисты не любят "кодировать" чью-то другую идею. Каждая программа пишется персонально.

14. Русские программисты всегда имеют копии Doom, Duke Nukem и Quake на их жестком диске. Они могут играть ночи напролет по сетке в Deathmatch.

15. Русские программисты никогда не используют джойстик. Клавиатура - вот главное оружие.

16. Русские программисты никогда не сдаются. Они могут вылавливать баги из их программы забыв о сне и еде.

17. Жены Русских программистов несчастны, потому как им не уделяется внимания, пока в доме есть хоть один компьютер.

18. Русским программистам недоплачивают. Но и не существует суммы в мире, способной успокоить их желания.

19. Начальники не любят Русских программистов. А кто любит умника, который все знает?

20. Русские программисты не любят использовать шаблоны. Их программы - это индивидуально написанные произведения с большой долей импровизации. Причем, Русский программист старается во всю, чтобы побыстрее запустить программу и увидеть ее в работе.

:))

Присылайте компьютерные анекдоты, рассказы и истории по этой ссылке и они будут опубликованы в ближайших выпусках рассылки.
Ведущий рассылки, Ерёмин Андрей.

В избранное