Целью данной статьи было не просто написание программного обеспечения, альтернативы которому имеются во множестве, а описание хода работы над данным ПО, рассмотрение возможностей INDY-компонентов Дельфи: idHTTP и idSMTP, и примеры осуществления некоторых функций (ping, HostToIp и пр.). Таким образом, это своего рода учебное пособие по созданию приложений такого типа, работе с Дельфи и вышеперечисленными компонентами. Исходные коды и готовое приложение здесь. Статья рассчитана на читателей, освоивших азы программирования на Паскале, уже умеющих создавать на Дельфи простые оконные приложения (Hello world). Некоторые термины, применяемые здесь, могут показаться непонятными: INDY – Internet Dyrect, набор компонентов для Дельфи, ориентированный преимущественно на работу с сетевыми функциями. idHTTP – INDY компонент для клиентской работы с протоколом HTTP. idSMTP – INDY компонент для отправки электронной почты по протоколу SMTP. ПО «Simple Internet Browser» (далее SIB) должно обладать следующими возможностями: загрузка только исходного кода html-страниц, установка произвольных параметров http-request, поиск гиперссылок в загруженном коде и вывод их пользователю, определение свойств веб-страницы и её сервера (тип сервера, его ИП, пинг, размер страницы, кодировка и проч.), печать и изменение шрифта отображаемого кода, пинг любого указанного узла, получение информации о узле со WhoIs сервиса, выяснение ИП по имени и наоборот, отправка почты. Итак, с чего начинается написание такого приложения на Дельфи, учитывая что все нужные книги прочитаны, нужные исходники найдены? Как и всегда – с создания первой формы. Назовём её MForm, и соответственно у нас сразу появиться новый класс TMForm. Далее установим параметры формы. Сделаем так, чтобы форма появлялась по центру экрана (position - poDesktopCenter), зададим текст для шапки формы (Caption - Simple Internet Browser 1.0) и растянем форму так, чтобы на экране она нормально смотрелась. Сохраним, дав имя MainUnit pas-файлу. Вот форма и готова. Берём и ищем на вкладке Standart (там где компоненты) MainMenu, кликаем и ложим на форму. Далее, кликая уже по нему, создаём главное меню такого вида: Файл, Правка, Вид, Сервис, Справка. В «Файл» подменю: Открыть, Сохранить как, Печать, Свойства и Закрыть. В «Правка»: Копировать и Выделить всё. В «Вид»: Ссылки из html, Обновить, Переход, Шрифт, Во MSIE. В «Сервис»: Свойства SIB, Свойства MSIE, Утилиты (Пинг узла, Отправка почты, Host to IP to Host). В «Справка» - О программе. Все эти пункты меню будут позволять использовать функционал программы, и уже сразу видно, как много ещё предстоит сделать. Куда будет загружаться исходный код страниц? В простой компонент Memo, для которого укажем отображение во весь клиентский экран, независимо от его размера (align - alClient). И запретим изменение текста в нём (Readonly - true) и добавим полосы прокрутки (ScrollBars - ssBoth). Теперь добавим строку ввода текста (ComboBox) и кнопку (SpeedButton). Чтобы они выглядели нормально вместе с Memo, поставим их не на форму, а на Panel c align – alTop, BevelOuter – bvNone. Для ComboBox укажем Anchors - [akLeft,akTop,akRight,akBottom], а для SpeedButton Anchors - [akTop,akRight,akBottom] и Caption – Переход. На этом оформление формы MForm завершено. Поставим на неё ещё только компоненты, нужные для работы далее: OpenDialog (DefaultExt – htm, Filter - Веб-страницы|*.htm |Все файлы|*.*), SaveDialog (DefaultExt – htm, Filter - Веб-страницы|*.htm |Все файлы|*.*),), FontDialog, Timer (Interval - 500), PrintDialog, idHTTP, IdAntiFreeze (нужен для того, чтобы форма была доступна во время работы прочик компонентов INDY) и Memo2 на Panel2 со свойством Visible – false. Создадим ещё одну форму с названием SibProp и параметром BorderStyle – bsDialog. Эта форма для настроек параметров SIB – request и proxy. Учитывая, что для прокси нужно указывать имя сервера и порт, а ещё иногда имя пользователя и пароль, создадим на форме 4 соответствующих поля ввода и два переключателя типа CheckBox. А у структуры request у idHTTP 26 параметров. Для этого ставим ещё 25 полей ввода и CheckBox (один из параметров логический). Добавляем кнопки «закрыть» и «Применить». Создадим третью форму HIForm такого же типа, как вторую. Эта форма для использования функций HostToIP, IPToHost и получения инфомации WhoIs. Следовательно понадобиться 4 поля ввода, две кнопки к ним, а ещё кнопка Whois и закрытия диалогового окна. В четвёртой, подобной же, форме PingF нужно создать всё для функции Ping. Это два поля ввода, кнопка «Пинг» и кнопка «Закрыть». Пятая форма – это форма свойств загруженной страницы. Должна быть всегда на переднем плане, т.к. будет вызываться как Prop.Show, а не Prop.ShowModal. Должна содержать 13 Label’ов для надписей: Серверные параметры, URL, Тип сервера, Хост, Пинг, Код ответа сервера, IP, Параметры страницы, Размер документа, Кодировка, Язык, ContentType, Количество ссылок. К каждой надписи (кроме Серверные параметры, Параметры страницы, URL и Тип сервера) создаём ещё по одному Label для собственно данных. Для URL и Тип сервера создаём по Edit’у с Readonly – true, (чтобы можно было выделять и копировать). И добавляем кнопку «Закрыть». Шестая форма LinkF нужна для отображения списка доступных ссылок из кода веб-страниц. Тут следует применить компонент ListBox с параметрами Align – alClient. А ещё добавляем меню PopupMenu для ListBox с пунктами: Копировать, Перейти, Открыть в MSIE, Автопоказ списка (меню типа CheckBox). Седьмую форму я добавлял из мной ранее сделанной программы для отправки почты, где есть 9 полей ввода, Memo, OpenDialog и три кнопки. Схема связей форм: Формы связываются между собой указанием имени модуля формы в Uses после interface и Uses после implementation. Для отображения формы она вызывается командой Show. Если форма должна отображаться без возможности передачи фокуса на форму, из которой вызвана, то ShowModal. Обращаться к элементам формы можно только после её создания. В коде модулей можно найти описание каждой процедуры или функции, поэтому описывать их и здесь будет излишне. Остановлюсь лишь на некоторых важных моментах и также опишу процесс функционирования кратко, в целом. Функционирование приложения. Вводим в строку ввода текст tut.by и нажимаем на ввод. Что при этом происходит: Если введённая строка введена не из списка ComboBox, то проверка, не пуста ли она и добавление в ComboBox, далее вырезка всех пробелов в строке (если они там есть), добавление префикса протокола http:// (если нету), далее загрузка в Memo1 данных посредством idHttp (memo1.Text := idhttp1.Get ( 'http://' + CutPref (ComboBox1.Text) )), далее показ окна для ссылок (если это включено), затем запись последнего введённого адреса в переменную для старых адресов с удалением из неё http://, далее поиск в Memo1 ссылок и после поиска обновление ими ListBox в окне для ссылок. Компонент idHTTP. Содержит две, довольно важных структуры: Response и Request. Заполнение структуры Request можно увидеть в исходниках и готовом приложении. Там можно задать такие параметры, как авторизацию на сервере (имя пользователя и пароль), UserAgent, Referer (вспомним antichat quest 1). Структура Response даёт нам ответ от сервера после запроса у него странички, например можно в ней взять код (описание здесь: http://forum.antichat.ru/showpost.php?p=207299&postcount=1) ответа сервера (idhttp1.Response.ResponseCode). Помимо сего idHTTP может работать с прокси, что в SIB можно задать в Свойствах SIB. Процедура TMForm.SearchLinks; Служит для поиска в html коде гиперссылок. Поиск происходит так: вначале определяется длина всей строки кода, затем происходит посимвольный анализ. Со строкой href=" сравнивается по 6 символов, при каждом цикле со смещением на один. Если такая строка обнаружена, то все символы после неё копируются в новую строку вплоть до обнаружения символа " , а после строка обрабатывается функцией конвертации относительного пути в постоянный (если задан относительный) и добавляется в ListBox. И так, пока не будут обработаны все символы. Процедура TMForm.RunLink(lnk:string;spec:boolean); Создаёт/заменяет и открывает на запись файл в папке для временных файлов. Принимает строковые данные и логический параметр. Если параметр true, то строка просто записывается в файл, иначе строка записывается посреди html-обрамления инициирующего переход по этой строке-ссылке при загрузке файла в браузере. Загрузка затем и происходит путём запуска explorer с передачей ему в качестве параметра пути к данному файлу. Можно было обойтись и без файла, но увы, корректно передать в качестве параметра explorer’у можно далеко не все веб-адреса. Процедура SendMail (MailText: TStrings; SendDate, SenderName, SenderAddress, RecAddress, RecServer, MailTheme, Attach, AuthUser, AuthPass: string; IsAttach, IsAuth: boolean); Осуществляет отправку почты через SMTP компонент idSMTP, а также idMessage, IdAttachment. Вначале создаётся idSMTP1, затем указывается порт, сервер. Происходит соединение, при успехе коего авторизуемся, если нужно, далее – создаём TIdMessage, указываем тему письма, адреса отправителя и принимающего, имя отправителя, текст письма, дату, если нужно производим IdAttachment. После отправляем (idSMTP1.Send(Msg)) и освобождаем память (Free). Визуально здесь компонентов INDY не используем (на форме нет кнопочек, как с idHTTP). При работе над ПО SIB использовалась среда разработки Дельфи 7.0. Для придания SIB завершённого вида использовался редактор ресурсов Restorator 3.51, программа-редактор изображений ArtIcons 4.06, упаковщик исполняемых файлов UPX 1.95. Весь код данного ПО, кроме автокода модулей Дельфи и некоторых функций был написан автором. Функции, код которых был взят из сторонних источников следующие: HostToIP(Name: PChar):string; IPToHost(IPChar):string; PingAddress(hostnameChar):integer. Данная статья и ПО были созданы в учебных целях, специально для forum.antichat.ru. На данной стадии ни она сама, ни ПО на звание завершённого продукта не претендуют. ПО и его исходные коды можно использовать абсолютно свободно, не забывая лишь про автора. Статью можно дополнять, переопубликовывать, ссылаясь на первоисточник. Критика желательна и ожидаема. По малозначимым вопросам обращаться к автору в ПМ. ________________ Вот ещё, как важное (и думаю нужное) дополнение к статье - литература по INDY: Indy Knowlege Base Книга "Глубины ИНДИ", 514 Кб
А я помню, тоже "свой" браузер написал на делфи... только изнутри он почему-то имел все те же дыры, что и Ie... да и определялся тоже как эксплорер... хрен его знает почему)
Дак можно просто сделать как-бы свой браузер на основе ActiveX-компонента MSIE, что обычно и делается. А я здесь сделал не на основе ActiveX MSIE, а используя INDY. То есть я просто получаю html-код странички в окно, а затем произвожу поиск и сбор ссылок на этой страничке с отдельным выводом. Хотя, может в будующем, это перерастёт в более основательную разработку, где будет анализ не только для гиперссылок, но и для большинства html-тегов. PS: http://forum.vingrad.ru/topic-137141.html - nerezus, большое спасибо, это несколько изменило мои планы в отношении дальнейшей разработки браузера.