Данная статья писалась в далекие времена, когда основным моим увлечением было программирование, а не медицина. Не знаю насколько она актуальна в настоящее время, однако думаю польза от нее будет. Во-первых, как небольшое руководство для начинающих. Во-вторых, как дополнительный источник трафика на наш сайт :).
Для того что бы использовать элемент управления WebBrowser в своей программе, вам необходимо подключить к проекту файл shdocvw.dll. Для этого выберите меню Project / Components, а затем поставьте галочку напротив "Microsoft Internet Controls". Также необходимо подключить библиотеку Microsoft HTML Object Library, через которую мы будем осуществлять взаимодействие с элементом управления WebBrowser. Для этого выберите меню Project / References и отметьте "Microsoft HTML Object Library" соответствующий файлу mshtml.tlb. Кроме этого от вас потребуется хотя бы минимальное знание HTML и CSS.
Основные области применения элемента управления WebBrowser в приложении:
В этой статье мы рассмотрим пример использования элемента управления WebBrowser в качестве интерфейса программы, а так же в качестве генератора отчёта. Для этого мы напишем программу, которая будет отображать в виде таблицы информацию из базы данных. При этом будет реализована возможность просмотра отчёта и его печати, а так же возможность смены стиля оформления.
Допустим, у нас имеется некая база данных c именем "db". В нашем случае это база данных Microsoft Access "db.mdb", в ней есть таблица с именем "people", в которой хранится список контактов.
Структура этой таблицы следующая:
Имя поля -- Тип данных:
id_people -- Счётчик
Surname -- Текстовый
Name -- Текстовый
PName -- Текстовый
City -- Текстовый
Address -- Текстовый
Telephone -- Текстовый
Нашей задачей будет вывести в виде таблицы все фамилии, и при щелчке по ячейке с фамилией, отобразить таблицу с полной информацией по данному человеку, а так же кнопки для перехода назад, просмотра отчёта и его печати.
Для этого нам необходимо создать два HTML-документа. Первый, в котором будет отображаться список фамилий, назовём "people.html".
Вот его HTML-код:
Разобраться в этом коде не составит труда, единственное, что может остаться непонятным – это тэг
Второй HTML-документ, в котором будет отображаться подробная информация о определённом человеке, назовём его "people_info.html", будет иметь следующий HTML-код:
Таблица с id="people_info" не имеет ни одной ячейки, т.к. все они будут добавлены из нашей программы.
Необходимо отметить, что в Windows XP, для того чтобы в HTML-документе, который вы выводите через WebBrowser, все элементы управления (кнопки, списки, текстовые поля и т.д.) отображались в стиле XP, необходимо в секцию добавить следующий мета-тэг
, а для того, что бы отключить стиль XP, .Теперь нам необходимо создать файл style_1.css, в котором мы опишем стиль наших html-документов. Перед вами листинг этого файла:
Хотелось бы отметить строку body {background-color:buttonface; border:none}. Значение buttonface – это значение системного цвета, который используется для свойства BackColor формы. Таким образом, WebBrowser при любой цветовой схеме не будет выделяться на форме. Запись border:none скрывает границу при отображении документа с этим стилем в элементе управления WebBrowser. Остальные строки не должны вызвать особых затруднений.
Таких файлов можно создать сколь угодно много, описав в них различные стили оформления, которые можно будет применить к программе. Мы же создадим ещё один файл style_2.css. Примем первый стиль за «Классический», второй за «Современный».
Целесообразность использования нескольких стилей оформления может быть продиктована тем, что ваша программа может запускаться на разных операционных системах, имеющих различное графическое оформление. При этом цвета, используемые в оформлении вашей программы могут абсолютно не сочетаться с цветовым оформлением операционной системы. Вы сможете убедиться в этом на примере нашей программы, так как для Windows 9x больше подходит «Классический» стиль, а для XP - «Современный».
Все файлы, только что созданные нами, мы будем хранить в виде ресурсов, внутри исполняемого файла. Конечно, их можно было бы поместить в папку, в которой располагается программа или же в отдельную директорию, но это может создать лишние проблемы, так как если один из файлов будет по какой-либо причине удалён, программа не будет корректно работать.
Данные, загружаемые из ресурсов должны находиться в разделе «HTML». Для создания файла ресурса создадим файл htmlRes.rc следующего содержания:
Теперь нам необходимо создать файл ресурсов htmlRed.res. Для упрощения процесса, создадим в этой же папке файл makeRes.bat с таким содержанием: "C:Program FilesMicrosoft Visual StudioVB98WizardsRC.EXE" /r /fo htmlRes.res htmlRes.rc
Теперь, после того, как вы запустите файл makeRes.bat, в этой же директории будет создан файл htmlRes.res, который вам надо будет подключить к проекту.
Если файл ресурсов не создался, проверьте правильность пути к утилите rc.exe в файле makeRes.bat, а так же наличие всех файлов, указанных в htmlRes.rc – если хотя бы один из них будет отсутствовать, файл ресурсов не будет создан.
Создайте новый проект. Подключите необходимые библиотеки (см. «Вступление»), кроме того подключите Microsoft DAO 3.6 Object Library, необходимую для работы с базой данных. После этого добавьте элемент управления WebBrowser на форму и установите в качестве его свойства Name – «WebBrowser».
Сначала объявим все необходимые нам переменные:
Объявления WithEvents необходимы для того, что бы мы смогли получать и обрабатывать события соответствующего класса.
Так же необходимо пояснить отличие класса HTMLDocument от IHTMLDocument. Класс HTMLDocument – это функциональный эквивалент объекту document, используемому в скриптах внутри HTML-страниц, он предоставляет все свойства и методы, необходимые для доступа к содержимому активного документа. Если же в программе используется раннее связывание с объектом HTMLDocument, то сослаться на него можно, используя интерфейсы IHTMLDocument, IHTMLDocument2 и IHTMLDocument3.
При загрузке формы нам необходимо выровнять на ней WebBrowser, соединиться с базой данных и вывести список фамилий.
В нашей программе будет предусмотрена возможность просмотра и печати отчёта. При этом внешний вид документа будет зависеть от настроек InternetExplorer’а, которые храняться в реестре. Так, например, если вы будете использовать вывод картинок в WebBrowser, вам необходимо будет включить их отображение. Для этого необходимо будет сделать соответствующие изменения в реестре. Главное, не забывайте восстанавливать прежние значения после завершения работы программы. В нашей программе мы отключим так называемые «footer» и «header» - подписи вверху и внизу страницы, а так же включим вывод на печать фона страницы. Большинство настроек находится в разделах реестра: HKEY_CURRENT_USERSoftwareMicrosoftInternet ExplorerMain, HKEY_CURRENT_USERSoftwareMicrosoftInternet ExplorerPageSetup, поэтому будет полезно вооружиться редактором реестра и уделить некоторое время изучению содержания данных разделов.
Однако, если вы используете такой способ решения этой проблемы, то учтите, что, если пользователь одновременно с вашей программой запустит InternetExplorer, то он очень удивится... Существует более красивый способ решения, но пока он не реализован автором этой статьи...
Сразу же напишем процедуру, которая будет восстанавливать прежние значения параметров реестра:
Получить ссылку на объект внутри документа можно либо по его уникальному идентификатору (mDoc.getElementById(«id») или mDoc.All.id, где id – уникальный идентификатор), либо по имени (mDoc.getElementsByName(«name»), где name – имя элемента), либо по названию тега элемента (mDoc.getElementsByTagName(«tagName»), где tagName – название тега. При этом мы получим массив объектов. Чтобы обратиться к какому-то конкретному элементу этого массива, необходимо указать его индекс – mDoc.getElementsByTagName(«tagName»).Item(Index)).
Теперь создадим процедуру, которая будет добавлять строки из базы данных в таблицу:
Метод insertRow([index as Long=-1]) класса HTMLTable позволяет добавлять строку в таблицу. Единственный необязательный параметр index определяет порядок добавления строки: -1 – новая строка добавляется в конец таблицы, 0 – в начало, 1 – перед строкой, добавленной в последнюю очередь.
Метод insertCell([index as Long=-1]) класса HTMLTableRow добавляет ячейки в строку.
Метод setAtribute(strAttributeName As String, AttributeValue, [lFlags As Long = 1]) позволяет устанавливать для любого атрибута, заданного в strAttributeName, любое значение, заданное в AttributeValue. При этом можно устанавливать значения существующих атрибутов, а так же создавать новые, как и показано в нашем примере. Атрибут «Pos» со значением, равным порядковому номеру добавляемой строки, нам будет необходим для того, чтобы определить по какой строке произошёл щелчок мыши. Это нам необходимо, чтобы узнать, информацию о каком человеке необходимо отобразить.
Свойство innerHTML определяет HTML-код внутри определённого объекта.
Для того, чтобы пользователь мог изменять стиль оформления, создадим меню «Стиль» с пунктами «Классический» и «Современный». Дадим им соответствующие имена – mnuStyleClassic и mnuStyleModern. Процедуры выбора пунктов меню будут следующими:
Непосредственно изменять стиль оформления будет процедура ActivateStyle:
Таким образом, при загрузке формы у нас будет появляться таблица со списком фамилий. При этом она всегда будет позиционироваться по центру, независимо от изменения размера формы. Если таблица выйдет за пределы формы автоматически появятся полосы прокрутки.
Чтобы скрыть полосы прокрутки используйте код mDoc.body.Style.overflow = "hidden" или определите в каскадно-стилевых таблицах: body {overflow:hidden}, либо для горизонтальной или вертикально полос отдельно – body {overflow-x:hidden} или body {overflow-y:hidden} соответственно.
Теперь нам необходимо сделать так, чтобы при наведении курсора на ячейку с фамилией, менялся её цвет и тип курсора. Основная работа нами уже сделана – стиль ячейки, на которую наведён курсор уже описан (см. листинг файла style_1.css, стиль для класса second_col_on), осталось только зафиксировать наведение курсора на ячейку и изменить её класс с second_col на second_col_on и обратно, когда курсор уйдёт за пределы ячейки.
Для того чтобы получить элемент документа, к которому относится событие необходимо обратиться к объекту Event следующим образом: mDoc.parentWindow.Event.srcElement. Затем нам надо будет убедиться, является ли этот элемент ячейкой таблицы, в которой содержится фамилия, для этого мы проверим наличие атрибута Pos (который есть только у этих ячеек). Если он окажется, то изменим имя класса этой ячейки. Затем аналогичным образом изменим имя класса ячейки на первоначальное. Таким образом нам надо будет обрабатывать события onmouseover и onmouseout:
Таким же образом обработаем событие onclick. Только теперь нам надо будет не изменить имя класса для элемента, а получить значение атрибута «Pos», для того, чтобы вывести информацию по конкретному человеку. Это реализуется в следующей процедуре:
Затем значение атрибута «Pos» передаётся в процедуру отображения информации по конкретному человеку:
С помощью кода:
Set btnBack = mDoc.All.btnBack
Set btnPreview = mDoc.All.btnPreview
Set btnPrint = mDoc.All.btnPrint
мы получаем ссылки на три кнопки, а так как экземпляры btnBack, btnPreview и btnPrint класса HTMLButtonElement объявлены у нас WithEvents, то мы легко можем обрабатывать их события.
При нажатии на кнопку btnBack, мы снова загружаем список фамилий:
При нажатии на кнопку btnPreview, мы откроем стандартное окно Предварительного просмотра страницы:
Чтобы в отчёте не было трёх кнопок, их необходимо сначала спрятать, а затем снова отобразить. Для этого используются две соответственные процедуры HideButton и ShowButton:
Так как мы разрешили печать фона документа, то нам необходимо не только скрыть кнопки, но и изменить цвет фона на белый, а затем восстановить исходные значения.
Печать отчёта будет осуществляться при нажатии кнопки btnPrint:
Теперь необходимо позаботиться о надёжности приложения. Нам необходимо запретить WebBrowser’у реагировать на нажатие клавиш, так как последствия их нажатия могут быть для нас нежелательны (например нажатие F5 приведёт к обновлению страницы, в результате чего всё содержимое её будет потеряно). Для этого создадим следующую процедуру:
Таким образом, при нажатии любой клавиши, будет возвращён keyCode, равный 0, следовательно никакой реакции со стороны WebBrowser не последует.
Кроме того вы можете в зависимости от возвращённого keyCode, т.е. в зависимости от того какая клавиша была нажата, производить определённые действия в вашей программе.
Кроме этого может возникнуть необходимость запрета вызова контекстного меню WebBrowser’а, это осуществляется при помощи следующего кода:
Аналогично можно запретить выделение в документе:
По завершению работы программы нам необходимо закрыть соединение с базой данных и восстановить прежние значения реестра:
Спасибо всем, кто осилил. Кто не выдержал -- может скачать пример и разобраться на досуге.