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

Вступление

Для того что бы использовать элемент управления 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 в качестве интерфейса программы (Возможности WebBrowser, как контейнера для других элементов значительно превосходят возможности стандартной формы. Помимо привычного абсолютного позиционирования, когда задаются чёткие координаты, есть возможность использовать относительное, когда размещение элемента зависит от размеров других. Это очень важное свойство, позволяющее реализовать автоматическое изменение размеров (и при необходимости расположения) элементов формы при изменении размеров окна. При этом вы можете обрабатывать события HTML-документа, как обычно, - внутри самого документа, используя скрипты на языках VBScript или JavaScript, кроме того у вас появляется возможность делать это из программы на VB. Использование каскадно-стилевых таблиц позволяет легко менять стиль оформления интерфейса приложения. Использование DHTML позволит применять различные графические фильтры к графике в вашей программе)
  • Генератор отчётов (Альтернатива Crystal Reports и ему подобным генераторам отчётов)
  • Просмотр файлов различных форматов (как альтернатива OLE Container)

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

Перед тем как начать

Допустим, у нас имеется некая база данных c именем "db". В нашем случае это база данных Microsoft Access "db.mdb", в ней есть таблица с именем "people", в которой хранится список контактов.

Структура этой таблицы следующая:

Имя поля -- Тип данных:

id_people -- Счётчик

Surname -- Текстовый

Name -- Текстовый

PName -- Текстовый

City -- Текстовый

Address -- Текстовый

Telephone -- Текстовый

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

Для этого нам необходимо создать два HTML-документа. Первый, в котором будет отображаться список фамилий, назовём "people.html".

Вот его HTML-код:

<base />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />

    <link rel="stylesheet" href="/style_1.css" type="text/css" />

<table class="bg" cellspacing="0 cellpadding=0 align=center">
    <tbody>
        <tr>
            <td>
                <table cellspacing="1 cellpadding=4 width=310 id=people">
                    <tbody>
                        <tr>
                            <td class="number">№</td>
                            <td class="surname">Фамилия</td>
                        </tr>
                    </tbody>
                </table>
            </td>
        </tr>
    </tbody>
</table>

 

Разобраться в этом коде не составит труда, единственное, что может остаться непонятным – это тэг . В HTML ссылки на внешние изображения, апплеты, программы для обработки форм, таблицы стилей и т.д. всегда задаются с помощью URI. Относительные URI разрешаются в соответствии с базовым URI, который может определяться из различных источников. Элемент "base" позволяет явно указать базовый URI документа. Необходимость его использования в нашем случае вы поймёте чуть позже.

Второй HTML-документ, в котором будет отображаться подробная информация о определённом человеке, назовём его "people_info.html", будет иметь следующий HTML-код:

<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />

    <link rel="stylesheet" href="/style_1.css" type="text/css" />

<table class="bg" cellspacing="0 cellpadding=0 align=center">
    <tbody>
        <tr>
            <td>

                <table cellspacing="1 cellpadding=4 width=310 id=people_info">
                </table>
            </td>
        </tr>
    </tbody>
</table>
<table>
    <tbody>
        <tr>
            <td align="center">
 <input value="Назад" id="btnBack" class="button" type="button" />
 <input value="Предпросмотр" id="btnPreview" class="button" type="button" />
 <input value="Печать" id="btnPrint" class="button" type="button" /></td>
        </tr>
    </tbody>
</table>

 

Таблица с id="people_info" не имеет ни одной ячейки, т.к. все они будут добавлены из нашей программы.

Необходимо отметить, что в Windows XP, для того чтобы в HTML-документе, который вы выводите через WebBrowser, все элементы управления (кнопки, списки, текстовые поля и т.д.) отображались в стиле XP, необходимо в секцию добавить следующий мета-тэг

    <meta http-equiv="MSThemeCompatible" content="Yes" />
    
, а для того, что бы отключить стиль XP,
    <meta http-equiv="MSThemeCompatible" content="No" />
    
.

Теперь нам необходимо создать файл style_1.css, в котором мы опишем стиль наших html-документов. Перед вами листинг этого файла:

body {background-color:buttonface;border:none}
table.bg {background-color:#000000; margin-bottom:5}
td.number{background-color:#656ECA; width:20; font-family:Tahoma; font-size:12; font-weight:bold; color:#ffffff; text-align:center}
td.surname {background-color:#747FE9; width:290; font-family:Tahoma; font-size:12; font-weight:bold; color:#ffffff; text-align:center}
td.first_col {background-color:#bbbbbb; font-family:Tahoma; font-size:12}
td.second_col {background-color:#cdcdcd; font-family:Tahoma; font-size:12; color:#555555}
td.second_col_on {background-color:#bbbbbb; font-family:Tahoma; font-size:12; cursor:pointer}
input.button{font-family:Tahoma; font-size:12; color:#555555; width:100; cursor:pointer;border: solid 1 #000000; background-color:#cdcdcd}
input.button_on{font-family:Tahoma; font-size:12; width:100; cursor:pointer;border: solid 1 #000000; background-color:#bbbbbb}

Хотелось бы отметить строку body {background-color:buttonface; border:none}. Значение buttonface – это значение системного цвета, который используется для свойства BackColor формы. Таким образом, WebBrowser при любой цветовой схеме не будет выделяться на форме. Запись border:none скрывает границу при отображении документа с этим стилем в элементе управления WebBrowser. Остальные строки не должны вызвать особых затруднений.

Таких файлов можно создать сколь угодно много, описав в них различные стили оформления, которые можно будет применить к программе. Мы же создадим ещё один файл style_2.css. Примем первый стиль за «Классический», второй за «Современный».

Целесообразность использования нескольких стилей оформления может быть продиктована тем, что ваша программа может запускаться на разных операционных системах, имеющих различное графическое оформление. При этом цвета, используемые в оформлении вашей программы могут абсолютно не сочетаться с цветовым оформлением операционной системы. Вы сможете убедиться в этом на примере нашей программы, так как для Windows 9x больше подходит «Классический» стиль, а для XP - «Современный».

Создание файла ресурсов

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

Данные, загружаемые из ресурсов должны находиться в разделе «HTML». Для создания файла ресурса создадим файл htmlRes.rc следующего содержания:

#define RT_HTML 23

people.html RT_HTML "people.html"
people_info.html RT_HTML "people_info.html"
style_1.css RT_HTML "style_1.css"
style_2.css RT_HTML "style_2.css"

Теперь нам необходимо создать файл ресурсов 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».

Сначала объявим все необходимые нам переменные:

Private WithEvents mDoc As HTMLDocument
Private mIDoc As IHTMLDocument
Private mTable As HTMLTable
Private mTR As HTMLTableRow
Private mTD As HTMLTableCell
Private mIElement As IHTMLElement
Private WithEvents btnBack As HTMLButtonElement
Private WithEvents btnPrint As HTMLButtonElement
Private WithEvents btnPreview As HTMLButtonElement

Private mReg As Object

Private dbPeople As Database
Private strQuery As String
Private recPeople As Recordset

Private Type REGSETTINGS
 footer As String
 header As String
 Print_Background As String
End Type

Private strRegSettings As REGSETTINGS

Private isInfo As Boolean
Private strHTML As String

Объявления WithEvents необходимы для того, что бы мы смогли получать и обрабатывать события соответствующего класса.

Так же необходимо пояснить отличие класса HTMLDocument от IHTMLDocument. Класс HTMLDocument – это функциональный эквивалент объекту document, используемому в скриптах внутри HTML-страниц, он предоставляет все свойства и методы, необходимые для доступа к содержимому активного документа. Если же в программе используется раннее связывание с объектом HTMLDocument, то сослаться на него можно, используя интерфейсы IHTMLDocument, IHTMLDocument2 и IHTMLDocument3.

При загрузке формы нам необходимо выровнять на ней WebBrowser, соединиться с базой данных и вывести список фамилий.

В нашей программе будет предусмотрена возможность просмотра и печати отчёта. При этом внешний вид документа будет зависеть от настроек InternetExplorer’а, которые храняться в реестре. Так, например, если вы будете использовать вывод картинок в WebBrowser, вам необходимо будет включить их отображение. Для этого необходимо будет сделать соответствующие изменения в реестре. Главное, не забывайте восстанавливать прежние значения после завершения работы программы. В нашей программе мы отключим так называемые «footer» и «header» - подписи вверху и внизу страницы, а так же включим вывод на печать фона страницы. Большинство настроек находится в разделах реестра: HKEY_CURRENT_USERSoftwareMicrosoftInternet ExplorerMain, HKEY_CURRENT_USERSoftwareMicrosoftInternet ExplorerPageSetup, поэтому будет полезно вооружиться редактором реестра и уделить некоторое время изучению содержания данных разделов.

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

Private Sub Form_Load()
'позиционируем WebBrowser на форме, таким образом, что 'бы не было видно его границ
 'создаём объект для работы с реестром
 Set mReg = CreateObject("WScript.Shell")
 'далее идут процедуры сохранения старых и установка
'новых значений реестра, а так же процедуры соединения с 'базой данных и вывода списка фамилий
 GetRegSettings
 SetRegSettings
 Connect
 LoadPeople
End Sub

'сохраняем старые значения реестра
Private Sub GetRegSettings()
 With strRegSettings
 .footer = mReg.RegRead("HKCUSoftwareMicrosoftInternet ExplorerPageSetupfooter")
 .header = mReg.RegRead("HKCUSoftwareMicrosoftInternet ExplorerPageSetupheader")
 .Print_Background = mReg.RegRead("HKCUSoftwareMicrosoftInternet ExplorerMainPrint_Background")
 End With
End Sub

'устанавливаем новые значения реестра
Private Sub SetRegSettings()
 With mReg
 .RegWrite "HKCUSoftwareMicrosoftInternet ExplorerPageSetupfooter", "" 'убираем надпись внизу страницы
 .RegWrite "HKCUSoftwareMicrosoftInternet ExplorerPageSetupheader", "" 'убираем надпись вверху страницы
 .RegWrite "HKCUSoftwareMicrosoftInternet ExplorerMainPrint_Background", "yes" 'печатать фон
 End With

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

'восстанавливаем старые значения реестра
Private Sub RestoreRegSettings()
 With mReg
 .RegWrite "HKCUSoftwareMicrosoftInternet ExplorerPageSetupfooter", strRegSettings.footer
 .RegWrite "HKCUSoftwareMicrosoftInternet ExplorerPageSetupheader", strRegSettings.header
 .RegWrite "HKCUSoftwareMicrosoftInternet ExplorerMainPrint_Background", strRegSettings.Print_Background
 End With
End Sub

'устанавливаем соединение с базой данных
Private Sub Connect()
 Set dbPeople = OpenDatabase("db.mdb")
'запрос на получение всех записей отсортированных по
'значениям столбца Surname
 strQuery = "SELECT * FROM people ORDER BY Surname ASC"
'Теперь recPeople содержит все записи из таблицы
 Set recPeople = dbPeople.OpenRecordset(strQuery)
End Sub

'выводим список фамилий в таблицу в WebBrowser
Private Sub LoadPeople()
'загружаем пустую страницу
 WebBrowser.Navigate "res://mshtml.dll/blank.htm"
'ждём полной загрузки страницы
 While WebBrowser.ReadyState READYSTATE_COMPLETE
 DoEvents
 Wend
'присваиваем ссылки на объект WebBrowser.Document
 Set mDoc = WebBrowser.Document
 Set mIDoc = WebBrowser.Document
'извлекаем HTML-код страницы people.html из ресурсов
 strHTML = StrConv(LoadResData("people.html", 23), vbUnicode)
'записываем HTML-код в наш документ
 mIDoc.write strHTML
'изменяем базовый URI (см.выше) для корректного отображения страницы
 mIDoc.getElementsByTagName("BASE").Item(0).href = _
 "res://" & App.Path & "" & App.EXEName & ".exe"
'Активируем текущий стиль оформления
 ActivateStyle
'Получаем ссылку на таблицу, id которой равен «people»,
'для дальнейшей работы с этой таблицей (добавление 'строк, обеспечение её интерактивности) Set mTable = mDoc.All.people
'добавляем строки в таблицу (процедура будет рассмотрена 'ниже)
 AddRows
'Переменная, сообщающая нам, что сейчас отображается 'список фамилий, а не информация по конкретному человеку
 isInfo = False
End Sub

Получить ссылку на объект внутри документа можно либо по его уникальному идентификатору (mDoc.getElementById(«id») или mDoc.All.id, где id – уникальный идентификатор), либо по имени (mDoc.getElementsByName(«name»), где name – имя элемента), либо по названию тега элемента (mDoc.getElementsByTagName(«tagName»), где tagName – название тега. При этом мы получим массив объектов. Чтобы обратиться к какому-то конкретному элементу этого массива, необходимо указать его индекс – mDoc.getElementsByTagName(«tagName»).Item(Index)).

Теперь создадим процедуру, которая будет добавлять строки из базы данных в таблицу:

Private Sub AddRows()
Dim lngNumber As Long 'порядковый номер добавляемой строки
 recPeople.MoveFirst 'переходим на начало записи
 lngNumber = 1
'последовательно добавляем строки
 While Not recPeople.EOF
 Set mTR = mTable.insertRow(-1)
 Set mTD = mTR.insertCell()
 With mTD
 .className = "first_col"
 .innerHTML = lngNumber
 End With
 Set mTD = mTR.insertCell()
 With mTD
 .className = "second_col"
 .innerHTML = recPeople.Fields(1)
 .setAttribute "Pos", lngNumber
 End With
 lngNumber = lngNumber + 1
 recPeople.MoveNext
 Wend
End Sub

Метод 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. Процедуры выбора пунктов меню будут следующими:

Private Sub mnuStyleClassic_Click()
 mnuStyleClassic.Checked = True
 mnuStyleModern.Checked = False
 ActivateStyle
End Sub

Private Sub mnuStyleModern_Click()
 mnuStyleModern.Checked = True
 mnuStyleClassic.Checked = False
 ActivateStyle
End Sub

Непосредственно изменять стиль оформления будет процедура ActivateStyle:

Private Sub ActivateStyle()
 If mnuStyleClassic.Checked = True Then
'получаем объект, по имени тега и меняем его 'свойство href
 mIDoc.getElementsByTagName("LINK").Item(0).href = "style_1.css"
 ElseIf mnuStyleModern.Checked = True Then
 mIDoc.getElementsByTagName("LINK").Item(0).href = "style_2.css"
 End If
End Sub

Таким образом, при загрузке формы у нас будет появляться таблица со списком фамилий. При этом она всегда будет позиционироваться по центру, независимо от изменения размера формы. Если таблица выйдет за пределы формы автоматически появятся полосы прокрутки.

Чтобы скрыть полосы прокрутки используйте код 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:

Private Sub mDoc_onmouseover()
 If isInfo = False Then
 Set mIElement = mDoc.parentWindow.event.srcElement
 While IsNull(mIElement.getAttribute("Pos")) = True
 Exit Sub
 Wend
 lngPos = mIElement.getAttribute("Pos")
 mIElement.className = "second_col_on"
 End If
End Sub

Private Sub mDoc_onmouseout()
 If isInfo = False Then
 Set mIElement = mDoc.parentWindow.event.srcElement
 While IsNull(mIElement.getAttribute("Pos")) = True
 Exit Sub
 Wend
 lngPos = mIElement.getAttribute("Pos")
 mIElement.className = "second_col"
 End If
End Sub

Таким же образом обработаем событие onclick. Только теперь нам надо будет не изменить имя класса для элемента, а получить значение атрибута «Pos», для того, чтобы вывести информацию по конкретному человеку. Это реализуется в следующей процедуре:

Private Function mDoc_onclick() As Boolean
 Dim lngPos As Long
 If isInfo = False Then
 Set mIElement = mDoc.activeElement
 While IsNull(mIElement.getAttribute("Pos")) = True
 Exit Function
 Wend
 isInfo = True
 lngPos = mIElement.getAttribute("Pos")
 LoadInfo lngPos
 End If
End Function

Затем значение атрибута «Pos» передаётся в процедуру отображения информации по конкретному человеку:

Private Sub LoadInfo(lngPos As Long)
 WebBrowser.Navigate "res://mshtml.dll/blank.htm"
 While WebBrowser.ReadyState READYSTATE_COMPLETE
 DoEvents
 Wend
 strHTML = StrConv(LoadResData("people_info.html", 23), vbUnicode)
 mIDoc.write strHTML
 mIDoc.getElementsByTagName("BASE").Item(0).href = _
 "res://" & App.Path & "" & App.EXEName & ".exe"
 ActivateStyle
 Set mTable = mDoc.All.people_info
 Set btnBack = mDoc.All.btnBack
 Set btnPreview = mDoc.All.btnPreview
 Set btnPrint = mDoc.All.btnPrint
 recPeople.MoveFirst
 recPeople.Move lngPos - 1
 arrDescription = Array("Фамилия:", "Имя:", "Отчество:", "Город:", "Адрес:", "Телефон:")
 For i = 0 To UBound(arrDescription)
 Set mTR = mTable.insertRow(-1)
 Set mTD = mTR.insertCell()
 With mTD
 .className = "first_col"
 .Width = 80
 .innerHTML = arrDescription(i)
 End With
 Set mTD = mTR.insertCell()
 With mTD
 .className = "second_col"
 .innerHTML = recPeople.Fields(i + 1)
 End With
 Next
End Sub

С помощью кода:

Set btnBack = mDoc.All.btnBack
Set btnPreview = mDoc.All.btnPreview
Set btnPrint = mDoc.All.btnPrint

мы получаем ссылки на три кнопки, а так как экземпляры btnBack, btnPreview и btnPrint класса HTMLButtonElement объявлены у нас WithEvents, то мы легко можем обрабатывать их события.

При нажатии на кнопку btnBack, мы снова загружаем список фамилий:

Private Function btnBack_onclick() As Boolean
 LoadPeople
End Function

При нажатии на кнопку btnPreview, мы откроем стандартное окно Предварительного просмотра страницы:

Private Function btnPreview_onclick() As Boolean
 HideButton
 Me.WebBrowser.ExecWB OLECMDID_PRINTPREVIEW, OLECMDEXECOPT_DODEFAULT
 ShowButton
End Function

Чтобы в отчёте не было трёх кнопок, их необходимо сначала спрятать, а затем снова отобразить. Для этого используются две соответственные процедуры HideButton и ShowButton:

'скрываем кнопки
Private Sub HideButton()
 btnBack.Style.visibility = "hidden"
 btnPreview.Style.visibility = "hidden"
 btnPrint.Style.visibility = "hidden"
 mDoc.body.Style.backgroundColor = "#ffffff"
End Sub

'показываем кнопки
Private Sub ShowButton()
 btnBack.Style.visibility = "visible"
 btnPreview.Style.visibility = "visible"
 btnPrint.Style.visibility = "visible"
 mDoc.body.Style.backgroundColor = "buttonface"
End Sub

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

Печать отчёта будет осуществляться при нажатии кнопки btnPrint:

Private Function btnPrint_onclick() As Boolean
 HideButton
 Me.WebBrowser.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_PROMPTUSER
 ShowButton
End Function

Теперь необходимо позаботиться о надёжности приложения. Нам необходимо запретить WebBrowser’у реагировать на нажатие клавиш, так как последствия их нажатия могут быть для нас нежелательны (например нажатие F5 приведёт к обновлению страницы, в результате чего всё содержимое её будет потеряно). Для этого создадим следующую процедуру:

Private Sub mDoc_onkeydown()
 mDoc.parentWindow.event.keyCode = 0
End Sub

Таким образом, при нажатии любой клавиши, будет возвращён keyCode, равный 0, следовательно никакой реакции со стороны WebBrowser не последует.

Кроме того вы можете в зависимости от возвращённого keyCode, т.е. в зависимости от того какая клавиша была нажата, производить определённые действия в вашей программе.

Кроме этого может возникнуть необходимость запрета вызова контекстного меню WebBrowser’а, это осуществляется при помощи следующего кода:

Private Function mDoc_oncontextmenu() As Boolean
 mDoc_oncontextmenu = False
End Function

Аналогично можно запретить выделение в документе:

Private Function mDoc_onselectstart() As Boolean
 mDoc_onselectstart = False
End Function

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

Private Sub Form_Unload(Cancel As Integer)
 dbPeople.Close
 RestoreRegSettings
End Sub

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

Скачать пример к статье