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

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

  Все выпуски  

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


Программирование на DELPHI
Выпуск #78 (31 января 2008 г.)

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

Delphi.int.ru

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

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

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

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

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

Соскучились? Да, рассылка действительно долгое время была в тени. Однако, если рассылки нет - не стоит беспокоиться. Просто зайдите на сайт, и Вы увидите, что "жизнь идёт"... В любом случае, уточнить состояние рассылки Вы всегда можете в службе поддержки. Позади новогодние праздники, а на дворе уже во всю идёт 2008-ой год. Что ж, будем надеяться, что в этом году наш проект будет увеличивать масштабы, набирать обороты и всесторонне развиваться!

Не забывайте о нашем IRC-канале - там Вам всегда рады. Главный канал находится в сети DalNet (сервер: irc.dalnet.ru, порт: 6667, канал: #delphiintru). Ещё есть канал в сети RusNet (данные для подключения см. на сайте), однако он не стал особо удачным, но, быть может, это только временно?..

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

Совсем недавно был запущен новый пользовательский интерфейс, который собрал воедино все настройки профиля: изменение личной информации, установка личного образа (аватара), система личных сообщений между пользователями сайта, настройки работы в Delphi.int.ru Expert и др. - этот интерфейс живёт по адресу my.delphi.int.ru. Надеемся, что он сильно облегчит работу на сайте.

Самые крупные задачи из планируемых на ближайшее время - создание на сайте форума и реконструкция файлового архива. Что касается системы Expert - она тоже постепенно разивается. Обо всех изменениях можно прочитать на странице "История версий системы".

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

В этом выпуске:

  • Обучение - урок 17: Циклы - цикл с предусловием и цикл с постусловием;
  • Статья: Знакомство с SQLite;
  • Файловый архив - новые программы, компоненты и исходники.

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

Количество экспертов: 47 (+7).
Участниками задано вопросов: 1303 (+169).
Экспертами отправлено ответов: 1882 (+172).
Количество сообщений на мини-форумах: 2379 (+296).
Максимальное число разосланных в день писем (за январь '08): 1503 (20.01.2008).
Максимальное число разосланных в день писем (за всю историю): 1960 (28.10.2007, +0).

До встречи в следующем выпуске!

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

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

Delphi.int.ru Expert
Сообщество программистов: общение, помощь, обмен опытом.

Количество читателей рассылки (31.01.2008, 12:00):
5574+1610+444= 7628 (+39)

Связь по e-mail:

admin@delphi.int.ru
support@delphi.int.ru


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

Delphi.int.ru Expert
Сообщество программистов: общение, помощь, обмен опытом
(текущая версия системы: 2.33; последнее обновление: 23.01.2008)

Последние новости

Начиная с декабря 2007 в начале каждого месяца проходит голосование за лучший ответ месяца и самый интересный вопрос. Победителям вручаются почётные медали.
За ноябрь медали получили: Николай Рубан (лучший ответ) и Павел Федянин (лучший вопрос). За декабрь: Косолапов Дмитрий Юрьевич (лучший ответ) и Emfs (лучший вопрос). На днях начнётся голосование за январь.

11 декабря 2007 г.

Создана система опросов на сайте. В опросах могут принимать участие только зарегистрированные участники.

17 декабря 2007 г.

Реализована функция добавления примечаний к вопросам (подробнее).

 

Архив: вопросы и ответы

В архив попадают вопросы, срок действия которых истёк. Каждый заданный вопрос действителен в течение одной недели, т.е. ответы на него принимаются именно в этот период. В сегодняшнем выпуске опубликованы вопросы # 326 - 340. Вопросы, на которые не было дано ни одного ответа, не публикуются.

Статистика по выпуску:

Кол-во вопросов: 15
Кол-ответов: 33
Баллы за ответы: 89
 

Вопрос # 327

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

Вопрос задал: Шуваев Алексей Сергеевич - 737 (статус: Посетитель)
Вопрос отправлен: 19 февраля 2007, 07:41 (эксперты)
Всего ответов: 1

 

1. Отвечает эксперт: Вадим К

Ну так в чём проблема?
Ставим его на форму. Двойной клик. Добавляем одну серию (вкладки Chart - Series кнопарик Add)
Потом вкладка series - Data source. В комбобоксике - DataSet.
Теперь чуть ниже выбираем Датасет и поля для осей.
Всё, готово.

Ответ отправил: Вадим К (статус: Кандидат наук)
Ответ отправлен: 19 февраля 2007, 12:39


Вопрос # 328

Добрый день)
Как сделать возможность выделения элементов в таблице(например, галочкой)? Т.е. дать возможность пометить нужные ему записи в таблице DBGrid! Я УЖЕ пользуюсь компонентом DBGridEh(!), сам не могу разобраться!
Заранее спасибо!

Вопрос задал: RedMask (статус: Посетитель)
Вопрос отправлен: 19 февраля 2007, 12:05 (эксперты)
Всего ответов: 1; сообщений в мини-форуме вопроса: 2

 

1. Отвечает эксперт: Alex Van Glukhman

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

У компонента TDBGrid есть property Options: TDBGridOptions там устанавливаем dgMultiSelect:=true; Это позволяет выбирать несколько записей. Тоже самое и для TDBGridEh

Удачи

Ответ отправил: Alex Van Glukhman (статус: 7-ой класс)
Ответ отправлен: 19 февраля 2007, 13:20
Оценка за ответ: 3
Комментарий: Это как бы не совсем то, надо выбирать записи целиком, а не область какую то! Так то всё просто было бы =)


Вопрос # 329

Всем Привет!
Вопрос такой:
Как скачать с _http://rapidshare.com имея
Пароль и логин через IndyHTTP. Размер получаю
правильный а скачать не получается.

Вопрос задал: Vit2 (статус: Посетитель)
Вопрос отправлен: 20 февраля 2007, 13:16 (эксперты)
Всего ответов: 2; сообщений в мини-форуме вопроса: 11

 

1. Отвечает эксперт: Роман

Здравствуйте, Vit2!Надо было хоть код привести.Если в коде всё правильно увеличте timeout.

Ответ отправил: Роман (статус: 5-ый класс)
Ответ отправлен: 20 февраля 2007, 14:30

2. Отвечает эксперт: Вадим К

Скорее всего в вашем коде нехватает referns и замените идентификацию с Indy на что нибудь мирное - "opera/ua" к примеру. Многие серверы не равнодушны к идентификации.

Ответ отправил: Вадим К (статус: Кандидат наук)
Ответ отправлен: 20 февраля 2007, 14:37


Вопрос # 330

Доброе время суток всем. Помогите, кто знаеи как (если можно) в компоненте PopupMenu сделать, так чтобы сбоку меню писалось название программы (либо любой текст) или помещалась картинка

Вопрос задал: Дима Гусаков (статус: 2-ой класс)
Вопрос отправлен: 20 февраля 2007, 20:50 (эксперты)
Всего ответов: 3; сообщений в мини-форуме вопроса: 3

 

1. Отвечает эксперт: Евгений Козаченко

Нужно установить TMS Component Pack. Там есть такой компонент "AdvPopupMenu". Вот он умеет так делать. Ссылку дать не могу, но поиск же рулит

Ответ отправил: Евгений Козаченко (статус: 2-ой класс)
Ответ отправлен: 20 февраля 2007, 21:04
Оценка за ответ: 4

2. Отвечает эксперт: Роман

Здравствуйте, Дима Гусаков!Вот по этому адресу: http://sources.ru/magazine/0906/07.html (это архив журнала "Sources.RU Magazine") есть статья об альтернативном способе написать PopupMenu: всплывающее меню – вовсе не меню, а самая обыкновенная форма, и о том, как пидать ей "красивости".Думаю что она поможет в решении проблемы.

Ответ отправил: Роман (статус: 5-ый класс)
Ответ отправлен: 21 февраля 2007, 00:20
Оценка за ответ: 5

3. Отвечает эксперт: Вадим К

Как вариант, можно отрисовать меню самостоятельно. Получиться дешиво и сердито. Вы сможете нарисовать всё, что подскажет вам ваша фантазия :)
Смотреть пример здесьhttp://www.delphikingdom.com/asp/viewitem.asp?catalogid=511&mode=print

Ответ отправил: Вадим К (статус: Кандидат наук)
Ответ отправлен: 21 февраля 2007, 00:21


Вопрос # 331

Такая вот проблема. Написал прогу на Делфи(Работа с базами данных). Но когда удаляю делфи она не идет т.е она рзагружается, но не поддерживает работу с Б.Д. Как сделать чтобы она работала без Делфи и В другой системе, например в Windows 98,2000. Помогите пожалуйста. Буду очень блогадарен.

Вопрос задал: mAx (статус: Посетитель)
Вопрос отправлен: 20 февраля 2007, 23:09 (эксперты)
Всего ответов: 3; сообщений в мини-форуме вопроса: 1

 

1. Отвечает эксперт: Alex Van Glukhman

Здравствуйте, Рожков Максим Сергеевич!

Вариантов здесь может быть очень много. Хотелось бы знать всё-таки тип БД. И используемый в дельфи тип коннекта с БД (BDE, dbGO, IBX и т.д.). При удалении Delphi в BDE псевдоним БД сохраняется. Так что если создавали псевдоним он будет работать. Скорее всего не цепляются дрова линков к БД, которые в идеале должны храниться в Windows/system32. Давайте для начала опишите тип подключки и что выдаёт прога в сообщении об ошибке. Попробуем решить Вашу праблу.

Ответ отправил: Alex Van Glukhman (статус: 7-ой класс)
Ответ отправлен: 21 февраля 2007, 00:17
Оценка за ответ: 4

2. Отвечает эксперт: Вадим К

Если писали по старым книгам, то 99% BDE - кидайтие его побыстрей. Вариант два, при использовании ADO - жестко прописаный путь к базе.

Ответ отправил: Вадим К (статус: Кандидат наук)
Ответ отправлен: 21 февраля 2007, 00:29

3. Отвечает эксперт: Помфюк Владимир Степанович

Здравствуйте, Рожков Максим Сергеевич!
Найдите в установке Delphi файл bdeinst.cab, достанте из него bdeinst.dll и на компьютере, где должна запускатся Ваша программа выполните
regsvr32 bdeinst.dll

Ответ отправил: Помфюк Владимир Степанович (статус: Абитуриент)
Ответ отправлен: 21 февраля 2007, 10:04
Оценка за ответ: 4


Вопрос # 332

Когдая загружаю свою прогу на винде на которой не установлен Delphi и нажимаю на кнопку обработчик события:
Datamodule1.Table1.Active:=False;
Datamodule1.Table1.DatabaseName:= '';
Datamodule1.Table1.TableName:= MainForm.DBComboBox1.Text;
Datamodule1.Table1.TableType:= ttDbase;
Datamodule1.Table1.Active:=True;
with Datamodule1.Table1.FieldDefs do
begin
While not Datamodule1.Table1.Eof do
Begin
if Datamodule1.Table1.FieldByName('Date').AsString=DateToStr(MainForm.DateTimePicker1.Date) Then
MessageDlg('На этот день расписание уже составлено!', MtError,[MBOK, mbCANCEL],0);
Datamodule1.Table1.Next;
end;
Datamodule1.Table1.Edit;
Datamodule1.Table1.Insert;
Datamodule1.Table1.FieldByName('Date').AsString:=DateToStr(MainForm.DateTimePicker1.Date);
Datamodule1.Table1.FieldByName('Lesson1').AsString:=DbLookupCombobox1.Text;
Datamodule1.Table1.FieldByName('Lesson2').AsString:=DbLookupCombobox4.Text;
Datamodule1.Table1.FieldByName('Lesson3').AsString:=DbLookupCombobox7.Text;
Datamodule1.Table1.FieldByName('Lesson4').AsString:=DbLookupCombobox10.Text;
Datamodule1.Table1.FieldByName('Lesson5').AsString:=DbLookupCombobox13.Text;
Datamodule1.Table1.FieldByName('Teacher1').AsString:=DbLookupCombobox2.Text;
Datamodule1.Table1.FieldByName('Teacher2').AsString:=DbLookupCombobox5.Text;
Datamodule1.Table1.FieldByName('Teacher3').AsString:=DbLookupCombobox8.Text;
Datamodule1.Table1.FieldByName('Teacher4').AsString:=DbLookupCombobox11.Text;
Datamodule1.Table1.FieldByName('Teacher5').AsString:=DbLookupCombobox14.Text;
Datamodule1.Table1.Post;
MessageDlg('Сохранено!', MtInformation,[MBOK],0);

т.е. создает таблицу БД Access то уменя выскакивает ошибка:
An error occurred while attempting to initialize the Borland Database Engine (error $2108)
Такая же бадяга если хочу внести в таблицу какието данные.
Что мне делать. Помогите плиз. Просьба: Я еще познаю Азы Delphi. Не могли бы вы обяснить по подробней. Спасибо заранее.
А, еще как мне сделать экзешник минимальным.

Вопрос задал: mAx (статус: Посетитель)
Вопрос отправлен: 21 февраля 2007, 23:17 (эксперты)
Всего ответов: 3

 

1. Отвечает эксперт: Вадим К

Ну не знаю, как ещё отвечать на этот вопрос, который изучен вдоль и впоперек. Дело в том, что когда то (1992-1997гг.) Борланд придумала хорошую технологию доступа к данных - BDE. Хорошую на то время. Но на данный момент эта технология НЕ РАЗВИВАЕТСЯ. Многие, старые да и новые книги по делфи почему то упорно игнорирую этот факт (мож им просто лень переписывать?) и толкают BDE как передовую технологию.
Что же делать? Есть два варианта. Найти где небудь дистрибутив BDE - когда то на сайте борланда был. Есть ли сейчас - не знаю.

Вариант два, более правильный. Да и переделок будет мало - ADO. Судя с вашего кода, вам прийдётся добавить на форму ADOConnection, в котором настоить с помощью мастера доступ к базе (ConnectionString). Рекомендую сразу путь с прямого заменить на относительный.
Также заменить компоненты TTable -> TADOTable
TQuery --> TADOQuery. И с помощью свойства Connection привязать их к ADOConnection. Если вы не особо извращались в коде - заработает с пол пинка.

Ответ отправил: Вадим К (статус: Кандидат наук)
Ответ отправлен: 22 февраля 2007, 00:02
Оценка за ответ: 4

2. Отвечает эксперт: Матвеев Игорь Владимирович

Здравствуйте, Рожков Максим Сергеевич!
Дистрибутив BDE можно достать из программ создания установки, InstallShield или WiseInstall - там есть галочка специальная. Размер дистрибудива Вашей программы "потяжелеет" мегабайт на пять. Также в InstallShield можно добавлять псевдонимы БД.

Но, конечно, лучше сразу переходить на более передовые технологии.

Ответ отправил: Матвеев Игорь Владимирович (статус: Студент)
Ответ отправлен: 22 февраля 2007, 03:27

3. Отвечает эксперт: Alex Van Glukhman

Здравствуйте, Рожков Максим Сергеевич!

Всё правильно! На компе клиента просто не установлена BDE. Надо либо скачать дистрибутив BDE либо настроить подключку без использования BDE

Вот пример написания без использования BDE
http://program.rin.ru/razdel/html/1242.html

Удачи

Ответ отправил: Alex Van Glukhman (статус: 7-ой класс)
Ответ отправлен: 22 февраля 2007, 08:20


Вопрос # 333

Где можно скачать "Сборник задач по Паскалю"
Пильщикова.(Если я не ошибаюсь с автором).
Также нужны сборники задач по Delphi для начинающих.

Вопрос задал: Просвиринин Руслан Олегович (статус: Посетитель)
Вопрос отправлен: 21 февраля 2007, 23:56 (эксперты)
Всего ответов: 1; сообщений в мини-форуме вопроса: 2

 

1. Отвечает эксперт: Alex Van Glukhman

Здравствуйте, Просвиринин Руслан Олегович!

Emule -> поиск Kad -> Сборник задач по Паскалю

Удачи

Ответ отправил: Alex Van Glukhman (статус: 7-ой класс)
Ответ отправлен: 22 февраля 2007, 08:24
Оценка за ответ: 3
Комментарий: хотелось бы узнать более конкретный адрес


Вопрос # 334

Приветствую!!!У меня появилось несколько вопросов:1.Как во время выполнения программы узнать все установленные серверы баз данных;2.Как по известному имнеи сервера узнать какие там находятся базы данных;3.Как определить что программа уже запушенна(кроме создания фалов,или записей в файлах)???? Огромное СПАСИБО!!!

Вопрос задал: KilkaMS (статус: Посетитель)
Вопрос отправлен: 22 февраля 2007, 00:32 (эксперты)
Всего ответов: 1; сообщений в мини-форуме вопроса: 1

 

1. Отвечает эксперт: Вадим К

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

а теперь по существу
1)Никак. Если на компе есть кокой-то сервер, которого вы не знаете, то вы его не найдёте.
Что же делать? Каждый сервер имеет свои "отпечатки". К примеру MySQL висит на 3306 порту. Можно попробывать туда подсоединиться, но не факт, что он там будет. Вариант два - поискать в реестре (они обычно имеют стандартные ключи) поискать в списке сервисов (это и MySQL,MSSQL, FireBird)
Вариант два - используя средства делфи (технологии dbExpress, DBP) попытаться "нашару" подключиться. Если получилось - сервер есть.
2) тут чуточку проще. Если вы можете подключиться к серверу, то можно у него это запросить. Для каждого сервера свои команды. Например, MySQL для этого нужно подключиться к специальной таблице и оттудова можно "стянуть"
3)В своих программах я использовал следующие методы. С помощью FindWindow я ищу окно своей программы. Если нахожу, то принимаю соответствующие действия. Недостаток - ваше приложение должно иметь форму с именем, которое отсутствует в системе. Но можно не только по имени, но и по типу. приведу пример
if FindWindow('TMyCoolForm','MyCoolFormCaption')<>nil then Application.Terminate.
Первый параметр - это тип формы, второй - Caption. Если у вас заглавие формы меняется, то можно искать только по типу - тогда в качестве второго параметра пишем nil

Ответ отправил: Вадим К (статус: Кандидат наук)
Ответ отправлен: 22 февраля 2007, 01:03
Оценка за ответ: 5


Вопрос # 335

Здравствуйте!
IBTable.RecordCount существующей таблицы с множеством записей выдаёт 0!

Я пытаюсь навигацией пройтись по всей таблице и выбрать названия в Combobox, а в итоге в Combobox'е оказывается только первая запись из таблицы?
Наверняка вы сталкивались с этим! Спасибо!
Привожу отрывок кода

Приложение:

Вопрос задал: RedMask (статус: Посетитель)
Вопрос отправлен: 22 февраля 2007, 09:14 (эксперты)
Всего ответов: 3; сообщений в мини-форуме вопроса: 1

 

1. Отвечает эксперт: Помфюк Владимир Степанович

Здравствуйте, RedMask!
Сделайте
while not(IBTable1.EOF) do
или
IBTable1.Last;
rc:=IBTable1.RecordCount;
IBTable1.First;
for i:=0 to rc do

Ответ отправил: Помфюк Владимир Степанович (статус: Абитуриент)
Ответ отправлен: 22 февраля 2007, 09:52
Оценка за ответ: 5
Комментарий: Спасибо! Теперь сделаю!
Но всё таки, интересно, почему так?

2. Отвечает эксперт: Бубырь Александр Николаевич

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

Ответ отправил: Бубырь Александр Николаевич (статус: 6-ой класс)
Ответ отправлен: 22 февраля 2007, 11:00
Оценка за ответ: 5
Комментарий: После вашего ответа прочитал про комманду FetchAll! Много нового и интересного, очень благодарен

3. Отвечает эксперт: Alex Van Glukhman

Здравствуйте, RedMask!
Если брать Ваш код то правильнее сделать так.
Компонент IBTable хранит данные набора в кэше и
обновление набора данных в кэше опрежделяется выполнением транзакции.
if IBTransaction1.Active then IBTransaction1.Commit;
IBTransaction1.StartTransaction;
IBTable1.Active:=true;
ShowMessage(inttostr(IBTable1.RecordCount));
if not IBTable1.IsEmpty then
begin
IBTable1.First;
while not IBTable1.eof do
begin
ComboBox2.Items.Add(IBTable1.FieldByName('NAME').AsString);
IBTable1.Next;
end;
IBTable1.Active:=false;
Смею предположить что кроме извлечения данных вы пытались ещё что-то занести в таблицу. По рекомендации Borland компонент IBTable рекомендуется использовать только для неизменяемых наборов данных, все изменяемые наборы данных используют компонент TIBQuery
Удачи!

Ответ отправил: Alex Van Glukhman (статус: 7-ой класс)
Ответ отправлен: 22 февраля 2007, 11:05
Оценка за ответ: 5
Комментарий: Спасибо, про транзакцию не знал) Про изменения набора данных тоже в первый раз слышу! :-)


Вопрос # 336

Доброго времени суток господа эксперты. У меня такая проблема. Я хочу сделать так чтобы мою прогу небыло видно в диспетчере задач. Пытался зарегестрировать как сервис не получается. Может я делаю что-то не так плз помогите. Если можно пример кода. Заранее благодарю

Вопрос задал: Яковлев Николай Сергеевич (статус: Посетитель)
Вопрос отправлен: 22 февраля 2007, 13:49 (эксперты)
Всего ответов: 4; сообщений в мини-форуме вопроса: 2

 

1. Отвечает эксперт: Роман

Здравствуйте, Яковлев Николай Сергеевич!Вот адресок:http://sources.ru/delphi/internet/remote_admin_aibolit.shtml.Это статья Троянец "Айболит" называется. Там есть исходники.Сервер прописывается в windows/system,в автозапуск,не имеет видимого окна и не виден в диспетчере задач.

Ответ отправил: Роман (статус: 5-ый класс)
Ответ отправлен: 22 февраля 2007, 14:17
Оценка за ответ: 4

2. Отвечает эксперт: Вадим К

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

Ответ отправил: Вадим К (статус: Кандидат наук)
Ответ отправлен: 22 февраля 2007, 14:50
Оценка за ответ: 4

3. Отвечает эксперт: Alex Van Glukhman

Здравствуйте, Яковлев Николай Сергеевич!
Всё это реализуется достаточно просто, но в данной ситуации я полностью согласен с предыдущим ответом.
Удачи!

Ответ отправил: Alex Van Glukhman (статус: 7-ой класс)
Ответ отправлен: 22 февраля 2007, 15:58
Оценка за ответ: 4

4. Отвечает эксперт: Denisss

Вот статья:
http://www.wasm.ru/article.php?article=apihook_1
Пример бери там же, внизу, называется [url=http://www.wasm.ru/pub/21/files/prochide.rar]ProcHide[/URL].

Ответ отправил: Denisss (статус: 2-ой класс)
Ответ отправлен: 24 февраля 2007, 21:35
Оценка за ответ: 5


Вопрос # 337

Уважаемые эксперты, я только начинаю изучать программирование. Купил книгу В.Кадлеца "Delphi книга рецептов....".
В разделе примеров обработки событий предлагается описать код цикла для кнопки.
Не получается(
При компиляции курсор встает после слова ShowMessage, и вся строка красным выделяется.
В чем ошибка?
(фрагмент кода,точно(!) как в книге, привожу ниже).
Спасибо.

Приложение:

Вопрос задал: Игорь (статус: Посетитель)
Вопрос отправлен: 22 февраля 2007, 19:18 (эксперты)
Всего ответов: 5; сообщений в мини-форуме вопроса: 3

 

1. Отвечает эксперт: Помфюк Владимир Степанович

Здравствуйте, Игорь!
1)Точки с запятой нет перед ShowMessage
2)Операция какая-то ненормальная: J:= J = 10

Ответ отправил: Помфюк Владимир Степанович (статус: Абитуриент)
Ответ отправлен: 22 февраля 2007, 19:22

2. Отвечает эксперт: Федоров Роман Сергеевич

Здравствуйте, Игорь!
В вашей книге опечатка. Код должен выглядеть следующим образом:

Приложение:

Ответ отправил: Федоров Роман Сергеевич (статус: 2-ой класс)
Ответ отправлен: 22 февраля 2007, 21:55

3. Отвечает эксперт: Alex Van Glukhman

Здравствуйте, Игорь!

Советую перед тем как изучать примеры по книгам, хотя бы поверхносто изучить основы синтаксиса Object Pascal. Хотя компилятор и отслеживает ошибки кода, но понимание разметки и правил определения структурных единиц никогда не помешает. Таким образом исчезнут многие вопросы и огромное число потерянного времени на поиск ошибок.

Удачи!
м

Ответ отправил: Alex Van Glukhman (статус: 7-ой класс)
Ответ отправлен: 22 февраля 2007, 23:09

4. Отвечает эксперт: Вадим К

и никто не нависал правильный вариант
мда, эксперты.
procedure TForm1.Button2Click(Sender: TObject);
var I,J: Integer;
begin
J:=0;
for I:= 1 to 10 do
J:= J + 10 ;
ShowMessage ('Цикл окончен, значение J = ' + IntToStr(J));
end;
end.
Всегда читайте текст сообщения о ошибке которое пишет Делфи. Хотя там по английски, но всё достаточно понятно. Если нет - выделяем описание ошибки и нажимаем F1 - делфа приведёт описание ошибки и почти всегда она приводит пример правильной и неправильной программы. Смотрим свой код и сравниваем
эксперт: Федоров Роман Сергеевич точку с запятой кто поставит?

Ответ отправил: Вадим К (статус: Кандидат наук)
Ответ отправлен: 23 февраля 2007, 00:34

5. Отвечает эксперт: Дима Гусаков

Здравствуйте, Игорь! В строке выше вместо J:= J = 10 напиши J:= J + 10; не забывай вконце строки ставить точку с запятой

Ответ отправил: Дима Гусаков (статус: 2-ой класс)
Ответ отправлен: 23 февраля 2007, 09:57


Вопрос # 338

Приветствую!!!Как можно послать сообщение на др. комп. не используя NET SEND.Вообще разрабатываю ИС и хочу чтобы пользователи могли переписываться из нее.Могу узнать имя машины,и ip тоже не проблема.

Вопрос задал: KilkaMS (статус: Посетитель)
Вопрос отправлен: 23 февраля 2007, 01:12 (эксперты)
Всего ответов: 1

 

1. Отвечает эксперт: Матвеев Игорь Владимирович

Здравствуйте, KilkaMS!
Сообщения от net send принимаются службой сообщений (svchost.exe -k netsvcs), которая присутствует на всех системах (правда обычно отключена) т.е. Вы можете посылать сообщения на любой компьютер, на него не нужно будет ставить своих программ.
Есть другой вариант - писать методы отсылки/приема в своей программе и кидать ее в автозапуск.
Как писать передачу/прием сообщений - зависит от Вашей ситуации: планируется ли chat room'ы, многоадресные сообщения и т.д. Можно использовать распространенные примеры с TCP сокетами - тогда необходим сервер, можно воспользоваться UDP - здесь можно слать на подсеть, в этом случае желательно личные сообщения "заворачивать" в пакет, где указывать адресата и шифровать (как нельзя здесь подходит RSA).
Ну а если в сети много компьютеров - лучше воспользоваться IRC сервисами - там уже все проработано и отлажено - лучше не придумаете.
Ссылки:
\Program Files\Borland\Delphi6\Demos\Internet\Chat
Сергей Бобровский - "Delphi 6 и Kylix".

Ответ отправил: Матвеев Игорь Владимирович (статус: Студент)
Ответ отправлен: 23 февраля 2007, 06:07
Оценка за ответ: 5


Вопрос # 339

Приветствую!!!Есть у кого-нибудь текст лицензии OpenSourсe?

Вопрос задал: KilkaMS (статус: Посетитель)
Вопрос отправлен: 23 февраля 2007, 01:13 (эксперты)
Всего ответов: 2

 

1. Отвечает эксперт: Матвеев Игорь Владимирович

Здравствуйте, KilkaMS!
Есть поисковой движок для программистов www.koders.com - там можно выбрать тип лицензии и есть список где-то из 20 общеупотребительных лицензий и их описаниями.
http://www.koders.com/info.aspx?c=LicenseInfo.

Ответ отправил: Матвеев Игорь Владимирович (статус: Студент)
Ответ отправлен: 23 февраля 2007, 02:10
Оценка за ответ: 5

2. Отвечает эксперт: Вадим К

Да,лицензий много, самой OpenSourse'ной считается GPL (можно даже переводы найти например здесь http://www.infolex.narod.ru/gpl_gnu/gplrus.html, а здесь http://www.linux.kiev.ua/ru/devel/licenses/gpl-explained/ некоторые рассуждения). На данный момент Ричард М. Столлман разрабатывает третью версию этой лицензии, но многие не совсем согласны с ней (читать здесьhttp://citkit.ru/articles/230/).
---
В целом,вам никто не мешает написать свою лицензию и распространять софт под ней. Один мой знакомый распространяет под такой лицензией "Вы можете свободно копировать, изменять эту софтину, дописывать (но не приписывать) авторство. Если у вас есть возможность - подбростье автору бутылочку пива."

Ответ отправил: Вадим К (статус: Кандидат наук)
Ответ отправлен: 23 февраля 2007, 11:41
Оценка за ответ: 5


Вопрос # 340

Здравствуйте!
Подскажите что можно сделать чтобы приложение в виде экзешника работало только на оригинальном диске. То есть как защитить приложение от копирования с диска на диск.

Вопрос задал: HotMan (статус: Посетитель)
Вопрос отправлен: 23 февраля 2007, 12:34 (эксперты)
Всего ответов: 3

 

1. Отвечает эксперт: Вадим К

В общем виде эта задача нерешабельна. тоесть нет точного способа решить. Запомните, всё что написано одним человеком, гарантировано может быть сломано другим. Проблема только во времени. Новсё же пару идей могу дать. Можно скачать StarForce - но он достаточно дорог, и если у вас это еденичная программа, то она врядли окупиться.
Вариант два - привязаться к номеру диска. Только не делайте в коде проверок типа
if MySecurityCod<>CD_Cod then begin
ShowMessage('Не на том диске работаем!');
Application.Terminate;
end;
Лучше зашифровать этим кодом данные программы (они у вас наверняка есть). Код лучше выбрать несеметричный и проверку делать так.
Расшифровываем небольшой участок(килобайт-другой) и проверяем его crc. если он несовпадает - кричим, но не сразу, а просто не отображаем данные. Но всёравно такая защита может быть обойдена.
Если вы хотите написать что то серёзное, то рекомендую почитать Криса Касперски (С Евгением Касперским непутать!) - этот человек написал многохороших книг, в часности по поводу защиты и слома для компактов. (Только не говорите, что вам не нужно ломать! Если вы не представляете, как можно сломать вашу защиту, вы никогда не можете быть уверены, что она более-менее надёжна.) Скачать книги в электронной версии можно на http://kpnc.opennet.ru/ (сам автор разрешил их выложить, но он будет абсолютно не против, елси вы их купите :) ) И хотя там много кода на С/С++, но автор имеет особенность очень доходчиво писать.

Ответ отправил: Вадим К (статус: Кандидат наук)
Ответ отправлен: 23 февраля 2007, 12:57
Оценка за ответ: 3

2. Отвечает эксперт: Матвеев Игорь Владимирович

Здравствуйте, Kardonsky Roman Viktorovich!

Добавлю еще свои соображения к обстоятельному рассказу Вадима.

Итак, вариант с номером диска в чистом виде отметаем сразу, поскольку это ломается моментально. Вариант с шифрованием гаммой, построенной на этом же коде диска также отметаем: сломать тяжелее, но программа так и так должна определять этот код, для чего придется воспользоваться SystemVolumeInformation - найдя этот вызов есть возможность его здесь же поменять, ведь у взломщика есть доступ к оригинальному диску (конечно можно попробовать скрыть вызов API, но это не совсем "красиво", да и надо проверять для разных OC).

Что еще можно придумать? StarForce - это хорошо, очень сильная система, но дорога, однако можно воспользоваться частью ее методов.

Как работает StarForce - принцип системы основан на том, что болванки из одной партии имеют одинаковые физические параметры, в то время как болванки из разных партий со значительной долей вероятности имеют разные физ. параметры.

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

Еще замечания:
1. Можно использовать не только "карту скоростей чтения", но и скорость перемещения по диску, т.е. скорость «перепрыгивания» с одной позиции на другую.
2. Можно к гамме можно все-таки подмешать и серийный номер диска.

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

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

Ответ отправил: Матвеев Игорь Владимирович (статус: Студент)
Ответ отправлен: 23 февраля 2007, 15:28
Оценка за ответ: 4

3. Отвечает эксперт: Новаковский Юрий Аврамович

Здравствуйте, Kardonsky Roman Viktorovich!
Попробуйте так:

Инсталяшка после установки Вашей программы считывает номер диска, материнки, проца и т.д.
Затем сцепляет эти номера в массив байт и хеширует этот массив. Хешированное значение записывается в реестр в виде бинарного ключа.
При каждом запуске Ваша программа делает то же самое, считывает с реестра этот ключ и сравнивает по байтам два хешированных значения.
Если инсталяху и саму программу сжать EXE-упаковщиком, то получится почти 100% надежность.
Алгоритмов хеширования и получения с железа серийных номеров в инете полно. Дальше, думаю, понятно.
Удачи!

Ответ отправил: Новаковский Юрий Аврамович (статус: 4-ый класс)
Ответ отправлен: 26 февраля 2007, 15:54
Оценка за ответ: 3


Обучение Delphi

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

14. Выбор (ветвления)
15. Подводим промежуточный итог
16. Циклы - общее понятие; цикл с параметром

Циклы - цикл с предусловием и цикл с постусловием

Автор:
© Ерёмин А.А., 2008
У прогресса должен быть и тормозной рычаг!
Номер урока:
17
 

Введение

На прошлом уроке мы познакомились с циклами и разобрались, как использовать цикл по переменной. Сегодня мы разберём оставшиеся два вида циклов - цикл с предусловием и цикл с постусловием. Они очень похожи и просты в использовании.

Задача

Определить количество натуральных чисел, рассматривая их в порядке возрастания, сумма кубов которых не превышает 50000. Т.е. мы должны последовательно суммировать кубы чисел 1, 2, 3, ..., и делать это до тех пор, пока сумма не достигнет 50000, а в результате должны узнать, сколько чисел было пройдено.

Понятно, что решить задачу лучше использованием цикла. Но будет ли решение с циклом FOR оптимальным? Конечно, можно задать диапазон пробегаемых значений от 1 до 50000 - количество чисел точно будет найдено (очевидно, это кол-во будет даже менее 50, ведь 50^3 >> 50000). Но в этом случае придётся ставить дополнительное условие на значение суммы и выполнение команды Break.

Есть способ проще!

Цикл WHILE - цикл с предусловием

Цикл WHILE (англ. "пока") - цикл, в котором условие находится перед телом цикла, а сам цикл выполняется до тех пор, пока условие не станет ложным.

Общий вид:

WHILE {условие} DO
  {действия}

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

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

Решение задачи с помощью цикла WHILE

Вернёмся к нашей задаче. С помощью цикла с предусловием задача решается очень просто. Во-первых, нам потребуется переменная, в которой будет храниться текущее обрабатываемое число - это будут числа 1, 2, 3 и т.д. Во-вторых, ещё одна переменная потребуется для хранения суммы кубов чисел. Всё, этого достаточно. Теперь разберёмся, что писать в теле цикла. Там мы должны: а) увеличивать переменную-счётчик на единицу, чтобы последовательно проходить числа; б) увеличивать сумму на куб текущего числа. Условием цикла будет главное условие нашей задачи - достижение суммой 50000. Вот что получается:

procedure TForm1.Button1Click(Sender: TObject);
var s,i: integer;
begin
  i:=0;
  s:=0;
  while s < 50000 do
  begin
    Inc(i);
    Inc(s,i*i*i);
  end;
  Label1.Caption:=IntToStr(i-1)
end;

В данном случае процесс "повешен" на кнопку (Button1), а результат выводится в текстовую метку (Label1). Вы спросите, почему выводится i-1, а не само число i ? Всё просто. Ведь переменная-счётчик увеличивается после того, как проверяется условие цикла, а значит и результат получится на единицу больше. Удостовериться в этом можно, добавив в тело цикла вывод промежуточных результатов (в примере - в текстовое поле Memo1):

Memo1.Lines.Add(IntToStr(s)+' : '+IntToStr(i));

Цикл REPEAT - цикл с постусловием

Завершает тройку циклов цикл с постусловием - REPEAT (англ. "повтор"). Примечательно, что этого цикла во многих языках программирования нет - есть только FOR и WHILE. Между тем, цикл с постусловием очень удобен.

Работает цикл точно так же, как и WHILE, но с одним лишь отличием, следующим из его названия - условие цикла располагается после тела цикла, а не до него.

Общий вид:

REPEAT
  {действия}
UNTIL {условие выхода из цикла};

Есть несколько моментов, на которые стоит обратить внимание. Во-первых, в качестве условия задаётся уже условие выхода из цикла, в то время как в цикле WHILE задаётся условие продолжения цикла. Во-вторых, при наличии нескольких команд, которые помещаются в тело цикла, заключать их в блок BEGIN .. END не нужно - зарезервированные слова REPEAT .. UNTIL сами составляют аналогичный блок.

Цикл с постусловием, в отличие от цикла с предусловием, всегда выполняется хотя бы один раз! Но, как и цикл WHILE, при неверно написанном условии цикл станет "вечным".

Решение задачи с помощью цикла REPEAT

Решение нашей задачи практически не изменится - всё останется, только условие будет стоять в конце, а само условие изменится на противоположное:

procedure TForm1.Button2Click(Sender: TObject);
var s,i: integer;
begin
  i:=0;
  s:=0;
  repeat
    Inc(i);
    Inc(s,i*i*i);
  until s >= 50000;
  Label1.Caption:=IntToStr(i-1);
end;

Команды Break и Continue

Команда Break, выполняющая досрочный выход из цикла, работает не только в цикле FOR, но и в циклах WHILE и REPEAT. Аналогично, команда Continue, немедленно запускающая следующую итерацию цикла, может использоваться в циклах WHILE и REPEAT.

Как остановить цикл?

Очень часто спрашивают, как написать такой цикл, который можно было бы остановить нажатием кнопки на форме, или, к примеру, клавишей [Esc]. В простейшем случае реализовать такой механизм достаточно просто. Однако, данный метод является не совсем верным - есть более удобные и правильные средства для организации таких операций. Тем не менее, рассмотрим пример.

Задание: при нажатии кнопки "Старт" программа начинает генерировать случайные комбинации из латинских букв (верхнего регистра) длиной 10 символов и все эти комбинации отображаются в текстовом поле TMemo. При нажатии кнопки "Стоп" генерация должна быть прекращена.

Каким образом решить поставленную задачу? Сначала сделаем акцент на механизме остановки. Понятно, что в данном случае нужно задать вечный цикл, да-да, самый настоящий, но каким образом предусмотреть его остановку? Очевидно, что выбор падает либо на WHILE, либо на REPEAT. Остановить цикл можно либо изменив значение логического выражения, заданного для цикла, либо вызвав команду Break. Вопрос стоит теперь в том, как при нажатии кнопки "Стоп" изменить условие цикла, описанного в обработчике кнопки "Старт". Ответ прост - использовать ту память, которая доступна обработчикам обеих кнопок. Итак, заведём глобальную переменную, которая будет видна во всей программе. Глобальные переменные описываются над словом implementation модуля, там, где идёт описание формы:

var
  Form1: TForm1;
  Stop: Boolean = False;

В этой логической переменной мы будем хранить состояние процесса. Изначально будет стоять значение "ложь", а когда пользователь щёлкнет по кнопке "Стоп", мы изменим его в "истина".

На форме разместим Memo1 (TMemo) и 2 кнопки: Button1 ("Старт"), Button2 ("Стоп"). У кнопки "Стоп" поставим Enabled = False, т.е. выключим её.

Сразу приведу обработчики обеих кнопок, после чего подробно разберём их работу:

procedure TForm1.Button1Click(Sender: TObject);
var s: string; c: byte;
begin
  Button2.Enabled:=True;
  Button1.Enabled:=False;
  Stop:=False;
  while not(Stop) do
  begin
    s:='';
    for c := 1 to 10 do
      s:=s+Chr(Random(Ord('Z')-Ord('A')+1)+Ord('A'));
    Memo1.Lines.Add(s);
    Application.ProcessMessages
  end
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  Stop:=True;
  Button2.Enabled:=False;
  Button1.Enabled:=True;
end;

Начнём с кнопки "Стоп" (Button2). При её нажатии:
1) Значение переменной Stop устанавливается в True, т.е. мы подаём сигнал, что нужно остановиться;
2) Кнопку "Стоп" мы снова выключаем;
3) Кнопку "Старт" - наоборот, включаем.

Теперь кнопка "Старт" (Button1):
1) Кнопка "Стоп" включается, кнопка "Старт" выключается;
2) Переменной Stop присваивается значение False (если этого не сделать, то запустить процесс генерации второй раз будет невозможно);
3) Цикл с генерацией строки с условием на переменную Stop - цикл будет работать до тех пор, пока переменная Stop имеет значение False. Как только значение станет True, цикл сам завершит свою работу.

А теперь более подробно о том, что происходит в теле цикла. Начнём с генерации строки символов. Напомню, что строки можно складывать. Если сложить строку 'A' со строкой 'B', то получится строка 'AB'. Именно этот приём здесь и использован. Сначала мы делаем строку пустой, а затем последовательно добавляем в неё 10 произвольных символов. Как происходит добавление... Ну естественно с помощью цикла на 10 итераций. А вот выбор случайной из латинских букв не совсем прост и не для всех очевиден. Конечно, можно было заранее записать все буквы куда-либо (например, в массив, или в другую строковую переменную), а затем брать их оттуда. Но это не совсем хорошо, ведь можно сделать гораздо проще. В данном случае решающим фактором является то, что латинские буквы в кодовой таблице символов идут по порядку. Т.е. 'A' имеет некоторый код n, 'B' имеет код n+1 и т.д. - весь алфавит идёт последовательно, без разрывов. Убедиться в этом можно с помощью программы "Таблица символов& quot;, которая есть в Windows.

Вернёмся к нашей задаче. Мы должны выбрать случайную из букв 'A'..'Z'. Так как коды этих символов последовательны, то мы должны выбрать произвольное число от код_символа_A до код_символа_Z. Напомню, что для выбора случайного числа используется функция Random(n), возвращающая случайное число от 0 до n-1. Недостаток функции в том, что она берёт числа всё время от нуля, а код символа 'A' уж явно не 0. Но и здесь ничего сложного нет: сначала узнаём "ширину" диапазона кодов - из кода символа 'Z' вычитаем код символа 'A'. Не забываем прибавить 1, иначе буква 'Z' никогда не попадёт в строку, т.к. число берётся от 0 до n-1. Ну и дальше мы делаем сдвиг числа на код символа 'A'.
На буквах: от 'A' до 'Z' p позиций. Сама 'A' стоит в позиции n. Очевидно, 'Z' стоит в позиции p+n. Берём случайное число от 0 до p, а прибавив n получаем число из интервала от n до n+p. Простая арифметика, которая не для всех кажется простой.
Итак, код символа мы получили - осталось только добавить соответствующий символ в нашу строку. Функция Chr() возвращает символ с указанным кодом.

Для справки: очень часто, глядя на такой код, говорят, что он неоптимален - мол, коды символов будут постоянно рассчитываться (речь о функции Ord). Однако знающие люди никогда этого не скажут, ведь в Delphi есть маленькая хитрость: компилятор вычислит эти значения ещё на этапе компиляции и в программе они будут просто константами. Т.е. Ord('Z') и Ord('A') в программе не будут считаться никогда - там будут стоять вполне реальные числа, а значит никакого избытка вычислений идти не будет. Более того, даже вычитание будет произведено на этапе компиляции, ведь оба слагаемых являются константами. Мы пишем Ord('A') и Ord('Z') только из-за того, чтобы не лезть в кодовую таблицу, и не смотреть вручную коды этих символов. Кроме того, если вместо этого записать реальные коды, другой человек может испытать затрудение при чтении кода - он ведь не знает, откуда вы взяли эти числа и не помнит всю кодовую таблицу, чтобы определить, каким символам эти числа соот ветствуют.

Далее полученная строка s добавляется в Memo1 уже известным способом. А вот последняя строка в теле цикла - это маленькая хитрость. В одном из уроков об этой команде уже упоминалось. Дело в том, что при отсутствии этой команды программа просто зависнет с точки зрения пользовательского интерфейса - никаких изменений в Memo видно не будет, да и само окно перестанет реагировать на щелчки. На самом деле, конечно, программа будет работать, в памяти генерация строк будет идти полным ходом... Команда Application.ProcessMessages заставляет приложение обработать всю очередь задач, в том числе по отрисовке окна программы и элементов формы. Если при генерации каждой строки это будет происходить, программа будет выглядеть вполне живой - можно будет легко переместить окно по экрану и, что самое главное, нажать на заветную кнопку "Стоп". Ради эксперимента попробуйте убрать эту строку, и посмотреть, что получится.

Программа генерации строк

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

Подводим итог

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


Оцените данный урок (1 - плохо, ..., 5 - отлично): -1- -2- -3- -4- -5-. Комментарии в тексте письма приветствуются.
 

Статьи

Самые популярные статьи на сайте:

Создание непрямоугольных форм в Delphi
Как можно из Delphi отслеживать все события Windows?
Конвертирование графических форматов
Работа с приложениями Microsoft Office. Excel
Как прочитать ID3-Tag'и из MP3-файла?
Работа с реестром и INI-файлами в Delphi
Работа с приложениями Microsoft Office. Word
Написание инсталлятора на Delphi
Работа со строковыми типами данных
Работа с HTML-справкой в программах

Знакомство с SQLite

Автор: Вадим К

Вступление

Часто на форумах, да и здесь на сайте спрашивают, какую базу данных выбрать. Хочу сегодня представить вам ещё один движок БД, у которого есть свои преимущества.

Называется этот движок SQLite. Итак, его преимущества:

  • бесплатный + открытый исходный код;
  • достаточно быстр;
  • не нуждается в дополнительной настройке на клиентской машине – распространять вместе с приложением нужно только одну dll;
  • лоялен к программисту;
  • возможность работать с компакт-диска (т.е. в режиме "только для чтения");
  • возможность работать с гостевого аккаунта;
  • никаких записей в реестр и на диск (кроме dll и файла базы данных), никаких настроек сетевых протоколов;
  • многоплатформенный: есть поддержка для многих языков (с 3 версии формат файла БД совместим для различных ОС и языков);
  • сама dll зависит только от одной системной dll - MSVCRT.DLL, которая всегда есть в системе;
  • синтаксис SQL достаточно хорошо соответствует стандарту – вы можете взять любую книгу, где описывается ANSI SQL 92 и пользоваться. Или посмотреть на сайте http://www.sqlite.org/lang.html.

Но есть и недостатки:

  • не рекомендован для баз большого размера (эксперты не рекомендуют более 200 Мб);
  • есть только два типа данных – целое автоинкримент и строка (всё остальное – эмулируется через строки);
  • не предназначен для многопользовательского использования (хотя это и возможно).

Начальные приготовления

Для работы с этой базой нам в обязательном порядке понадобится сама dll. Её можно скачать с сайта http://www.sqlite.org/ или взять в архиве к статье. С dll можно работать напрямую, но куда удобнее использовать обертку в виде классов. Есть обертка, которая подобна делфийскому TTable, есть и драйвер для ODBC, который позволяет работать с базой посредством TADOTable. И если первый вариант ещё интересен, то вариант с использованием через ADO лишен смысла – многие «вкусности» теряются.

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

Также неплохо иметь ещё одну программу – программу для редактирования баз данных. Что-то в виде Database Desktop, только для SQLite. Такая программа есть и она бесплатна. Скачать можно здесь http://sqlitebrowser.sourceforge.net/ или опять же, взять в архиве. Хотя программа и проста, свою работу выполняет отлично. Мы не будем составлять базу в программе, а пойдём как настоящие кодеры - научимся создавать её в своей программе.

Работа с БД

Для примера мы создадим маленькую базу из одной таблицы. У нас будет одно автоинкрементое поле и два строковых.

Запускаем Delphi. Создаём новый проект. В папку с проектом копируем файлы sqlite3.pas, sqliteTable3.pas и sqlite3.dll. Дальше их надо подключить к проекту. Выбираем в меню Project – Add to project и добавляем эти файлы. Также не забываем сделать File – Use unit и выбрать эти же файлы, но предварительно переключившись на главный юнит.

После строки {$R *.dfm} допишем Var sldb: TSQLiteDatabase; - это будет глобальный объект для работы с базой. Хотя лучше сделать его свойством формы. Кто понимает – сделает :-)

Делаем подключение к базе. Для этого впишем такой код в FormCreate:

procedure TForm1.FormCreate(Sender: TObject);
begin
  sldb := TSQLiteDatabase.Create('test.db');
  try
    if not sldb.TableExists('test') then
       sldb.ExecSQL('CREATE TABLE Test (id INTEGER PRIMARY KEY, T1 TEXT, T2 TEXT)');
  except
    ShowMessage('При создании базы произошла ошибка.');
    Application.Terminate;
  end;
end;

Согласитесь, всё предельно просто. На ADO, если бы базы не было, пришлось бы делать дополнительную работу и писать процедуру не на одну строку.

Суть этого кода следующая – открыть файл test.db. Потом проверить, есть ли в нём таблица test. Если нет – создать, выполнив запрос. Если файла не будет, то он будет создан. Если же при создании таблицы у нас что-то не сложилось – закроем приложение.

Также не забываем, что за собой надо чистить.

procedure TForm1.FormDestroy(Sender: TObject);
begin
  sldb.Free;
end;

Теперь научимся добавлять записи. Ставим кнопку с заголовком "Create records" ("Создать записи") и создадим для неё такой обработчик

procedure TForm1.Button1Click(Sender: TObject);
  const
     n = 100; // сколько записей хотим добавить
  var i: integer;
     t: cardinal; //для подсчёта времени
begin
  t := GetTickCount;
  for i := 0 to n - 1 do
    sldb.ExecSQL('insert into test (t1,t2) values("'+inttostr(random(1000))+'","'+inttostr(random(1000))+'")');
  t := GetTickCount - t;
  ShowMessage(Format('Добавленно %d записей за %d мс',[n,t]));
end;

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

Поставим TMemo, TEdit и кнопку "Select" ("Выбрать"). По нажатию на кнопку будем искать записи в поле T1, которые начинаются на те же цифры, что мы ввели в Edit, и будем их выводить.

procedure TForm1.Button2Click(Sender: TObject);
var sltb:TSQLiteTable;
   i:integer;
begin
  Memo1.Lines.BeginUpdate;
  try
    Memo1.Clear;
    sltb := sldb.GetTable('select t1,t2 from test where t1 like "'+Edit1.Text+'%"');
    try
    for i := 0 to sltb.Count - 1 do
      begin
        Memo1.Lines.Add(sltb.FieldAsString(0)+', '+sltb.FieldAsString(0));
        sltb.Next;
      end;
    finally
      sltb.Free;
    end;
  finally
    Memo1.Lines.EndUpdate;
  end;
end;

Как можно заметить, ничего особенного. Всё очень похоже на то, что доступно в BDE.

А картинки как?

Не знаю почему, но с другими базами добавление картинок для меня – большая трагедия. И если ещё с BDE всё спокойно, то с ADO сплошные приключения :-)

В SQLite есть специальный тип поля – BLOB (он есть и во многих других БД).

Итак, общий алгоритм добавления бинарных данных в базу:

- Добавить запись с помощью INSERT. Но не включать бинарное поле (BLOB).

- Узнать ID добавленной записи (есть специальный метод у TSQLiteDatabase – GetLastInsertRowID – возвращает значение последнего добавленного автоинкрементого поля. Его имя не обязано быть ID. Важно только наличие)

- С помощью UPDATE обновить данное поле, добавив к нему изображение/BLOB (для этого опять же есть метод UpdateBlob. Он принимает два параметра. Первый – сиквел-выражение вида "UPDATE моя_таблица SET поле_блоба = ? WHERE поле_id = сохранённый_id". Надо только заполнить по шаблону 4 слова. Второй параметр – подготовленные в TStream данные. Например, var f: TFileStream; … f := TFileStream.Create('FileName',fmOpenRead));.

Саму реализацию оставляю как домашнее задание :-)

Результаты

Всего несколько строк, а имеем сколько преимуществ. На этом движке я построил несколько приложений, используя его для хранения информации. По субъективным ощущениям работает база в несколько раз быстрей, чем аналогичная на Access. Приложение при старте запускается моментально, ведь ему не надо инициализировать COM-объекты.

Пробуйте, дерзайте, экспериментируйте!

Файлы к статье »

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

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

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

Название
Описание
Раздел
Объём
Ссылки
Symbols Image
Программа для преобразования изображения в текстовый вид.
325 Кб
System Manager
Программа предназначена для управления завершением работы Windows с помощью таймера. Поддерживает 10 действий: выключение, перезагрузка, блокировка компьютера, завершение сеанса Windows, запуск экранной заставки, сон, гибернация, отключение дисплея, запуск и завершение указанной программы. Находится в трее, занимает мало места в оперативной памяти, не нагружает систему. Поддерживается режим Drag&Drop.
316 Кб
ScreenShot
Программа для создания скриншотов. Перед работой вы можете выбрать формат картинки - BMP, JPG и PNG, назначить кнопку при нажатии на которую изображение будет фиксироваться, выбрать папку для сохранения, конвертировать изображения (целую папку) из одного формата в другой, а также заказать программе снятие картинок через промежуток времени, например каждые 5 секунд.
644 Кб
vtkExport
Библиотека, предназначенная для экспорта данных из Ваших программ в форматы Excel и HTML.
Формирование XLS файла происходит без использования DDE, OLE, т.е. для того, чтобы получить XLS-файл, не обязательно, чтобы на компьютере был установлен Excel.
Метод экспорта очень прост - Вы формируете объект TvteXLSWorkBook, который имеет свойства и методы схожие со свойствами и методами OLE сервера Excel и вызываете у него метод SaveAsXLSToFile или SaveAsHTMLToFile.
753 Кб
USB Disk Info
Программа показывает информацию у подключенных USB устройствах. Выводится идентификатор для USB устройств хранения (USB Storage Devices).
13 Кб
MP3 Player с поддержкой скинов
MP3-Player c поддержкой скинов. Также можно изменять громкость.
1.46 Мб
File Unfreezer
Если какая-то программа открывает файл с помощью CreateFile, в зависимости от параметров,она может блокировать доступ к этому файлу других программ. Иногда полезно узнать какая именно программа использует файл - именно это делает данный проект.
34 Кб
Fonts & ComboBox
Программа, демонстрирующая, как вывести список установленных шрифтов в ComboBox.
209 Кб
SQLite
Файлы к статье "Знакомство с SQLite": SQLite Database Browser, компоненты и модули для работы с БД, пример, рассмотренный в статье.
2.39 Мб
 
Всего новых файлов: 9  
6.14 Мб
 
 

Юмор

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

Чайники веб-дизайна (часть II)

К сожалению, опыты по дрессировке чайника и его использованию в качестве рабочего животного пока не привели к положительным результатам. Хотя чайник и способен следовать формальным критериям (в случае подкормки), для работы по структурной разметке он не пригоден, так как не осознает структуры документа. Эксперимент показал, что наиболее сообразительные чайники в принципе способны проверять свой документ валидатором и с нескольких попыток добиваться полной синтаксической грамотности, однако ни о какой структурной грамотности речи идти не может. В частности, чайники применяют тэги заголовков (например, <H5>) для выделения (вместо <STRONG>), а списки организуют не с помощью тэгов списков, а посредством перевода строк тэгом <BR> и ручной расстановкой маркеров списка. Это происходит из-за того, что чайники, не способные понять структуры и тем более - смысла текста в опытном документе, стремятся скопировать единственное, что понимают, - внешний вид документа в известных им браузерах.

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

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

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

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

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

Вместе с тем, если начать обеспечивать чайника подкормкой за действия, которые раньше были для него «бесполезными», он переключается на эти действия и заставляет других делать то же самое, несмотря на то, что раньше относился к подобным действиям других с агрессией. Hапример, отмечались случаи, когда чайник, ранее агрессивно относящийся к указанию в документе, после подкормки начал использовать по 2-3 в каждой работе и принуждать к этому других чайников. Это еще одно подтверждение того, что для чайника не свойственны моральные соображения и прочие человеческие качества; вся его деятельность обусловлена исключительно условными рефлексами, опирающимися на подкормку.

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

1. Hе обманывайтесь внешним сходством чайника и человека. Помните, что чайник подобен попугаю, повторяющему человеческую речь. Он не способен к осмыслению и пониманию; вся его деятельность - только подражание. Hа чайника нельзя обижаться, как нельзя обижаться на домашних животных.

2. Hе выражайте своего несогласия с чайником. Так как чайник не осознает того, что говорит и делает, смысл вашего несогласия останется для него непонятным. Он поймет только то, что чем-то вас не устраивает, а это, как отмечалось выше, является поводом для агрессии и может привести к облаиванию и даже покусанию. Спорить с чайником не более разумно, чем с попугаем или телефонным роботом, сообщающим точное время.

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

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

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

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

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

:))

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




Ведущий рассылки: Ерёмин Андрей


В избранное