Visual Basic 6. Руководство разработчика

         

Ключевые свойства элемента управления


Как уже известно, объект UserControl, вообще говоря, представляет собой форму, на которую можно помещать другие элементы управления, рисовать фигуры, отображать текст и обнаруживать события. Он даже имеет свойства, такие как AutoRedraw и ScaleMode, которые облегчают рисование во время выполнения. Но он не называется формой — он называется UserControl. Кроме того, он имеет несколько уникальных свойств для элементов управления ActiveX, которые будут рассмотрены в этом разделе.

CanGetFocus. Установите это свойство в True, если элемент управления может получать фокус либо с помощью мыши, либо с использованием клавиши табуляции. Специальный элемент управления может получить фокус, если получает фокус объект UserControl либо один из конституэнтных элементов управления. Если элемент управления способен получать фокус, события EnterFocus и Exit Focus инициируются всякий раз, когда элемент управления получает или теряет фокус.

Установите свойство CanGetFocus прототипа элемента управления в True и затем введите следующие строки в обработчики событий EnterFocus и ExitFocus.

Private Sub UserControl EnterPocus()

UserControl.Backcolor = vbRed

End Sub

Private Sub UserControl_ExitFocus()

UserControl.Backcolor = vbGreen

End Sub

Затем переключитесь на тестовую форму и найдите на ней два экземпляра нового элемента управления (или один экземпляр элемента управления ActiveX и пару стандартных элементов управления). Запустите приложение и перемещайте фокус от одного элемент управления к другому. Прототип элемента управления, который имеет фокус, заполняется красным цветом, в то время как стандартные эле­менты управления заполняются зеленым цветом.

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


SetFocus следующим образом.

1. Вернитесь к базовому прототипу элемента управления и поместите две кнопки Command на UserControl. He меняйте их имена.

2. Добавьте следующие строки, чтобы переместить фокус на кнопку Command2 в событии EnterFocus.

Private Sub UserControl _EnterFocus()

UserControl.Backcolor = vbRed

Command2.SetFocus

End Sub

3. Переключитесь на тестовую форму, удалите все элементы управления на форме и поместите на нее экземпляр нового элемента управления (достаточно большой, чтобы отобразить обе кнопки) и еще одну кнопку Command.



4. Запустите проект и посмотрите, как фокус перемещается от одного элемента управления к другому. Обратите внимание: когда специальный (заказной) элемент управления получает фокус, он передает его кнопке Command2. Нельзя переместить фокус на кнопку Command1 с помощью клавиши табуляции. Заказной элемент управления представляет собой атомарный объект, и он получает фокус один раз.

ControlContainer.

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

По умолчанию заказной элемент управления не является контейнером. Другими словами, можно нарисовать кнопку Command, которая находится наполовину на заказном элементе управления и наполовину вне его. Для изменения такого поведения нужно установить свойство ControlContainer равным True.

Alignable. Если это свойство установлено в True, то заказной элемент управления во время конструирования имеет свойство Align. Свойство Align определяет, где и как элемент управления выравнивается на форме. Возможные значения свойства Align показаны в табл. 16.3.

Таблица 16.3. Значения свойства Align

Значение

Описание

VbAlignNone

Элемент управления выравнивается вручную (установлено по умолчанию)

VbAlignTop

Элемент управления выравнивается по верхнему краю формы

VbAlignLeft

Элемент управления выравнивается по левому краю формы

VbAlign Right

Элемент управления выравнивается по правому краю формы

VbAlignBottom

Элемент управления выравнивается по нижнему краю формы

<


Совет

Свойство Align не доступно во время конструирования, если свойство Alignable специального элемента управления равно False. Рекомендуется устанавливать свойство Alignable равным True для таких элементов управления, как, например, панель инструментов, которые должны всегда располагаться у края контейнера (даже при изменении его размеров).

InvisibleAtRuntime.

Некоторые элементы управления, наиболее типичным примером которых является элемент Timer, во время выполнения невидимы. Если пользовательский элемент управления не имеет интерфейса пользователя и не должен появляться на форме, установите свойство InvisibleAtRuntime равным True.

ToolboxBitmap.

Используйте это свойство для отображения BMP-файла на панели инструментов вместо стандартной пиктограммы элемента управления ActiveX Значение свойства ToolboxBitmap - это путь к BMP-файлу, но изображение хранится в элементе управления и переносится вместе с ним.

AccessKeys.

Свойство AccessKeys используется для задания комбинаций клавиш, которые будут "горячими" клавишами для быстрого перемещения на элемент управления. Если хотите, чтобы пользователь, нажимая комбинацию "горячих" клавиш (Alt+клавиша), мог сразу перемещать фокус на пользовательский элемент управления, присвойте свойству AccessKeys значение какой-либо клавиши. На­пример, выполните следующие действия.

1. Присвойте свойству AccessKeys пользовательского элемента управления значение "А" (без кавычек).

2. Переключитесь на тестовую форму и запустите ее. Обратите внимание, что можно переместить фокус на пользовательский элемент управления, нажав комбинацию клавиш Alt+A.

3. Теперь остановите приложение, возвратитесь к заказному элементу управления и откройте событие AccessKeyPress. Это событие вызывается каждый раз, когда нажимается "горячая" клавиша. Добавьте следующие строки, чтобы событие отображало ASCII-код клавиши.

Private Sub UserControl_AccessKeyPress(KeyAscii As Integer)

Debug.Print "Access key pressed" & KeyAscii



End Sub

Чтобы переместить фокус на определенный конституэнтный элемент управления или выполнить некоторое действие, когда фокус перемещается на заказной элемент управления, введите соответствующий код в событие AccessKeyPress. Давайте добавим "горячие" клавиши к двум кнопкам Command из последнего примера. Для этого выполните следующие действия.

1. Переключитесь на объект UserControl и добавьте две кнопки - Command1 и Command2, как показано на рис. 16.15. (Если был выполнен пример при рас­смотрении свойства CanGetFocus двумя страницами ранее, то эти две кнопки уже находятся на форме.)



Рис. 16.15. Когда фокус перемещается на заказной элемент управления, он, на самом деле, перемещается на один из конституэнтных элементов управления

2. Переключитесь на тестовую форму и поместите на форму экземпляр нового элемента управления, кнопку или другой элемент управления.

3. Запустите тестовый проект и перемещайте фокус между элементами. Обратите внимание на следующее.

• При перемещении фокуса на заказной элемент управления с помощью мыши, фокус устанавливается на кнопке Command1.

• При перемещении фокуса на заказной элемент управления с помощью клавиши Tab в окне проверки отображается ASCII-код "горячей" клавиши.

4. Теперь переключитесь обратно на объект UserControl и назначьте "горячие" клавиши двум кнопкам Command. Измените их свойства Caption на Command&l и Command&2, чтобы клавиши 1 и 2 стали их "горячими" клавишами.

5. Запустите тестовый проект и поэкспериментируйте с перемещением фокуса на элементы управления, размещенные на форме.

Можно использовать комбинацию "горячих" клавиш, чтобы обратиться не только к указному элементу управления, но также и к отдельным его компонентам. Чтобы активизировать определенный конституэнтный элемент каждый раз, когда фокус перемещается на заказной элемент управления, добавьте метод SetFocus в подпрограмму UserControl_AccessKeyPress(). Если заказной элемент управления содержит текстовое поле как свою составную часть, то можно с помощью следующей подпрограммы перевести фокус и на это поле:



Private Sub UserControl

AccessKeyPress(KeyAscii As Integer)

Textl.SetFocus

End Sub

VB6 в действии: элемент управления ActiveX Alarm

Следующий пример демонстрирует элемент управления ActiveX, который содержит все три типа элементов — свойства, методы и события. Это простой сигнал оповещения, который может быть предварительно установлен, чтобы сработать в опре­деленное время, а когда это происходит, то генерируется событие TimeOut. Кроме того, пока таймер включен, элемент управления обновляет изображение на экране, показывая время, истекшее с момента запуска таймера (свойство CountDown должно быть False), или время, оставшееся до момента срабатывания сигнала (свойство CountDown должно быть True). На рис. 16.16 показана тестовая форма для элемента управления Alarm. Первый экземпляр элемента управления Alarm (Process А) подсчитывает время с момента запуска таймера, а второй экземпляр (Process В) подсчитывает время, оставшееся до момента срабатывания таймера.

Совет

При первой загрузке проекта Alarm Visual Basic выдает предупреждение о том, что он не смог загрузить элемент управления Alarm. Это означает, что элемент управления Alarm еще не был установлен в системе, и тестовая форма, которая их использует, не может быть загружена. Продолжайте загрузку проекта, а затем откройте тестовую форму. Два экземпляра элемента управления Alarm будут заменены двумя элементами управления PictureBox. Удалите эти два элемента управления и поместите два экземпляра элемента управления Alarm на тестовую форму (см. рис. 16.16).



Рис. 16.16. Тестовая форма для специального элемента управления Alarm

Интерфейс элемента управления Alarm

Элемент управления Alarm имеет два специальных свойства:

•  AJarmTime и

• Count Down.

AlarmTime - это время срабатывания сигнала, выраженное в 12-ти часовом формате. CountDown — это свойство типа True/False, которое определяет, что отображается на элементе управления. Если CountDown равно True, то Alarm показывает оставшееся время. Если установить время срабатывания сигнала на 8:00 вечера и запустить таймер в 7:46 вечера, то элемент управления отобразит 0:14.00, затем 0:13.59 и т.д., пока сигнал не сработает через 14 минут. Если CountDown установить в False, то элемент управления начинает отсчет с 00:00.00 и будет считать, пока не будет достигнуто значение AlarmTime. Если значение свой­ства AlarmTime меньше текущего времени, элемент управления Alarm предполага­ет, что сигнал должен сработать в заданное время на следующий день. Например, если текущее время 8:00.00 вечера 1 апреля, a AlarmTime равно 6:30.00 вечера, то сигнал сработает в 6:30.00 вечера 2 апреля (сигнал произойдет через 22 часа 30 ми­нут).



Элемент управления Alarm имеет два метода для запуска и остановки таймера:

•  StartTimer запускает таймер и

•  StopTimer останавливает таймер.

Наконец, элемент управления Alarm имеет событие TimeOut, которое сообщает приложению, что сигнал уже сработал (это происходит тогда, когда время достигло значения AlarmTime). Приложение может использовать это событие, чтобы выполнить другое действие или просто проинформировать пользователя.

Тестирование элемента управления Alarm

Тестовая форма элемента управления Alarm показана на рис. 16.16. Она содержит два экземпляра элемента управления и можно менять их свойство CountDown во время выполнения. Свойство AlarmTime элементов управления устанавливается в слу­чайное значение в обработчике события Load тестовой формы с помощью сле­дующих операторов:

Private Sub Form_Load()

Randomize Time

AlarmCtl1.AlarmTime = Rnd()

AlarmCtl2.AlarmTime = Rnd()

End Sub

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

Когда два элемента управления Check 1 и Check2 отмечены, свойство Count Down изменяется с помощью следующего кода:

Private Sub Checkl_Click()

If Checkl.Value Then

AlarmCtll.Count Down = True Else

AlarmCtll.CountDown = False

End If

End Sub

Код для события Click элемента управления Check2 идентичен, только он применяется к элементу управления AlarmCtl2. Наконец, когда у элемента управ­ления Alarm подходит время срабатывания сигнала, выполняется следующий код.

Private Sub AlarmCtll_TimeOut()

MsgBox "The Alarm" & AlarmCtll.Tag & "has Timed out"

End Sub

Нужно присвоить свойству Tag элемента управления подходящее имя, так как программа использует это свойство для различения двух элементов управления. Тестовый проект использует тэги ProcessA и ProcessB.

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



Программа 16.14. Запуск и остановка сигнала

Private Sub StartButtonl_Click()

If StartButtonI.Caption = "Start Timer" Then

AlarmCtl1.StartTimer

StartButtonI.Caption = "Stop Timer"

Else

StartButtonI.Caption = "Start Timer"

AlarmCtl1.StopTimer

End If

End Sub

И, наконец, кнопки Alarm Time с помощью следующего кода отображают время, когда соответствующий сигнал должен сработать.

Private Sub AlarmButtonl_Click()

MsgBox "The alarm will go off at" & AlarmCtll.AlarmTime

End Sub

Загрузите проект Alarm (продолжайте загрузку даже после того, как появится предупреждение) и замените два элемента управления PictureBox, которые появятся вместо элементов управления Alarm, на два экземпляра элементов управления Alarm. Поэкспериментируйте с интерфейсом элемента управления и исследуйте код тестового проекта.

Откройте тестовый проект, закомментируйтс операторы в событии Load формы (которые устанавливают значение свойства AlarmTime равным случайным значениям) и установите свойство AlarmTime на минуту больше, чем системное время (текущее время, отображаемое в нижнем правом углу панели задач). Запустите проект и затем отметьте флажок CountDown. Alarm начнет отсчитывать в обратном направлении разность между текущим временем и временем сраба­тывания сигнала. Когда эта разница достигнет нуля, окно сообщений сообщит, что время прошло. Если флажок CountDown не отмечен, то вы увидите, сколько времени прошло с момента запуска таймера. Чтобы отобразить время сигнала, нажмите кнопку Alarm Time.


Код элемента управления


Rates

Стандартные свойства элемента управления добавлены с помощью мастера интерфейса ActiveX. Остановимся на процедурах, которые загружают текстовый файл и выводят его в элемент управления ListBox.

Программа 21.10. Метод DownloadRates

Public Function DownloadRates(RatesURL As String)

On Error GoTo DLoadError

AsyncRead RatesURL, vbAsyncTypeFile, "Rates"

Exit Function

DLoadError:

RaiseEvent DLoadError(1024, "Could not download currency _

rates.")

' (He удалось загрузить курсы валют)

End Function

Метод, вызывающий функцию AsyncRead, передает ей URL Web-сервера в качестве параметра. Загруженная информация сохранится в файле с именем Rates.

Интересное действие выполняется, когда происходит событие

AsyncReadComplete объекта UserControl.

Private Sub UserControl_AsyncReadComplete(AsyncProp As AsyncProperty)

Dim FileName As String

On Error GoTo DLoadError

If AsyncProp.PropertyName = "Rates" Then

FileName = AsyncProp.Value

ReadRates FileName

End If

Exit Sub

DLoadError:

RaiseEvent DLoadError(1025, "Error in Downloading rates")

' (Ошибка при загрузке курсов)

End Sub

Код начинается с проверки значения свойства

PropertyName объекта AsyncProp. В элементе управления Rates это свойство принимает только значение Rates. Если элемент управления загружает несколько файлов сразу, то свойство укажет, загрузка какого файла уже завершена, чтобы его можно было обработать. Когда метод AsyncRead загружает файл, свойство Value объекта AsyncProp содержит имя файла и путь на локальном диске. Это имя не имеет никакого отношения к фактическому имени файла на сервере. Оно является уникальным именем файла, созданным сис­темой во временной папке файлов Интернет. Имя файла используется подпрограм­мой ReadRates() для отображения курсов в элементе управления ListBox.

Программа 21.11. Подпрограмма ReadRates()

Private Sub ReadRates(FileName As String)

Dim FNum As Integer

Dim currencyName As String, currencyValue As Currency


FNum = FreeFile

CurrencyList.Clear

On Error GoTo ReadError

Open FileName For Input As FNum

Input ttFNum, m_LastUpdate

i=1

While Not EOF(FNum)

Input #FNum, currencyName, currencyValue

CurrencyList.AddItem currencyName & Chr(9) & _

Format(currencyValue, "#.000")

CurrencyNames(i) = currencyName

AllRates.Add Str(currencyValue), currencyName

i = i + 1

Wend

RaiseEvent RatesRead

Exit Sub

ReadError:

RaiseEvent DLoadError(1025, "Unkown data format")

                                ' (Неизвестный формат данных)

End Sub

Это прямолинейный VB-код, который открывает текстовый файл и помещает его строки в элемент управления CurrencyList типа ListBox. Он сохраняет курсы валюты в списке AllRates, используя имя валюты в качестве ключа. Эта методика упрощает поиск курса обмена валюты. Подпрограмма ReadRates(), описанная в параграфе Private объекта UserControl, не может вызываться из основного приложения.

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

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

"Error in downloading rates" ("Ошибка в загрузке курсов"). Метод AsyncRead может вызываться для загрузки файла, пока загружается другой файл, но он не может загружать один и тот же файл дважды.

Тестирование элемента управления Rates

Тестирование элемента управления, который загружает значения свойства с HTTP-сервера, требует, чтобы приложение было соединено с сервером, а документ, используемый для тестирования, находился на сервере. Если имеется собственный Web-сервер (Internet Information или Server Personal Web Server), то можно только скопировать Rates, txt файл в виртуальный каталог Web-сервера. Или просто скопировать файл в корневой каталог и соединиться с сервером, используя следующий URL.



http://127.0.0.1/RatesPage.htm

Адрес 127.0.0.1 — адрес компьютера в сети. Фактически, нет необходимости в реальной сети. Если на компьютере установлен Web-сервер, то можно использовать этот URL, чтобы соединиться с файлом. Если Web-сервер находится на другом компьютере той же сети, замените "127.0.0.1" фактическим именем компьютера.

В большинстве случаев собственного Web-сервера нет. Тогда используется сервер провайдера услуг Интернет, если есть разрешение помещать файлы на этот сервер (большинство ISP предоставляет абонентам несколько мегабайт для пользовательских страниц). Чтобы проверить элемент управления Rates с ISP-сервера, поместите Rates.txt файл в каталог на сервере. Для этого выполните следующие действия.

1. Создайте новую папку на жестком диске и поместите туда файл Rates.txt (если есть другие HTML-файлы, которые необходимо поместить на сервер, также перепишите их в эту папку).

2. Запустите Web Publishing Wizard (утилита, поставляемая с Windows и FrontPage).

3. Первая страница Web Publishing Wizard - экран приглашения. Щелкните на кнопке Next, чтобы перейти к выбору файлов или папок.



4. Введите имя созданной папки в поле File Name Box или Folder Name Box. Щелкните на кнопке Next.

5. В следующем окне определите имя Web-сервера и щелкните на кнопке Advanced. Появится другое окно, в котором необходимо выбрать протокол, исполь­зуемый для пересылки файла.

6. Выберите FTP и щелкните на кнопке Next.

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

users.ISPname.com/yourname

Часть

yourname — имя пользователя, которое используется для входа в систему. Если адрес пользователя — jdoe@usa1.com, то имя входа в систему — jdoe, a URL каталога на ISP-сервере следующий.

users.usa1.com/jdoe

Многие ISP используют символ тильды перед именем пользователя (users.usa1.com ~ jdoe). Если поискать "user pages" на ISP Web-узле, то будет найдена вся необходимая информация.



Чтобы увидеть последнее окно мастера, щелкните на кнопке Next. Затем щелкните на кнопке Finish, чтобы поместить файлы на сервер.

Чтобы проверить каталог на сервере, запустите Internet Explorer и введите URL файла Rates.txt, находящегося на сервере.

Http://users.usa1.com/jdoe/rates.txt

Содержимое файла Rates.txt отобразится в окне броузера. Это значит, что файл на сервере успешно размещен и элемент управления Rates будет видеть его на сервере (и загружать с него). Необходимо скопировать URL из поля Address броузера и вставить его в код (передать как параметр в метод DownloadRates элемента управ­ления Rates).

Описанный процесс работает со многими ISP, но так можно обратиться не ко всем ISP. Если возникают проблемы при помещении файлов на сервер, необходимо выяснить у Internet провайдера, что необходимо выполнить для размещения персонального Web-узла. Вместо Web-узла поместите файл Rates.txt. Или, если собственный Web-узел уже есть, поместите файл Rates.txt в тот же каталог. Это не повлияет на Web-узел, так как ни одна из его страниц не содержит гиперсвязи к этому файлу.

Если курсы валют были загружены, а через некоторое время вы снова щелкнули на кнопке Download Rate, то возможно появление на элементе управления тех же значений. Можно разместить новые файлы на сервере несколько раз, но курсы не будут меняться. Опытные Web-пользователи уже сообразили, в чем дело AsyncRead метод не запрашивает сервер, чтобы загрузить Rates.txt файл снова он восстанавливает файл из кэша, сохраняет информацию в другом временном файле, а код элемента управления считывает его. В действительности, метод AsyncRead входит в класс IntemetExplorer и использует тот же кэш, что и Internet Explorer.

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

1. Запустите Internet Explorer и выберите команду Internet Options в меню View



2. Щелкните на кнопке Settings (Установки), чтобы открыть диалоговое окно Settings.



3. Чтобы заставить Internet Explorer перезагружать страницу с сервера (вместо чтения из кэша), установите флажок Eveiy visit to the page.

Теперь Internet Explorer не будет использовать кэш, и при каждом возврате к предыдущей странице, даже с интервалом в несколько секунд, страница будет перезагружаться с сервера. Когда эта книга была подготовлена к печати, Microsoft анонсировала первую бета-версию Internet Explorer 5. Возможно, новый AsyncRead метод позволит выбирать, загружать страницу или просто регенерировать кэш.

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

Загрузка свойств изображения

Метод AsyncRead может загружать свойства изображения. Изображения загру­жаются в виде двоичных файлов и отображаются с помощью метода LoadPicture. Visual Basic может создать контекст устройства для сохранения загруженного бито­вого изображения. Чтобы загрузить изображение, нужно вызвать функцию AsyncRead.

AsyncRead URL, vbAsyncTypePicture, "Image"

Константа

vbAsyncTypePicture

сообщает Visual Basic, что загружаемый объект -изображение. Файлы не создаются на хост-компьютере, поэтому считать значения пикселей нет возможности. Чтобы работать с изображением, необходимо контро­лировать его загрузку с помощью функции AsyncReadComplete. Когда загрузка свойства Image (или др. имени, назначенного свойству в методе AsyncRead) заверша­ется, необходимо прочесть значение свойства и сохранить его в объекте Picture с помощью следующего оператора.

Set Bitmap = AsyncProp.Value

Если загружаются несколько изображений, то для идентификации свойств используются различные имена. Можно использовать такие свойства объекта Bitmap, как Height (Высота) и Width (Ширина). Следующий фрагмент кода создает объект Picture с загруженным растровым изображением и вызывает подпрограмму Showlmage(), чтобы отобразить его в элементе управления PictureBox.



Private Sub UserControl_AsyncReadCornplete (AsyncProp As AsyncProperty)

On Error GoTo DloadError

If AsyncProp.PropertyName = "Image" Then

Set Bitmap = AsyncProp.Value

Showlmage Bitmap

' Ширина Bitmap задается в твипсах,

' для преобразования ее в пиксели используйте оператор

' Int(ScaleX(Bitmap.Width, vbHimetric, vbPixels))

End If

Exit Sub

DLoadError:

' сброс события ошибки

End Sub

Подпрограмма ShowImage() использует метод PaintPicture, чтобы скопировать битовое изображение из переменной Bitmap в элемент управления PictureBox.

Picture1.PaintPicture Image, 0, 0, _

Picture1.ScaleWidth, Picture1.ScaleHeight, _

0, 0, Picture1.ScaleWidth,Picture1.ScaleHeight

Подведем итог: загрузка свойств изображения с HTTP-сервера аналогична загрузке текстовых файлов. Необходимо определить тип данных, загружаемых в функцию AsyncRead (константа vbAsyncTypePicture

используется вместо vbAsyncTypeFile). Когда изображение загружено, объект Picture создается автоматически. В нем и сохраняется битовое изображение (так же, как автоматически генерировался текстовый файл). Можно использовать метод PaintPicture, чтобы передать растровое изображение от объекта Picture элементу PictureBox или непосредственно объекту UserControl.

Наконец, можно загрузить данные в формате массива, определяя константу vbAsyncTypeArray в функции AsyncRead. При этом Visual Basic создает байтовый массив, который можно обрабатывать с помощью кода.

Глава 22. Активные серверные страницы

• Взаимодействие клиент-сервер

• Использование активных серверных страниц

• Передача данных на сервер

• Обработка данных клиента

• Использование объекта Server

• Разработка Web-приложений

Мы уже знаем, как Web-cepep пересылает информацию клиенту в форме HTML-документов и как клиент взаимодействует с сервером с помощью гиперссылок (см. гл. 19), как создавать Web-страницы, позволяющие пользователю вводить данные на клиентском компьютере, и пересылать их вместе с URL на сервер. Кода сервер получает данные (так называемые значения параметров) от клиента, он обрабатывает их и возвращает результат в HTML-формате. В этой главе мы узнаем, как сервер извлекает параметры из сообщения клиента и обрабатывает их. Это самая важная часть механизма взаимодействия клиент-сервер и (во всяком случае, до появления ASP) наиболее сложная для реализации.



Параметры, передаваемые клиентом, разнообразны. Это может быть регистра­ционная информация, аргументы для поиска, параметры настройки. Компанию может интересовать информация из баз данных, извлекаемая по мере поступления запросов. Для получения самых "свежих" данных с Web-сервера переслать на сервер имя гиперссылки недостаточно. Представьте, что пользователю нужны данные о продажах некоторого товара в штате Северная Каролина или список наиболее активных заказчиков из Техаса. Данные получают из базы данных при поступлении запроса. Это не может быть документ, подготовленный загодя и находящийся на диске сервера в ожидании запроса. После запроса сервер должен извлечь необходимую информацию из базы, преобразовать ее в HTML-формат и передать клиенту.

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

Примечание

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

Microsoft, например, к Commerce Server.


Компонентное программное обеспечение


Сущность технологии OLE состоит в использовании компонентов программного обеспечения.

Компонент — это объект (элемент управления или приложение) который кто-то уже разработал, и его можно использовать в вашей программе. Если компонент поддерживает OLE, то можно "позаимствовать" его функцио­нальные возможности для собственных целей. Например, Microsoft Word содержит средства проверки правописания. Зачем же покупать другую программу проверки, или писать собственную, если можно позаимствовать эти функциональные возможности из Word?

Разработчик компонентного программного обеспечения рассматривает программу как совокупность работающих вместе компонентов, что позволяет обеспечить общий стандарт интерфейса для OLE-приложений. Например, функциональные возможности электронной таблицы могут быть доступными в текстовом процессоре, и наоборот. Прикладная программа, созданная средствами Visual Basic, может обладать функциональными возможностями и текстового процессора, и электронной таблицы.



Компоненты-члены элемента управления


Rates

Rates имеет много стандартных компонентов-членов.

BackColor

ForeColor

MouseMove

Click

Key Down

MouseUp

DblClick

KeyPress

Refresh

Enabled

KeyUp

Font

Mouse Down

Эти компоненты добавлены в элемент управления с помощью мастера. Все они соответствуют эквивалентным элементам управления ListBox.

В дополнение к стандартным, элемент управления

Rates реализует следующие пользовательские компоненты.

Метод DownloadRates (Загрузить курсы обмена). Метод DownloadRates соединяется с сервером и загружает документ, содержащий курсы валюты. Ниже приведен синтаксис этого метода.

DownloadRates (RatesURL As String)

RatesURL - это URL текстового файла, имеющий следующую структуру.

<date>

<currency>, <rate>

<currency>, <rate>

<currency>, <rate>

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

"5:31 РМ 5/18/96"

US$, 1.00

С$, 1.483

ВР, 0.867

FFr, 2.143

ECU, 1.103

DM, 1.780

ESP, 13.203

YEN, 143.300

LIR, 2340.500

GDr, 328.405

BFR, 25.403

Так как код использует запятую, чтобы отделить два элемента каждой строки, нельзя использовать тот же самый символ как разделитель тысяч. Значение 2340.500 не может быть представлено в Rates.txt файле как 2,340.500. Его не пропустит код, который анализирует файл и заполняет элемент управления ListBox.

Событие RatesRead (Чтение курсов). Инициируется, как только данные разгружены.

Свойство LastUpdate (Последняя модификация).

Возвращает дату и время последней модификации курсов. Значение свойства считывается с сервера вместе с курсами валюты.

Свойства Count (Счетчик). Возвращает число различных типов валют, загру­женных с сервера.

GetCurrencyValue (Получить курс). Возвращает обменный курс определенной валюты. Чтобы узнать обменный курс, например, для немецкой марки, вызовите метод GetCurrencyValue.

DMRate = GetCurrencyValue("DM") ,

Аргумент метода должен иметь тип String

Метод GetCurrencyName (Получить имя валюты). Возвращает имя валюты в поле index элемента управления ListBox.

Событие DLoadError (ErrNumber As Long, ErrDescription As String). Вызывается из события AsyncReadComplete, чтобы сообщить приложению, что произошла ошибка. Главное приложение может узнать номер и описание ошибки, чтобы предпринять соответствующие действия.



Конструирование базовых прототипов элемента управления


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

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



Конструирование элемента управления


FLEXLabel

Перед тем как создать элемент управления, хотелось бы обсудить выгоды от создания элементов ActiveX. Некоторые могут удивиться, зачем возиться с элементами ActiveX, если уже есть код для отображения трехмерной надписи на форме любым способом? Если захотеть, то можно модифицировать код для работы с элементом PictureBox, который можно расположить где угодно на форме.

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

•  Код элемента управления не будет пересекаться с кодом основного приложения. Приложение даже не будет знать о коде элемента управления.

•  Можно менять текст, стили выравнивания и специальные эффекты из окна свойств, не меняя исходного кода приложения. Кроме того, можно визуально менять свойства и наблюдать изменения без запуска всего проекта.

• Элемент управления может накрывать только часть формы. Кроме того, можно поместить на одной форме несколько элементов управления с различными надписями.

•  Наконец, можно свободно распространять элемент управления, и другие разработчики могут использовать его, не затрагивая его код.

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

Элемент ActiveX должен предоставлять определенные свойства, которые автомати­чески отображаются в окне свойств. Разработчик должен иметь возможность настраивать каждый параметр, влияющий на отображение, посредством манипуляции его свойствами. В дополнение, разработчики ожидают увидеть стандартные свойства, присущие всем стандартным элементам (такие как цвет фона, шрифт текста и т.д.). Следует тщательно конструировать методы так, чтобы они обеспечивали все функциональные возможности элемента управления и были доступны из кода приложения. Кроме того, методы не должны перекрываться. Наконец, нужно предусмотреть события, необходимые для реакции на внешние воздействия. Можно кодировать обычные приложения без предварительного конструирования, но элементы ActiveX и приложения для работы с базами данных требуют тщательной подготовки. Не начинайте кодировать элемент управления до тех пор, пока не сформулируете абсолютно четко, что будет делать элемент и как он будет использо­ваться разработчиками во время конструирования их приложений.


Alarm

Первым шагом является конструирование интерфейса элемента управления. В отличие от элемента управления Timer из Visual Basic, элемент управления Alarm имеет видимый интерфейс. Его работа основана на двух конституэнтных элементах управления:

• Timer, который обновляет изображение каждую секунду, и

•  Label, который отображает время.

Конструирование интерфейса пользователя

Для конструирования интерфейса элемента управления, выполните такие шаги.

1. Поместите элемент управления Label на форму UserControl и установите в свойстве Font желаемые шрифт и размер.

2. Выровняйте Label по верхнему левому углу элемента управления, и измените размеры элемента управления так, чтобы он полностью вмещал элемент Label. (Запомните значения свойств Width и Height элемента управления. Они понадобятся позже при написании кода для предотвращения изменения размеров этого элемента управления.)

3. Поместите элемент управления Timer на объект UserControl He имеет значения, где поместить элемент управления Timer. Он будет невидим во время выпол­нения Можно поместить Timer вне видимой области пользовательского элемента управления или даже поверх элемента Label.

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

Private Sub UserControl Resize()

UserControl.Size 1800, 500

End Sub

Метод Size заставляет элемент управления сохранять фиксированный размер Значения 1800 (ширина) и 500 (высота) размеров элемента управления нужно изменить согласно реальным размерам элемента управления Label.

Теперь можно проверить поведение нового элемента управления. Попробуйте изменить его размеры Даже при том, что можно перемещать органы управления этого элемента, его размеры изменить нельзя.

Реализация компонентов элемента управления

Теперь все готово для реализации свойств элемента управления, его методов и событий. Давайте начнем со свойств. Нам уже известно, как добавить свойства к элементу управления с помощью мастера интерфейса элемента управления ActiveX и как это сделать вручную. Теперь давайте рассмотрим еще один инструмент. Мы еще сделаем это с помощью мастера, но сейчас просто добавим одно свойство или метод.




Начнем с объявления переменных. Вставьте следующие строки в окно Code объекта UserControl:

Private startTime As Date

Private Running As Boolean

Private m_CountDown As Boolean

Private m_AlarmTime As Date

Уже можно догадаться, что m_CountDown

и m_Alarm Time — две закрытые пере­менные, которые содержат значения свойств CountDown и AlarmTime. Пока запущен Alarm, переменная Running равна True, и она объявлена вне всех процедур, чтобы все они могли обращаться к ее значению. Переменная startTime устанавливается равной времени начала отсчета и используется, когда элемент управления не считает в обратном направлении (дальше будет видно, как это используется).

Чтобы сделать заготовки для свойств элемента управления с помощью команды Add Procedure, выполните следующие действия.

1. Переключитесь в окно UserControl и выполните двойной щелчок на форме, чтобы открыть окно Code.

2. Выберите команду Add Procedure меню Tools, чтобы открыть диалоговое окно Add Procedure.



3. Введите имя свойства CountDown и выберите тип Property. В окно кода будут вставлены следующие строки.

Public Property Get  CountDown() As Variant

End Property

Public Property Let  CountDown(ByVal vNewValue As    Variant)

End Property

4. Измените тип свойства, чтобы он соответствовал объявлению, а затем введите строки кода для вставленных ранее процедур.

Public Property Get CountDown() As Boolean

CountDown = m_CountDown

End Property

Public Property Let CountDown(ByVal vNewValue As Boolean)

m_CountDown = vNewValue

End Property

Примечание

Приведенный код совершенно тривиален. Все процедуры Property ставят в соответствие закрытой переменной название свойства и имеют одинаковую структуру. Нужно не забывать только изменять их типы с Variant на требуемый.

5. Сделайте то же самое для переменной AlarmTime. Процедуры для этого свойства имеют следующий вид.

Public Property Get AlarmTime() As Date

AlarmTime = m_AlarmTime

End Property

Public Property Let AlarmTime(ByVal vNewValue As Date)



If IsDate(vNewValue) Then m_AlarmTime = vNewValue

End Property

Последняя процедура проверяет правильность значения свойства, чтобы удостовериться, что введено допустимое время. Если введена дата, то программа предполагает, что время равно 00:00:00 (полночь).

6. Теперь можно добавить два метода. В окне Code выберите команду Add Procedure меню Tools. В открывшемся диалоговом окне Add Procedure введите название метода StartTimer, но на этот раз установите переключатель в Sub. В код будут вставлены следующие строки.

Public Sub StartTimer()

End Sub

7. В подпрограмме StartTimer() введите код для запуска таймера.

Public Sub StartTimer()

If Not Running Then

Timer1.Enabled = True

Running = True

startTime = Time

If Time = m_AlarmTime > 0 Then NextDay = True

Label1.Caption = "00:00:00"

End If

End Sub

Эта подпрограмма ничего не делает, если таймер уже запущен. Если таймер не запущен, то подпрограмма инициализирует элемент управления Timer и устанав­ливает значение переменной startTimer равным текущему времени, а изображение в "00:00:00". Переменная Running устанавливается в True, чтобы предотвратить повторное выполнение этой подпрограмм, когда таймер уже запущен. Переменная NextDay устанавливается в True, если время срабатывания сигнала меньше текущего времени. Это означает, что элемент управления должен сработать в заданное время на следующий день.

8. Снова выберите команду Add Procedure меню Tools, чтобы создать еще одну общедоступную подпрограмму — метод StopTimer(). Ниже приведен код для этой подпрограммы.

Public Sub StopTimer()

If Running Then

Timer1.Enabled = False

Running = False

End If

End Sub

Так же как и в методе StartTimer, таймер останавливается только в том случае, если он был запушен. В этом случае код отключает элемент управления Timer и устанавливает переменную Running в False.

9. Теперь добавьте событие элемента управления. Выберите команду Add Procedure меню Tools, чтобы открыть диалоговое окно Add Procedure.



10. Введите имя TimeOut и выберите переключатель Event. После этого к коду добавится еще одна строка.

Event TimeOut()

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

RaiseEvent TimeOut

Событие TimeOut вызывается из кода элемента управления

Timer (мы позна­комимся с ним позже).

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

Alarm, нечто похожее было сделано ранее с помощью мастера интерфейса элемента управления ActiveX. На этот раз все элементы интерфейса элемента управления были добавлены вручную с помощью меню Tools. Проще позволить мастеру сформировать элемент управления автоматически, но знание того, как это можно сделать вручную, поможет добавить несколько свойств к существующему элементу управления без выполнения всех шагов мастера интерфейса элемента управления ActiveX.

Совет

Если запустить мастер интерфейса элемента управления

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

Команда Add Procedure не добавляет соответствующие строки в события ReadProperties и WriteProperties — их следует добавить вручную.

Программа 16.15. Сохранение и чтение свойств элемента правления Alarm

Private Sub UserControl ReadProperties(PropBag As PropertyBag)

CountDown = PropBag.ReadProperty ("CountDown", CountDown)

m_AlarmTime = PropBag.ReadProperty ("AlarmTime", AlarmTime)

End Sub

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)

PropBag.WriteProperty "CountDown", m_CountDown, False

PropBag.WriteProperty "AlarmTime", m_AlarmTime, 0

End Sub                                   __ ___ ___ ___ __

В заключение, нужно добавить следующий ниже код, также вручную, для инициализации значения свойства.

Private Sub UserControl InitProperties()

m_CountDown = True

Running = False

End Sub


Конструирование элемента управления ActiveX


Откройте новый проект ActiveX, выполнив следующие действия:

1. Выберите команду New Project меню File.

2.  В окне New Project выберите пиктограмму ActiveX Control. Visual Basic создаст новый проект под названием Project!, который содержит элемент управления с именем UserControll.

Начальные установки для элемента управления ActiveX показаны на рис. 16.3 (имена в окне проекта отличаются, ниже будет показано, как их изменить).

Рис 16.3. Проект элемента управления ActiveX содержит вместо формы элемент управления.

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

1. Выберите Project1 в окне Project и, когда появятся его свойства, измените свойство Name на FLEXLabel.

2. Выберите UserControll в окне Project и, когда появятся его свойства, измените свойство Name на Label3D.

Совет

Каждый раз, когда элемент управления ActiveX помещается на форму, его имя представляет собой соединение названия элемента управления и соответствующей цифры. Первый экземпляр элемента управления, помещенного на форму, будет назван Label3D1, следующий будет назван Label3D2 и так далее.

Только что вы познакомились с новым объектом —

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

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

Мастер интерфейса элемента управления ActiveX


Выберите меню Add-Ins и в открывшемся диалоговом окне выберите строку ActiveX Control Interface Wisard, чтобы открыть мастер. Этот мастер поможет соз­дать новый элемент управления ActiveX. Он создаст интерфейс элемента управления (свойства, методы и события) и приготовит его основной код. Останется только подготовить код, который рисует надпись и реализует еще несколько возможно­стей, которые не могут быть автоматизированы. Мастер сделает большую часть работы. Он имеет шесть окон, назначение которых будет вскоре объяснено.

Если мастер в меню Add-Ins отсутствует, выберите меню Add-In Manager и в диалоговом окне сделайте двойной щелчок на строке VB6 ActiveX Control Interface Wisard. Напротив, в колонке Load Behavior, появится, как показано на рис. 16.4, слово Loaded. Теперь нажмите ОК., и данный мастер появится в меню Add-Ins.

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



Рис. 16.4. Диалоговое окно Add In Manager

Введение

Первый экран мастера — приглашение, появление которого можно потом отключить, отметив флажок "Skip this screen in future". Для начала процесса конст­руирования интерфейса создаваемого элемента управления нажмите кнопку Next.



Выбор элементов интерфейса

Следующее окно мастера предлагает выбрать стандартные части элемента управления ActiveX Слева — список стандартных свойств, методов и событий, которые можно включить в конструируемый элемент. Справа — список уже выбранных свойств, методов и событий интерфейса. Visual Basic предполагает, что конструируемый элемет управления должен поддерживать выбранные свойства.



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



Appearance

Font

MouseMove

OLEGive Feedback

Backcolor

ForeColor

Mouse Pointer

OLESetData

Backstyle

HOC

Mouse Up

OLEStartDrag

BoiderStyle

HWnd

OLEDrag

Picture

Click

Key Down

OLEDragDrop

Resize

DblClick

KeyPress

OLEDragOver

Enabled

Key Up

OLEDropMode

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

Создание специальных частей интерфейса



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

1. Нажмите кнопку New, чтобы отобразить диалоговое окно Add Custom Member.



2. В поле Name введите Caption (это название свойства) и включите флажок Property.

3. Нажмите ОК. Имя первого заказного свойства теперь отображено в окне My Custom Members.

4. Повторите шаги 1—3, чтобы добавить свойства Effect и TextAlignmem.

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

Установка соответствия компонентов интерфейса



Это окно используется для установки соответствия между некоторыми свойствами специального элемента управления и свойствами так называемых конституэнтных (constituent) элементов управления. Конституэнтными являются стандартные элементы управления VB, используемые при конструировании специального элемента управления ActiveX. Предположим, что элемент управления содержит элемент Label, и желательно, чтобы фон элемента управления Label стал фоном конструируе­мого элемента управления (или цвет символа, например).

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



Следует установить соответствие между всеми компонентами (свойствами, методами и событиями), которые вы не желаете обрабатывать собственным кодом, и соответствующими компонентами объекта

UserControl. Событие Click — типичный пример. Нет необходимости в определении какой-либо реакции на щелчок внутри самого элемента управления, нужно передать событие главному приложению, чтобы обработать его соответствующим образом. Для отображения свойства выполните следующие действия.

1. Из списка Public Name выберите свойство или событие.

2. Щелкните на раскрывающемся списке и выберите UserControl Мастер немед­ленно выберет компонент объекта UserControl с тем же именем.

3. Отобразите все элементы нового элемента управления (исключая уникальные для данного элемента управления части) на эквивалентные компоненты объекта UserControl.

4. Нажмите кнопку Next.

Установка атрибутов



В этом окне можно установить атрибуты новых компонентов (или, если это необходимо, изменить атрибуты, заданные по умолчанию, хотя это и не рекомен­дуется). Компоненты, которые уже были отображены, не будут показаны в этом списке. Мастер объявляет все новые свойства как Variant, поскольку невозможно установить их типы только по именам. Однако свойства TextAlignment и Effects должны быть целыми числами, a Caption — строкой.

Для того чтобы установить атрибуты, выполните следующие действия.

1. В поле Public Name выберите TextAlignment.

2. Выберите из раскрывающегося списка Data Type тип Integer.

Обратите внимание на возможность устанавливать значение свойств по умолчанию.

3. В поле Default Value введите значение 4. Это — значение, которое отображается по умолчанию в окне свойств для элемента управления FLEXLabel. Как будет показано ниже, можно назначить пользовательские типы данных для свойств.

4. Повторите шаги 1—3 для свойства Effects. Установите тип данных Integer и значение по умолчанию 2 (тисненый).

Совет

Не забудьте снабдить коротким описанием каждое свойство в поле Description. Эти описания отображаются внизу окна свойств, когда пользователь выбирает свойство. Стандартные элементы уже имеют описание, а для пользовательских свойств необхо­димо его составить.



В поле Arguments можно указать параметры событий. Этот проект не имеет никаких собственных событий, но пример таких событий будет приведен позже в этой главе

Обратите внимание, что свойства могут различаться в режиме выполнения и в режиме конструирования. Если предполагается, что разработчику не нужно выполнять выравнивание или применять какие-либо эффекты во время выполнения, то необходимо для соответствующих свойств установить атрибут Read-Only at runtime (Только для чтения во время выполнения).

Завершение



Чтобы сгенерировать элемент управления, в этом окне предлагается нажать кнопку Finish. Оставьте отмеченным флажок View Summary Report (Показать итоговый отчет).

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

Элемент управления FLEXLabel создан. Он делает не так много (нами ведь еще даже не введен код, отображающий надпись), но можно испытать его поведение как элемента управления. На данный момент элемент управления имеет собственную страницу свойств и может быть помещен на форму.

На экране нет ничего, за исключением формы. Эта — объект UserControl, который является формой во всех отношениях. Появилась также новая пиктограмма на панели элементов управления. Эта пиктограмма представляет новый элемент управления. Значок с изображением матрицы и ручки по умолчанию дается всем элементам управления ActiveX. Для того чтобы поменять значок, нарисуйте новую картинку (Bitmap) и свяжите ее со свойством ToolboxBitmap объекта UserContiol. Давайте сначала удостоверимся, что элемент управления работает, а затем настроим его. Пиктограмма элемента ActiveX заблокирована, поскольку элемент управления все еще конструируется. Он не может быть активизирован во время конструирования.


Конструирование элементов управления


ActiveX

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

Стандартное приложение содержит главную форму и несколько вспомогательных. Вспомогательные формы обычно поддерживают главную, получая данные, вводимые пользователем, которые обрабатываются кодом главной формы. Можно считать элемент управления ActiveX главной формой, а окно его свойств и страницы свойств — вспомогательными формами.

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

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


Конструирование элементов управления ActiveX похоже на конструирование формы. При этом элементы располагаются на объекте, называемом UserControl, который является формой элемента управления. Он предусматривает примерно те же методы, что и стандартная форма, например, методы Print, Line и др.

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

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

Рассмотрим пример элемента управления TextBox в режиме конструирования. У него есть свойство Text со значением Textl. Если установить его свойство MultiLine в значение True, а свойство Scrollbar — в Vertical, то к элементу автома­тически будет присоединена вертикальная полоса прокрутки. Значит, эти свойства имеют некоторые значения в режиме конструирования. Запустите приложение и введите некоторый текст в элемент TextBox. Если проект снова вернуть в режим конструирования, свойство Text опять примет значение Textl. Элемент управления сохраняет информацию о свойствах при переключении из режима конструирования в режим выполнения, а при переключении обратно - восстанавливает информацию.



Этот двойной режим — нечто новое для программистов на

Visual Basic, и следует к этому привыкнуть. При конструировании собственного элемента управления ActiveX нужно также переключаться между функциями разработчика элементов управления ActiveX (программист, который конструирует элемент) и разработчика приложения (программист, который использует этот элемент).

Одним словом, элемент управления ActiveX — это приложение с видимым пользовательским интерфейсом. Видимый пользовательский интерфейс - это то, что видит разработчик, когда помещает экземпляр элемента управления на форму, которая, в свою очередь, также есть то, что видит разработчик при запуске проекта. Разработчик может манипулировать элементом управления через свойства, предоставляемые элементом (во время конструирования) и методами (во время выполнения). Свойства и методы вместе образуют невидимый интерфейс. Таким образом, разработчик элементов управления ActiveX конструирует видимый интерфейс на объекте UserControl, который почти идентичен объекту формы. Этот процесс похож на создание обычного приложения. Конструирование же невидимого интерфейса подобно конструированию модуля класса.


Конструирование страниц свойств


Элементы ActiveX могут иметь страницы свойств. Страницы свойств подобны окну свойств, которое позволяет разработчику (программисту, который использует элемент управления в проекте VB) устанавливать новые значения свойств. Но в отличие от окна свойств, страницы свойств предлагают лучший и более гибкий интерфейс с пользователем для настройки элемента управления, включая мгно­венную визуальную обратную связь.

Рис. 16.9. Страницы свойств для настройки TabStnp

Страницы свойств представляют собой набор инструментов конструирования Рис. 16.9 показывает страницу свойств для элемента управления TabStrip. Посред­ством этого интерфейса можно настраивать элемент управления TabStrip способами, которые просто невозможно реализовать, используя только окно свойств. Свойства, которые можно изменять посредством окна свойств, применяются ко всему элементу в целом, а возможности изменить заголовки и вид отдельных закладок, их номера и т.д. отсутствуют. Страницы свойств этого элемента управления содержат отдельные страницы (General, Tabs, Font, Picture), на которых сгруппи­рованы связанные атрибуты.

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



Контекстное меню элемента управления


OLE

Существует еще один способ внедрения объектов в элемент управления OLE Container с помощью контекстного меню управления. Если выполнить правый щелчок на элементе управления OLE Container в процессе работы, то на экране появится контекстное меню (рис. 14.8). Его можно использовать для вставки нового объекта или редактирования уже встроенного документа (если элемент управления уже содержит объект). Чтобы встроить (или связать) другой объект в OLE Container, необходимо сначала удалить существующий объект.

Наличие тех или иных команд в контекстном меню зависит от состояния выбранного объекта. Контекстное меню, показанное на рис. 14.8, содержит команды Edit (Редактировать) и Open (Открыть), так как выбранный объект является доку­ментом Word. Если встроенный объект - звуковой файл, то контекстное меню будет содержать команды Edit (Редактировать) и Play (Воспроизведение). Если же элемент управления не содержит никаких объектов (поскольку разработчик щелкнул на кнопке Cancel в диалоговом окне Insert Object), то команды Edit (Редактировать) и Open (Открыть), наличие которых определяется содержимым окна элемента управления, в сокращенном меню будут отсутствовать.

Рис. 14.8. Чтобы вывести на экран контекстное меню элемента OLE Container во время разработки проекта, выполните на нем правый щелчок

Контекстное меню элемента OLE Container может содержать некоторые из перечисленных ниже команд (или все).

•  Cut (Вырезать). Копировать объект, находящийся в контейнере, в буфер обмена и очистить контейнер.

• Copy (Копировать). Копировать объект, находящийся в контейнере, вбуфер обмена.

•  Paste (Вставить). Вставить объект из буфера обмена в элемент управления.

•  Delete (Удалить). Удалить OLE-объект из элемента управления.

• Insert Object (Вставка объекта). Удалить существующий объект и открыть диалоговое окно Insert Object (Вставка объекта), чтобы пользователь мог вставить новый или уже существующий объект в элемент OLE Container.

•  Paste Special (Специальная вставка). Открыть диалоговое окно Paste Special, которое позволяет вставить объект, скопированный в буфер обмена из другого OLE-совместимого приложения. Команда Paste позволяет встроить объект в элемент управления, а команда Paste Special позволяет создать связь с объектом, находя­щимся в буфере обмена. Диалоговое окно Paste Special выглядит так же, как и диалоговое окно Insert Object (Вставка объекта) с той лишь разницей, что опции диалогового окна Paste Special воздействуют на объект, находящийся в данный момент в буфере обмена.




•  Create Link (Создать связь). Создать связанный объект Доступно, если установлено свойство SourceDoc элемента управления OLE Container.

•  Delete Link (Удалить связь). Удалить связь, преобразуя связанный объект во встроенный.

•  Create Embedded Object (Создать встроенный объект). Создать встроенный объект. Появляется в том случае, если установлено значение свойства SourceDoc или Class.

Примечание

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


Метод


Create TextFHe

Этот метод создает новый текстовый файл и возвращает объект TextStream, который используется для чтения текста из файла или записи его в файл. Синтак­сис метода таков

Set TStream =

FSys.CreateTextFile(filename, overwrite, Unicode)

Аргумент

filename определяет имя создаваемого файла и является единственным обязательным аргументом; overwrite — булево значение, показывающее, можно ли обновлять (перезаписывать) существующий файл (True), или нет (False). Если опустить аргумент overwrite,

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

то создается ASCII-файл.

Чтобы создать новый текстовый файл, необходимо создать переменную типа FileSystemObject, а затем вызвать метод CreateTextFile.

Set TStream =

FSys.CreateTextFile ("с:\testfile.txt")

Переменная

TStream представляет объект TextStream, методы которого позволяют писать в указанный файл или читать из него (см. параграф "Методы объекта TextStream" далее в этой главе).


OpenTextFile

Метод OpenTextFile предназначен для открытия существующего файла. Он имеет следующий синтаксис.

FSys.OpenTextFile(filename, lomode, create, format)

Данный метод открывает существующий файл и возвращает объект TextStream, который использоваться для чтения из файла или записи в него. Filename —

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

Таблица 20.1. Допустимые значения аргумента iomode метода OpenTextFile

Константа

Значение

Описание

ForReading ForAppending

1

2

Файл открывается для чтения

Файл открывается для добавления новых данных

Необязательный аргумент create —

булево значение, показывающее, будет ли создан новый файл при отсутствии указанного в filename.

Если значение этого аргумента - True, новый файл создастся. Последний аргумент format

также необя­зателен и принимает значения True (файл открывается в Unicode-формате) или False (файл открывается в ASCII-формате). Если опустить аргумент format, то файл откроется в ASCII-формате.

Чтобы открыть объект TextStream для чтения, используйте следующий оператор.

Set TStream = FSys.OpenTextFile ("С:\testfile.txt", ForReading)

Метод OpenTextFile возвращает объект TextStream, методы которого позволяют писать в заданный файл или читать из него.

Теперь, когда уже ясно, как используется объект

FileSystemObject для открытия и создания файлов, ознакомимся с объектом TextStream, который позволяет читать из файла и писать в него. Объект FileSystemObject включает много других методов, позволяющих обращаться к различным устройствам, копировать и удалять файлы или целые папки и т.д. О методах объекта FileSystemObject мы расскажем чуть позже, а сейчас рассмотрим манипулирование текстовыми файлами с помощью объекта TextStream.



Методы элемента управления


Data

К встроенным функциональным возможностям элемента управления Data, которые действительно впечатляющи, можно обращаться из кода приложения, используя методы Data. Самые простые методы — это методы перемещения, соот­ветствующие действиям четырех кнопок перемещения.

•  MoveFirst. Перемещает элемент управления на первую запись.

•  MoveLast. Перемещает элемент управления на последнюю запись.

• MovePrevious. Перемещает элемент управления на предыдущую запись.

• MoveNext. Перемещает элемент управления на следующую запись.

Эти методы используются для реализации кнопок перемещения. Однако, при этом, необходимо помнить о трех частных случаях: (1) когда Data позиционируется на первую или последнюю запись; (2) когда нажата кнопка Previous, в то время как Data находится на первой записи; (3) когда нажата кнопка Next, в то время как Data находится на последней записи.

VB6 в действии: проект Data2

Приложение Data2 подобно приложению Datal, но использует другую базу данных. База данных BIBLIO, поставляемая с Visual Basic, содержит названия книг, фамилии издателей и авторов. Структура этой базы показана далее в этой главе, а в этом приложении сформирован интерфейс для управления таблицей Titles, которая содержит поля Title (Название), ISBN (Издательский код), Description (Описание), Subject (Предмет), Comments (Примечания) и многое другое. Форма приложения Data2 изображена на рис. 17.5.

Рис. 17.5 Приложение Data2 методы Data для реализации кнопок прокрутки

Форма разрабатывается достаточно просто. Для этого выполните следующие действия:

1. Поместите элемент Data и соедините его с базой данных BIBLIO, задав в свойстве DatabaseName путь к базе данных в системе, а в свойстве RecordSource — таблицу Titles.

2. Разместите на форме элементы управления, связанные с данными, и подключите их к Data, установив в их свойствах DataSource значение Datal и в свойствах Datafield - отображаемые поля.

Программа для кнопок First и Last вызывает соответствующий метод перемещения.


Программа 17.1. Кнопки First и Last

Private Sub FirstBttn_Click ()

Data1.Recordset MoveFirst

End Sub

Private Sub LastBttn Click()

Data1.Recordset.MoveLast

End Sub

Код для двух других кнопок немного сложнее, поскольку он написан с учетом свойства

EOF элемента управления.

Программа 17.2. Обработка щелчка на кнопке Next

Private Sub NextBttn_Click()

Data1.Recordset.MoveNext

If Data1.Recordset.EOF Then

MsgBox "You are on the last record"

'(Вы находитесь на последней записи)

           Data1.Recordset.MoveLast

End  If

End Sub

Программа перемещается на следующую запись, а затем проверяет свойство EOF. Если EOF равно True, то элемент управления Data переместился на запись, располо­женную за последней. Программа отображает сообщение, что достигнута последняя запись, и затем возвращается на нее.

Примечание

Переход на запись, находящуюся за последней, допустим. Это пустая запись, которую можно отредактировать и добавить к таблице. Проблема возникнет, если снова щелкнуть на кнопке Next. Попытка переместиться далее вызовет ошибку исполнения программы. Именно поэтому необходимо обработать эту ситуацию сразу, если выполняется условие EOF = True. Заметьте: когда отображается сообщение, поля пусты. Обычно необходимо выдавать сообщение при перемещении на последнюю запись. Данный же пример показывает, что после последней записи в RecordSet действительно имеется пустая запись.

Код для кнопки Previous такой же. Он вызывает метод MovePrevious, а вместо свойства EOF проверяет свойство BOF элемента управления Data.

Программа 17.3. Кнопка Previous

Private Sub PreviousBttn_Click()

Data1.Recordset.MovePrevious

If Data1.Recordset.BOF Then

MsgBox "You are on the first record"

'(Вы находитесь на первой записи)

Data1.Recordset.MoveFirst

End If

End Sub

Методы поиска записей

В дополнение к методам перемещения элемент управления Data предоставляет четыре метода для поиска записей в RecordSet. Одна из основных операций, которые выполняются над базами данных — нахождение требуемых записей. Следующие методы осуществляют нахождение записей, удовлетворяющих заданным критериям.



•  FindFirst. Находит первую запись;

•  FindLast. Находит последнюю запись;

•  FindNext. Находит следующую запись;

•  FindPrevious. Находит предыдущую запись.

Эти методы находят в RecordSet любую запись на основе критериев, заданных пользователем. Синтаксис всех этих методов одинаков.

RecordSet.FindFirst criteria

Параметр

criteria — строковое выражение, определяющее отношение между значениями полей и константами. Следующее выражение находит первую запись в RecordSet, поле State которой равно NY.

Datal.RecordSet.FindFirst "State = 'NY' "

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

Datal.RecordSet.FindFirst "InvoiceDate > '12/31/1996'._

And Invoice >= 1000"

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

Recordset.FindFirst "Title LIKE '*SQL*' "

Строка *SQL* — это шаблон для нахождения любого количества символов до и после символов SQL. Другими словами, он соответствует заголовкам типа:

Введение в SQL, Овладение SQL-методами или SQL: Руководство пользователя.

Как работает метод Find

В данном случае поиск методом Find был выполнен без учета регистра. Таким образом, параметр *SQL* соответствовал SQL, sql и Sql. Для изменения заданного по умолчанию режима поиска на сравнение без учета регистра используйте следующий оператор:

Option Compare Text

Для сравнения с учетом регистра используйте другой оператор:

Option Compare Binary

Выражение Option Compare помещается в объявлениях форм или в модуле.

При вызове метода Find (Поиск) Visual Basic находит запись, соответствующую заданным критериям и устанавливает элемент Data на эту запись. В программе, однако, необходимо сначала проверить значение свойства NoMatch, которое устанавливается в False, если запись найдена, и в True — в противном случае. Следующий фрагмент программы показывает, как используются методы Find.



Data1.RecordSet.FindFirst "City= ' Berlin' "

If Data1.Recordset.NoMatch Then

MsgBox "No such record found"

' (Запись не найдена)

Else

MsgBox Datal.Recordset.Fields ("Country")

End If

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

VB6 в действии: проект FindDemo

Приложение FindDemo демонстрирует поиск записей в RecordSet с помощью метода Find. Эту небольшую утилиту можно использовать в ваших приложениях. Первый элемент управления ComboBox позволяет выбрать таблицу, а второй элемент ComboBox — поле. Затем в текстовом поле Search For можно ввести пара­метры для операции поиска и, нажимая кнопки, найти записи, удовлетворяющие заданным критериям. (Программа, позволяющая извлекать имена таблиц из базы данных NWIND и имена полей из выбранной таблицы, приведена в параграфе "Отображение баз данных" далее в этой главе.)



Рис. 17.6. Приложение FindDemo: использование методов Find

Как видно из рис. 17.6, можно определить дополнительные поля в параметре поиска, помимо выбранного в ComboBox. Любые строковые константы в поле Search For должны быть заключены в одинарные кавычки. В качестве альтернативы можно написать процедуру, которая заменяет двойные кавычки в строке одинарными..

Если запустить приложение FindDemo, то появятся столбцы, отличающиеся от показанных на рис. 17.6. Указатель мыши на разделительной линии между двумя столбцами связанного с данными элемента управления Grid (Сетка) превращается в двойную стрелку, указывая, что можно изменять размеры столбца. На рис. 17.6 некоторые столбцы с ненужными данными удалены (их ширина равна нулю), а размеры остальных столбцов изменены, чтобы отобразить данные, представляющие интерес (контактные имена и города).

Форма приложения FindDemo содержит связанный с данными элемент управ­ления Grid и невидимый элемент управления Data. Элемент управления Grid рассмотрен далее в этой главе. Вы увидели, что он может быть связан с элементом Data и отображает содержимое RecordSet в табличном виде. Код, обеспечи­вающий заполнение данными обоих элементов управления ComboBox, приведен в параграфе "Доступ к. полям в объекте RecordSet" этой главы.



Программа 17.4. Кнопка Find First

Private Sub firstBttn_Click()

On Error GoTo SQLError

Data1.Recordset.FindFirst GenerateSQL()

If Data1.Recordset.NoMatch Then

MsgBox "No such record found"

  '( He найдено ни одной записи)

End If

Exit Sub

SQLError:

MsgBox Err.Description

End Sub

Функция GenerateSQL(). Эта функция генерирует параметр поиска для всех операций Find. Значение, возвращаемое функцией GenerateSQL(), используется совместно методами Find. После вызова метода FindFirst программа проверяет свойство NoMatch. Если оно равно True, то программа выводит сообщение. Если запись, соответствующая критерию, найдена, то элемент управления Data автоматически устанавливается на эту запись.

Функция GenerateSQL() извлекает строку из текстового поля txtsearchValue, присоединяет ее к выбранному полю и возвращает строку, использующуюся как параметр метода Find. Большая часть кода приложения обрабатывает потен­циальные ошибки. Основная работа выполняется функцией GenerateSQL(), которая формирует критерии поиска, как показано ниже.

Программа 17.5. Функция GenerateSQL()

Private Function GenerateSQL() As String

GenerateSQL = cmbFields.Text & " " & txtsearchValue

End Function


Методы объекта


Wscript

Объект Wscript имеет несколько методов, большая часть которых подобна функциям VBScript. Наиболее важные методы — CreateObject и GetObject — аналогичны функциям VBScript с такими же именами Рассмотрим методы Wscript.

Echo. Отображает одно или более значений в окне сообщений. Можно отобразить синоним имени Windows Scripting Host, воспользовавшись функцией MsgBox().

Wscript.Echo Wscript.Name

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

Wscript.Echo "string argument", Wscript.Name, 98.9+1

Свойство Name заменено его значением, а выражение 98, 9+1 - вычислено

Рис. 20.10. Метод Echo отображает несколько значений подряд

Echo — это простой метод и может использоваться в качестве примитивного инструмента отладки Функция

MsgBox() и метод Pop-Up (описан ниже) предос­тавляют гораздо больше возможностей.

Quit. Завершает выполнение сценария и может вернуть код ошибки. Его синтаксис:

Wscript.Quit errorCode

Необязательный аргумент errorCode - возвращаемый код ошибки. По умолчанию этот метод возвращает 0. Код ошибки может использоваться для контроля завершения приложения нормально или с ошибками.


InternetExplorer и элемента управления WebBrowser

Методы элемента управления WebBrowser и объекта InternetExplorer позволяют переместиться к новым или к уже посещенным URL.

GoBack, GoForward (Переместиться вперед. Переместиться назад). Эти методы управляют перемещением назад или вперед на один URL в списке посещенных узлов, который поддерживается автоматически элементом управления WebBrowser или объектом InternetExplorer. При попытке перемещения за пределы списка гене­рируется ошибка. Чтобы ее перехватить, необходимо включить код, обрабатывающий данную ошибку.

GoHome, GoSearch (Перейти к домашней странице. Перейти к поиску). GoHome — метод, который перемещает пользователя к домашней странице; GoSearch — метод, который перемещает пользователя к странице, определенной в диалоговом окне Internet Explorer Options.

Navigate (Переместиться).

Этот метод передвигается на URL или открывает HTML-файл, заданный в первом параметре метода. Его синтаксис:

Navigate URL [Flags], [TargetFrameName,] [PostData,] [Headers]

Все параметры, кроме первого, имеют значения по умолчанию. Параметр URL -адрес ресурса, который нужно показать на элементе управления. Параметр Flag — константа или значение, которое определяет, добавить ресурс к списку хронологии, читать или записывать из кэша, и отображать ли ресурс в новом окне. Его значения приведены в табл. 21.1.

Таблица 21.1. Значения параметра Flags

Константа

Значение

Описание

NavOpenlnNew Window

1

Открывать ресурс или файл в новом окне

NavNoHistory

2

Не добавлять ресурс или имя файла к списку хронологии

NavNoReadFrom Cache

4

Не читать из кэша жесткого диска при этом передвижении

NavNo Write To Cache

8

Не записывать результаты передвижения в кэш жесткого диска

Параметр Target FrameName - имя фрейма, в котором отображается документ. Если документ, отображенный на элементе управления WebBrowser, содержит фреймы, то можно отобразить новый документ в одном из существующих фреймов.




Document

Объект Document поддерживает несколько методов, которые позволяют работать с его содержимым.

Open (Открыть).

Открывает документ для вывода. Текущий документ очищается, а новые строки помещаются в документ с помощью методов Write и WriteLn.

Примечание

Метод Open объекта Document открывает текущий документ для вывода и не имеет ничего общего с методом Open объекта Window, который запускает новый экземпляр Internet Explorer и отображает в нем документ.

Write string (Записать строку). Записывает значение строковой

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

WriteLn string.

Записывает строковую переменную в текущий документ с управ­ляющим символом "новая строка", добавленным в конец строки. Управляющий символ игнорируется броузером, так что строковый метод WriteLn работает так же, как метод Write string.

Close (Закрыть).

Закрывает документ и заставляет всю информацию, записанную в него с помощью методов Write и WriteLn, отображаться как в HTML-документе, загруженном в окне броузера.

Clear (Очистить).

Очищает содержимое документа.

Использование методов объекта Document

Описанные методы позволяют программисту (или Web-дизайнеру) с помощью сценария создать HTML-документ, что и показано в примере

Pagel.htm следую­щего параграфа. Методы объекта Document обычно вызываются в следующем порядке.

Document.open

Document.write string

........

Document.write string

Document.close

Переменная string или литеральная константа могут быть чем угодно, что обычно появляется в HTML-документе (текст, HTML-отметки, гиперсвязи и т.д.). Параметр метода Write может содержать HTML-теги, что позволяет создавать Web-страницы на лету. Следующие операторы отображают заголовок первого уровня, расположенный на странице по центру.

Document.write "<CENTER>"

Document.write "<Hl>Welcome to our Active Pages</Hl>"

' (Добро пожаловать на наши активные страницы)




History

Объект History из Scripting Model поддерживает список уже посещенных узлов и предоставляет возможность обращения к ним через методы объекта History, описанные ниже. Объект History не имеет собственных свойств или событий.

Back n (Назад).

Позволяет перемещаться обратно в списке хронологии на п шагов, как при нажатии кнопки Back n раз. Чтобы переместится на предыдущий URL, используется выражение

call Window.History.back(0)

или

call Window.History.back

Forward n (Вперед).

Приводит к перемещению вперед по списку хронологии на п шагов, как при нажатии кнопки Forward n раз.

Go n (Перейти к).

Позволяет переместиться на п-ый

элемент в списке хроно­логии. Следующее выражение осуществляет переход к первому URL в списке.

Window.History.gо 1



Методы объекта TextStream


После создания объекта TextStream с помощью методов CreateTextFile

или OpenTextFile объекта FileSystemObject для чтения и записи в файл можно использовать следующие методы.

Примечание

Как следует из его имени, объект TextStream предназначен только для работы с текстовыми файлами.

Read. Этот метод считывает определенное число символов из объекта TextStream. Его синтаксис:

TStream.Read(characters)

Здесь

characters - количество символов, которые необходимо прочитать.

ReadAll. Этот метод считывает текстовый файл целиком и возвращает текст в виде строковой переменной. Его синтаксис таков.

fileText = TStream.ReadAll

Здесь

fileText - строковая переменная (или типа Variant).

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

fileText = Т Stream.ReadLine

Skip. Этот метод пропускает определенное число символов при чтении из текстового файла. Синтаксис метода следующий.

TStream.Skip(characters)

Здесь

characters - число пропускаемых символов.

SkipLine. Этот метод пропускает следующую строку текстового файла. Его синтаксис таков.

TStream.SkipLine

Символы пропускаемой строки отбрасываются до символа новой строки включи­тельно.

Write. Этот метод записывает строку в TextStream файл. Синтаксис метода:

TStream.Write(string)

Здесь

string — строка (типа String или Variant), записываемая в файл. Строки записываются в файл без вставки пробелов или разделителей между строками. Используйте метод WriteLine для записи символа новой строки или строки, закан­чивающейся этим символом.

WriteLine. Этот метод записывает в файл строку, заканчивающуюся символом новой строки. Синтаксис метода:

TStream.WriteLine(string)

Здесь

string — текст, который необходимо записать в файл. Если вызывается метод WriteLine без аргумента, то запишется символ новой строки.

WriteBlankLines.

Этот метод записывает заданное число пустых строк (символов новой строки) в файл. Его синтаксис:

TStream.WriteBlankLines(lines)

Здесь

lines - число пустых строк, записываемых в файл.



Методы объектов


Scripting

Объекты Scripting также имеют методы. Объект Document, например, имеет метод Write, который позволяет сценарию помещать текст непосредственно на Web-страницу — создавать Web-страницы на лету.

Метод Write воспроизводит строку на текущей странице. Следующий оператор выводит текущую дату на страницу.

Document.Write Date ()

Если использовать HTML, то необходимо жестко запрограммировать дату и модифицировать документ ежедневно. Функция VBScript Date() возвращает текущую дату, но VBScript не предусматривает методы для фактического отображения даты на странице. Чтобы отобразить что-либо на странице из сценария, используются объекты Scripting Model.

Предположим, имеется простой HTML-документ.

<HTML>

<BODY BGCOLOR="#HOOFFOO">

<Hl>Welcome to Visual Basic and the Web</Hl>

</BODY>

</HTML>

Этот документ воспроизводит страницу с зеленым фоном и заголовком первого уровня. Можно создать ту же страницу, используя код

VBScript.

<HTML>

<SCRIPT LANGUAGE = "VBScript">

Document.bgColor = "#HOOFFOO"

Document.Write "<H1> Welcome to Visual Basic and the Web</Hl>"

'(Добро пожаловать в Visual Basic и Web)

</SCRIPT>

</HTML>

В чем преимущества свойства Write для создания страницы? Гибкость. Эта страница фактически сгенерирована на клиентском компьютере. Если необходимо отображать дату и время открытия страницы, то надо добавить следующую строку кода VBScript.

Document.Write "This page was opened on " & date() & _

", at" & time()

  '(Эта страница была открыта... в. . . )

Метод Write предусматривает большую гибкость. Можно написать более сложный VBScript-код для создания на лету сложных страниц. Например, можно запросить пользователя о его имени и индивидуализировать Web-страницу следующим образом.

UserNaine = InputBox("Please enter your name")

' (Введите, пожалуйста, ваше имя)

Document.Write "<Hl>Welcome to our Active Pages," &


UserName & "</HI>"

Реальный заголовок будет отличаться на каждом клиентском компьютере в зависимости от ответа пользователя на запрос. Ниже показана типичная страница, сгенерированная на лету с помощью VBScnpt-кода, который управляет объектами IE Scripting.



Рис. 21.7. Создание HTML-документа на лету: использование метода Write объекта Document

Ниже показан HTML-файл, который создал страницу, приведенную на рис. 21.7.

<HTML>

<HEAD>

<TITLE>Demo Page</TITLE>

SCRIPT LANGUAGE="VBSCRIPT">

UserName = InputBox ("Please enter your name")

'(Введите, пожалуйста, ваше имя)

Document-Write "<Hl>Welcome to our Active Pages, " _

& UserName & "</H1>"

' (Добро пожаловать на наши активные страницы)

Document.Write "<BR>"

Document.Write "This page was opened on " & date() &

", at " & time()

' (Эта страница была открыта...)

</SCRIPT>

</HEAD>

<BODY>

</BODY>

</HTML>

Обратите внимание: этот документ не содержит тега HTML в разделе BODY. Весь документ сгенерирован из раздела сценария страницы командами VBScript.

В следующих параграфах исследуется объект Document из Scripting Model, как наиболее важный объект с точки зрения программиста на VB.


Модули и модули классов


Программные компоненты ActiveX реализованы в Visual Basic в виде модулей классов. Модули существуют в Visual Basic еще с его первой версии. Они содержат объявления переменных и подпрограмм (функций и процедур), которые доступны всем другим компонентам приложения. Многие примеры, приведенные в преды­дущих главах, имеют собственные модули. Функция ConvertTemperature (degrees As Double) может быть вызвана из нескольких мест кода и из многих форм, если ее определить в модуле. Процедуры, хранимые в модуле, могут быть вызваны из любого места приложения. Это также справедливо и для переменных, которые должны быть доступны многим процедурам. Это один из способов, благодаря которому формы и процедуры различных форм могут обмениваться информацией.

Можно рассматривать процедуры, как методы модуля, однако нет потребности предварять их вызов суффиксом в виде имени модуля. Общедоступные (public) переменные, которые находятся в модуле, также могут рассматриваться как свойства модуля. Таким образом, модуль очень похож на класс. В Visual Basic классы реали­зованы как модули специального типа, называемые модулями классов.

Здесь может возникнуть вопрос: "Зачем беспокоиться о классах, если модуль может предоставить функциональные возможности, необходимые для создания приложения?" Если необходимо создать всего лишь несколько процедур и глобальных переменных для одного проекта, то, возможно, лучше разместить их в одном модуле. Однако, если планируется использовать эти же процедуры в

различных проектах, то необходимо конструирование модуля класса. Допустим, несколько функций были реализованы в модуле и протестированы в составе проекта А. Их реализация оказалась вполне удовлетворительной. Если потом создается другой проект — В, который использует тот же модуль, то логика подсказывает, что функциям модуля необходима некоторая переделка. Тогда модуль дополняется несколькими новыми переменными типа public, в результате чего с проектом В он уже работает прекрасно. Но при этом проект А, скорее всего, перестает быть работоспособным. Даже если приказать себе больше не трогать модуль, то как быть в случае групп разработчиков, работающих над общим проектом? Позволить многим программистам иметь доступ к одному модулю из своих проектов, значит ожидать катастрофы. Один из них неизбежно изменит программу и испортит некоторые из существующих проектов.

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

ClassName.VariableName, которое делает свойство уникальным не только в текущем проекте, но и в операционной системе.



Модули VB: краткий обзор


Обычно легче понять новую концепцию, если ассоциировать ее с другой, уже освоенной. Начнем с обзора модулей Visual Basic, а затем посмотрим, как те же концепции могут быть применены к модулям классов. Разработаем небольшое приложение, подсчитывающее время (оно может стать частью другого приложения, которому необходимо вычислять время выполнения своих операций). Приложение должно иметь возможность запускать и останавливать таймер по своему желанию. Когда в приложении выполняется вспомогательный программный код, необходимо иметь возможность приостановить таймер, а затем продолжить отсчет времени. После завершения операции, продолжительность которой определяется, должна быть предусмотрена возможность считывания прошедшего времени. Поместим все необходимые переменные и функции в модуль. При этом его можно будет повторно использовать в других проектах. (Вообще, такая практика является хорошим тоном в программировании — изолировать механизм определения промежутков времени от остального кода и сделать его доступным приложению через вызов нескольких процедур). Приложение, которое будет разработано в этом разделе, называется TimerMod, и его можно найти в папке этой главы на компакт-диске.

Создайте новый проект и добавьте в него модуль. Затем введите в этот модуль следующие строки.

Программа 15.1. Код модуля TimerMod

Public TotalInterval As Double

Dim T1 As Double

Sub StartCounting()

Tl = Time

End Sub

Sub  StopCounting ()

     Totallnterval = Totallnterval + Time – Tl

End  Sub

Sub ResetTimer()

Totallnterval = 0

End Sub

Процедура

StartCounting()

запускает таймер, а процедура StopCounting() — оста­навливает. Каждый раз после остановки таймера переменная Totallnterval

обновляется. Для получения затраченного времени приложение должно прочесть значение этой переменной. И, наконец, процедура ResetTlmer() переустанавливает таймер. Такой механизм отсчета времени не позволяет прочитать затраченное время во время работы таймера. Необходимо сначала вызвать метод StopCounting для обновления переменной Totallnterval,


затем считать значение переменной.

А сейчас перейдите к формам приложения и поместите две кнопки на форму. Установите их заголовки в Start Timing и Show Interval, как показано на рис. 15.1. Затем добавьте следующие строки в содержимое окна кода формы.

Программа 15.2. Код тестирования

TimerMod

Private Sub Commandl_Click()

If Coinmandl.Caption = "Start" Then

StartCounting

Command1.Caption = "Stop"       ' (Остановка)

Else

StopCounting

Command1.Caption = "Start"      ' (Запуск)

End If

End Sub

Private Sub Command2_Click ()

MsgBox "I've been counting for " & vbCrLf & _

Hour(TotalInterval) & "hours" & vbCrLf & _

Minute(TotalInterval) & " minutes and" & vbCrLf & _

Second(TotalInterval) & " seconds" & vbCrLf

' (С начала отсчета прошло... часов... минут и... секунд)

End Sub

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

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

Totallnterval

какое-либо значение:

TotalInterval = 0.00453567

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

TotalInterval = 99



Рис. 15.1. Форма проекта TimerMod

Вероятнее всего, программа будет работать, но она больше не будет правильно информировать о затраченном времени. Другой программист может проигнориро­вать процедуру ResetTimer() и попытаться переустановить переменную Totallnterval из процедуры StartCounting(). Возможно, его действительно не интересует остановка и возобновление процесса отсчета времени и ему удобно переустанавливать пере­менную Totallnterval каждый раз при вызове функции StartCounting(). Его проект будет работать (и с меньшим числом вызовов), но ваш нет. В этом и заключается наиболее важное преимущество в реализации вспомогательных процедур в виде модулей классов — создание компонентов, совместимых со многими приложе­ниями. В дополнение, реализуя механизм отсчета времени отдельно от приложения, можно скрыть детали ее реализации от разработчиков, которые ее используют. Ведь на самом деле не надо знать, как Excel вычисляет сложное математическое выражение в процессе вызова его метода Evaluate.


Наборы записей


RecordSets

RecordSets — это объекты, содержащие множество (коллекцию, набор) записей, выбранных из одной или нескольких таблиц. В программировании базы данных RecordSets аналогичен переменным в обычном программировании. Нельзя обращаться к таблицам баз данных непосредственно. Единственный способ просматривать записи и управлять ими — использование объектов RecordSet. RecordSet состоит из столбцов и строк, похож на таблицу, но может содержать данные из нескольких таблиц. Содержимое сетки, приведенной на рис. 172, получено из одной таблицы, на основе которой и формируется RecordSet. Такой набор - результат запроса данных, например, просмотр имен заказчиков и суммы их заказов в данном месяце.

Рис. 17.2. Таблица Products базы данных NWIND: выделенная строка — запись в таблице Products

Примечание

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

RecordSet позволяет просмотреть некоторые данные, отобранные из базы данных согласно критериям, определенным пользователем. Существует три типа RecordSets

•  DynaSet (Динамический набор), предназначенный для изменения содержимого базы данных;

•  SnapShot (Моментальный снимок), являющийся статическим набором записей (только для чтения);

•  Table (Таблица), которая напрямую обеспечивает просмотр таблиц.

DynaSet и SnapShot обычно создаются с помощью SQL-операторов (Structured Query Language — язык структурированных запросов). SQL-операторы рассмотрены в этой главе позже, а пока запомните, что это — команды, использующиеся для определения критериев отбора данных из базы данных. (Можно использовать SQL-команды для редактирования и создания новых баз данных, но это в книге не рассмотрено). Изменения, вносимые пользователем с помощью DynaSet, находят отражение в исходных таблицах SnapShot позволяет осуществлять только просмотр данных.


Наиболее гибким и мощным типом коллекции записей является

DynaSet, хотя некоторые операции (такие, например, как поиск) могут быстрее выполняться в наборах типа Table. Однако тип Table требует значительных накладных расходов. Наименее гибкий тип - это SnapShot, хотя и наиболее эффективный в смысле накладных расходов (это справедливо только в случае, когда объем выборки невелик – прим. ред). Если модифицировать базу данных не надо - выберите тип SnapShot.

Существует разновидность типа SnapShot - forward-only SnapShot (просмотр вперед, более ограниченный, чем тип SnapShot, но и более быстрый). Forward-only SnapShot позволяет перемещаться по записям только вперед. Он используется в случаях, когда необходимо последовательно просматривать записи (использование их значений для вычислений, копирование выбранных записей в другую габлицу, и так далее). Не предоставляя методов возврата к записям, набор такого типа требует наименьших накладных расходов.

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


Написание и выполнение сценариев


Напишем и выполним простейший сценарий. Сценарий — это текстовый файл с командами VBScript, выполняющий определенную задачу. Напишем сценарий, сообщающий, сколько дней осталось до конца столетия. Запустите Notepad и введите строки программы 20.12.

Программа 20.12. Сценарий YEAR2000.VBS

DaysLeft = #1/1/2000# - Date ()

Message = DaysLeft & " days left for the year 2000"

'(... дней осталось до 2000 года)

MsgBox(Message)

При записи файла YEAR2000.VBS не забудьте выбрать тип All Files в команде Save As Туре. Если этого не сделать, то файл запишется как YEARS2000.VBS.TXT.

Выражение #1/1/2000# — это дата. В VBScript даты заключаются в символы "#". Date() — функция VBScript, возвращающая текущую дату. Ее значение вычи­тается из первого дня 2000 года, а результат сохраняется в переменной DaysLeft.

Для запуска сценария найдите файл YEAR2000.VBS на рабочем столе и выполните двойной щелчок на его значке. Будет выведено следующее окно.

Чтобы закрыть окно, щелкните на кнопке ОК.

Следующий параграф содержит основную информацию о

VBScript: переменных, функциях, операторах управления выполнением программы. Практические примеры не приведены: необходимо изучить основные структуры языка перед написанием какого-либо сценария.



Написание сценариев для


Windows

Можно использовать VBScript и его объект FileSystemObject при написании сценариев непосредственно для Windows. В этом параграфе рассмотрено создание сценариев, запускаемых в Windows 98, и автоматизация многих рутинных задач: подключение принтеров и сетевых драйверов, очистка папок и обработка большого количества файлов в пакетном режиме.

Приведем простой пример пакетной обработки для тех, кто незнаком с командными файлами DOS. Имеются две папки (в терминологии DOS — каталоги) — С:\ТМР и C:\DOCS\TEMP, содержащие временные файлы, которые необходимо удалять раз в день или чаще. Для этого надо выполнить такие команды.

CD С:\ТМР

DEL *.*

CD C:\DOCS\TEMP

DEL *.*

Команда CD (Change Directory) задает переход в другой каталог, а команда DEL *.* - удаляет все файлы в текущем каталоге. Если каталог содержит подкаталоги, то команда DEL *.* не поможет. Придется воспользоваться командой DELTREE.

Синтаксис командных файлов dos особенный. Например, в нем нет команд записи информации в файл (или чтения из файла). Чтобы записать выходную информацию командного файла в текстовый файл, надо воспользоваться символом перенаправления потока ввода/вывода (>). Для сохранения сообщений об ошибках, сгенерированных предыдущим командным файлом, в текстовом файле можно воспользоваться следующей командой (имя командного файла DELTEMP.BAT).

DELTEMP > ERRMSG.TXT

Затем можно прочитать сообщения, открыв файл

ERRMSG.TXT в любом текстовом редакторе.

Командные файлы DOS позволяют инициализировать принтеры, выполнять сетевые соединения, обрабатывать группы файлов и т.д. Любые операции, которые можно задавать в командной строке DOS, можно закодировать в командном файле.

То же самое можно делать в Windows 98. Ранние версии Windows не поддерживали пакетную обработку или языки сценариев, хотя многие пользователи испытывали в них необходимость. Язык сценариев Windows 98 - это VBScript, позволяющий использовать все преимущества системы без дополнительных затрат. Программист на VB готов к разработке сценариев для Windows.

В этой главе рассмотрено использование VBScript для автоматизации выполнения повседневных задач. Приводятся примеры, которые могут служить отправной точкой для написания собственных сценариев. Сначала мы научимся писать и запускать простые сценарии. Затем перейдем к изучению объектов Windows Scripting Host.



Написание сценариев для HTML-страницы


Написание сценариев позволяет контролировать содержимое страницы и управлять им с помощью программы. Первыми двумя языками написания сценариев были JavaScript и VBScript. JavaScript основан на языке Java для рабочих станций SUN, a VBScript — на Visual Basic. В нашей книге используется VBScript.

Сценарий — это короткая программа, которая управляет элементами на странице и вставляется в HTML-документ между тегами

<SCRIPT> и </SCRIPT>. Обычно SCRIPT документа размещается в разделе HEAD. Простой сценарий, который устанавливает цвет фона страницы и отображает приветственное сообщение, имеет следующий вид.

<HTML>

<HEAD>

<TITLE>VBScript Demo</TITLE>

<SCRIPT Language = VBS>

Document.fgColor="hFF0000"

Document.bgColor="h00FFFF"

MsgBox "Welcome to the VBScript Demo Page"

</SCRIPT>

</HEAD>

<BODY>

<Hl>VBScript Demo</Hl>

</BODY>

</HTML>

Элемент

Document задает документ, отображаемый в окне броузера. Доступ к его свойствам можно получить с помощью объекта Document. Свойства fgColor и bgColor задают (или считывают) цвет фона и текста документа. Функция MsgBox() уже известна. Есть много сходства между Visual Basic и VBScript, поэтому нет необходимости подробно рассматривать особенности VBScript.

Предупреждение

И все же имеется существенное отличие: VBScript не является типизированным языком. Как бы вы не объявили переменные, все они будут иметь тип Variant. Это является препятствием при вызове функций Visual Basic (например, объектных методов) из VBScript. Следует использовать функции преобразования данных (см. гл. 2) или заключать аргументы в скобки с целью преобразования типов VBScript и Visual Basic.

Языки написания сценариев, подобные VBScript, позволяют Web-разработчикам создавать динамически изменяющееся содержание их Web-страниц. Но это еще не все. Менее чем через год после появления VBScript, компания Microsoft решила "активизировать" Web-страницы - вот откуда термин ActiveX. Если есть средства программирования Web-страниц, почему бы ни дополнить их программируемыми объектами? Программируемые объекты — не что иное, как элементы управления ActiveX. Если есть возможность разместить элементы управления ActiveX на странице, то можно получить доступ к их методам и свойствам из среды VBScript и, таким образом, создать активную страницу. Активная страница похожа на небольшое приложение, запускаемое из Internet Explorer.

Следующим шагом была разработка элементов управления

ActiveX, которые можно было использовать на Web-страницах. Microsoft выпустила их большое количество. Сейчас с использованием Visual Basic 6 можно создавать свои собственные элементы управления ActiveX для использования на Web-страницах. В следующем параграфе мы протестируем элементы управления, разработанные ранее в гл. 16. В последней части главы рассмотрены DHTML, которые являются теми же HTML, но усовершенствованными с помощью фрагментов VBScript-кода.



Написание сценария для приложения


Если приложение предоставляет классы, то можно добавить элемент управления Script на отдельную форму, например, на ScriptForm, и позволить пользователю приложения создать сценарий. Предположим, вы написали приложение, которое позволяет пользователю открывать файлы с изображениями и сохранять их в различных графических форматах (TIF, JPEG, NPG и т. д.). Пользователь, желающий преобразовать несколько файлов, не должен открывать и записывать каждый файл по отдельности. Ему проще написать сценарий, который в нужный момент открывает файл, преобразовывает его и записывает под другим именем на диск.

Следовательно, ваш класс должен предоставлять методы Open(fllename) для открытия графического файла, Convert(format1, format2)

— для преобразования из одного формата в другой, и SaveAs(filename) - для записи файла в новом формате. Процесс конвертирования формата графических изображений достаточно сложен (это описано в нескольких книгах), но если кратко, то необходимо иметь возмож­ность преобразовывать процедуры в методы и привязывать их к классу.

VB6 в действии: проект StatCIss

Для ознакомления с использованием сценариев в приложениях рассмотрим простой класс, содержащий несколько несложных методов, используемых для вычисления основных статистических характеристик массива данных (рис. 20.6). На самом деле, здесь мы расширяем класс AXStat (см. гл. 15) и с его помощью добавляем возможности сценариев в приложения. Описание класса, который пре­доставляет законченную объектную модель (например, Excel), выходит за рамки этой книги, но приведенный ниже простой класс - пример того, как возможности сценариев добавляются в приложения.

Чтобы использовать класс StatCIss в проекте SEditor, необходимо выполнить следующие действия.

1. Откройте проект SEditor и добавьте новый модуль класса.

2. Запустите новый экземпляр Visual Basic, откройте проект AXStats (папка гл. 15 на компакт-диске) и скопируйте код модуля AXStats.

3. Переключитесь в проект SEditor и откройте окно кода добавленного модуля класса.


4. Добавьте код, скопированный из модуля класса AXStats.



Рис. 20.6. Проект StatCIss: вычисление основных статистических характеристик массива данных

Теперь имеется проект, состоящий из формы ScriptForm, на которой пользователь может вводить и выполнять сценарии, объект DisplayClass и класс AXStats, содер­жащий свойства и методы для вычисления основных статистических характеристик массива данных. Имеет смысл записать компоненты нового проекта в новую папку.

Примечание

Методы класса AXStats возвращают значения типа Double, в то время как VBScnpt является бестиповым языком. Каким образом сценарий взаимодействует с классом AXStats и интерпретирует возвращаемые значения? Можно использовать функции приведения типов, но не ожидайте, что пользователь (который вводит текст сценария) в состоянии выполнить все необходимые преобразования. Проще исправить код класса, удалив все типы. Для этого необходимо открыть окно Code для класса AXStats и удалить все объявления типов (часть As объявления методов и их типов). Для просмотра кода класса AXStats после исправления необходимо открыть проект в среде разработки VB.

Чтобы предоставить пользователю доступ к членам класса

AXStats (и позволить ему разрабатывать сценарии для обработки массивов данных), надо добавить ссылку на класс. Для этого в начало кода ScriptForm добавьте следующее объявление

Private Statistics As New AXStats

Затем добавьте объект Stat в элемент управления Script события Load формы

ScriptControll.AddObject "Stat", Statistics, True

Пользователь приложения получает доступ к членам класса

AXStats с помощью компонентов объектной переменной Stat или их имен. Далее следует небольшой сценарий для вычисления среднего арифметического четырех чисел. Введите следующий код в редактор сценария и щелкните на кнопке Execute Script.

Программа 20.11. Сценарий приложения StatCIss

Add 301

Add 44.50

Add 529

Add 124.5

Show "Mm значение " & Mm

Show "Max значение " & Мах

Show "Среднее      " & Average



Если добавить несколько дополнительных методов для более сложных статис­тических характеристик (стандартное отклонение, корреляцию и т.п.), то пользователи захотят использовать ваше приложение для обработки данных в пакетном режиме. Если добавить ссылку на объект FileSystemObject, то можно будет использовать локальный диск для чтения данных и записи результатов.

В той же папке, что и StatCIss, находятся сценарии

MakeData и Process. Сценарий MakeData создает текстовый файл в корневом каталоге диска С: и записывает туда 100 случайных значений. Сценарий Process открывает указанный файл, добавляет данные к семейству данных класса StatCIss, вычисляет и отображает число элементов данных, их среднее, минимальное и максимальное значения. Чтобы открыть сценарий MakeData, необходимо выбрать в меню File команду Load и выполнить ее, щелкнув на кнопке Execute Script. Затем нужно открыть и запустить сценарий Process..

Совет

В этом проекте есть одна проблема. Оба класса используют метод Clear (один — для очистки набора данных класса AXStat, другой — для очистки нижнего элемента управления TextBox формы). Оператор Clear на самом деле очищает элемент управления TextBox. Дело в том, что в случае конфликта имен, приоритет имеют компоненты класса, добавленного первым. Можно указать конкретный метод с помощью имени класса, задаваемого в префиксе. Для очистки элемента управления TextBox используется оператор Output. Clear, а для очистки массивов данных — оператор Stat. Clear.

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

1. Выберите команду Options меню Tools, чтобы открыть окно Options.

2. Выберите вкладку General.

3. В секции Error Trapping отметьте флажок Break on Unhandled Errors Only (Останов только для необработанных ошибок).

Если эту опцию не установить, то приложение будет прерываться при каждой ошибке (например, при вызове метода Item класса AXStat с ошибочным значением индекса). Включение флажка Break on Unhandled Errors Only позволяет классу ге­нерировать ошибки, которые обрабатываются в коде приложения.

Элемент управления Script - удобное средство для добавления возможностей сценария в приложения, но его обработчики ошибок оставляют желать лучшего. Это его первая версия, возможно, в следующих версиях он будет более гибким. Информацию об этом можно найти на http: //www.microsoft. com/scripting.

Последняя часть главы посвящена написанию сценариев для операционной системы. Windows Scripting Host - еще одна область применения знаний VB, если вы освоились с использованием предоставляемых объектов.


О прилагаемом компакт-диске


Прилагаемый компакт-диск является самозагружаемым - вставьте его в диско­вод, подождите несколько секунд и затем вы сможете:

• скопировать с него авторские примеры на ваш жесткий диск;

• воспользоваться учебным пособием, включающим поучительные примеры разра­ботки приложений на Visual Basic (например, примеры манипулирования файлами);

• инсталлировать и испытать новое программное обеспечение компаний InstallShield, Blue Sky, NuMega и т.п.;

• читать справочную информацию по VB6 в формате Adobe Acrobat;

• усовершенствовать ваши приложения использованием элементов мультимедиа.

Авторские примеры

Эта книга содержит многочисленные примеры, разработанные автором с целью демонстрации возможностей языка Visual Basic, элементов управления ActiveX и принципов программирования вообще. Автор предоставляет вам возможность использовать их в ваших приложениях. Ниже приводится перечень некоторых из проектов.

CDBox. Эта утилита даст вам возможность поэкспериментировать с элементами Common Dilog Box в интерактивном режиме. Воспользуйтесь ей, чтобы выяснить, как настроить диалоговые окна Font или, скажем. File Open и включить их в ваше приложение, не написав и одной строки кода.

DirMap. Это приложение можно использовать для редактирования и печати содержимого любой папки на вашем жестком диске, включая ее подпапки.

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

MDIEdit. Быстрый и наиболее эффективный путь овладения техникой работы с многодокументным интерфейсом (MDI).

RFTPad. Приложение, подобное предыдущему, однако позволяющее формати­ровать и печатать текст.

Globe и TreeViewScan. Позволяют научиться, как заполнять элемент Tree View во время выполнения программ и как сохранять его содержимое на диске.

VBA Sample Code.

Позволяет научиться использовать в ваших программах возможности таких приложений, как Excel, Word и Outlook.


ScriptEdit.

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

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

Программное обеспечение других компаний

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

InstallShield. Express Professional 2.1. 30-дневная версия пакета для создания дистрибутивов.

RoboHelp. HTML 6, позволяющий создавать справочные файлы для VB-прило-жений, работающих в Windows 98.

Smartcheck от компании NuMega. Позволяет не только обнаружить ошибки, но и объясняет, что именно происходит, когда они случаются.

LEADTooIs 10. Это элемент ActiveX, выполняющий более 500 функций работы с графикой.

Adobe Acrobat.

Программное обеспечение, абсолютно необходимое для Web-разработок. Используйте его для чтения учебного пособия на этом CD.

Winzip. Лучшая программа архивирования файлов на сегодняшний день.


Объект


Extender

Объект Extender предоставляет некоторые основные свойства данного элемента управления, такие как Name, Width и Height. Эти свойства поддерживаются непо­средственно операционной системой и при изменении их значения процедура Property Let не вызывается. Как известно, свойство Name элемента управления может быть изменено в любое время, если элемент управления используется в режиме конструирования, но процедура Property для этого свойства не существует. Можно выяснить, какое имя назначено пользователем элементу, вызвав свойство Name объекта Extender. Объект Extender является также шлюзом к некоторым

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

Свойство Name. Существует возможность выяснить имя контейнерного элемента управления и его размеры. Можно обратиться к объекту Extender, используя следующий вызов:

UserControl.Extender.extProperty

где

extProperty - имя свойства объекта Extender. Имя заказного элемента управления возвращается следующим ниже выражением.

UserControl.Extender.Name

Примечание

Но действительно ли нужно вызывать объект Extender для выяснения имени элемента управления в самом элементе управления? Не перестарались ли мы? Нет, элемент управления, на самом деле, не знает собственного имени! Пользователь может изменять свойство Name элемента управления в любое время в течение всего конструирования, а для того, чтобы прочитать имя элемента управления, необходимо действительно воспользоваться услугами объекта Extender. Для использования свойств такого типа нет необходимости в методах Property Get и Property Let.

Свойства Width и Height. Эти свойства возвращают размеры элемента управления. Используйте следующие ниже вызовы:

UserControl.Extender.Width

и

UserControl.Extender.Height

Свойства Tag и Index. Это еще два свойства, которые поддерживает Visual Basic. Они не являются свойствами объекта Extender (хотя синтаксис указывает на обратное). Это свойства специального элемента управления, к которым нельзя обратиться непосредственно. Код для поддержки этих свойств не был добавлен, но, тем не менее, они появляются в окне свойств элемента управления. Поскольку их значения поддерживаются самим Visual Basic, то доступ к ним можно получить только через объект Extender.


Ambient

Объект Ambient подобен объекту Extender в том смысле, что он предоставляет информацию об окружении элемента управления. И, фактически,'эти два объекта иногда перекрывают друг друга. Объект Ambient дает коду элемента управления информацию о цвете фона контейнера, шрифте и т.д. Единственное действительно важное свойство объекта Ambient — UserMode, которое указывает на то, действует ли элемент управления в режиме конструирования или в режиме выполнения программы.

Как известно из опыта работы с обычными элементами управления, все элементы управления VB функционируют в режимах конструирования и выпол­нения. Так как элемент управления ведет себя одинаково в обоих режимах, то нет необходимости различать их. При конструировании элементов управления ActiveX, однако, часто необходимо дифференцировать режимы работы в самом коде и реагировать на некоторые события по-разному, в зависимости от того, используется ли элемент управления в режиме конструирования или в режиме выполнения.

Свойство UserMode. Это свойство принимает значение True. когда элемент управления действует в режиме выполнения, или False, когда элемент управления действует в режиме конструирования. Для иллюстрации работы этого свойства попробуем отображать текст "Design Mode", когда элемент находится в режиме конструирования. Откройте код обработчика события Paint и вставьте следующие строки в конец кода.

Программа 16.9. Использование свойства UserMode

Private Sub UserControl_Paint()

DrawCaption

OldFontSize = UserControl.Font.Size

UserControl.Font.Size = 10

If Not Ambient.UserMode Then

UserControl.CurrentX = 0

UserControl.CurrentY = 0

UserControl.Print "Design Mode"

End If

UserControl.Font.Size = OldFontSize

End Sub

Эти операторы определяют, используется элемент управление в режиме конст­руирования или режиме выполнения. В режиме конструирования строка "Design

Mode" отображается в верхнем левом углу, как показано на рис. 16.8. В данном случае необходимы операторы, сохраняющие и восстанавливающие размер шрифта, в противном случае надпись "FLEXLabel Control" будет отображаться тем же маленьким шрифтом, что и строка "Design Mode", либо, наоборот, строка будет отображаться тем же большим шрифтом, что и надпись. Код устанавливает малый размер шрифта, отображает строку и восстанавливает исходный размер шрифта.




Database

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

В приложении Database Structure (рис. 17.24) показаны объекты, описанные в этом параграфе. Сначала рассмотрим объекты, составляющие базу данных, а затем – реализацию приложения Database Structure.

Рис. 17.24. Приложение Database Structure отображает любую базу данных, созданную в Microsoft Access

Объектом верхнего уровня является объект Database, который задает базу данных. Чтобы создать объект Database и задать базу данных, объявите объектную переменную.

Dim DB As Database

Объект Database присваивается переменной DB с помощью функции OpenDatabase, которой в качестве параметра передается путь к существующей базе данных и которая возвращает объект Database.

Set DB = OpenDatabase(dbName)

Параметр

dbName — строка пути к базе данных — может быть свойством FileName элемента управления Common Dialogs. Все объекты, рассмотренные в следующих параграфах, являются свойствами объекта Database.

Каждая таблица в базе данных задается объектом

TableDef, а запрос — объектом QueryDef. Каждый из них имеет собственные свойства, подобные Name (имя таблицы или запроса) и Count (число таблиц в объекте TableDef или количество запросов в объекте QueryDef).




QueryDef: определения запросов

Кроме таблиц, база данных может содержать определения запросов. Запросы, которые обычно используются в базе данных, сохраняются в ней и вызываются по именам. Ко всем запросам в базе данных можно обращаться через объект QueryDefs, подобный объекту TableDef. Объект QueryDefs - это семейство объектов QueryDef, каждый из которых соответствует сохраненному запросу. Из программы можно обращаться к следующим свойствам семейства QueryDefs.

• Count. Возвращает число запросов, сохраненных в базе данных.

• Name. Возвращает имя запроса.

•  SQL. Возвращает SQL-оператор запроса.

Число запросов, сохраненных в базе данных, можно получить с помощью следующего выражения.

DB.QueryDefs.Count

Чтобы обратиться ко всем запросам, сохраненным в базе данных, объявите объектную переменную QueryDef

Dim qry As QueryDef

а затем просмотрите элементы семейства QueryDefs с помощью цикла For Each...Next.

For Each qry In DB.QueryDefs

Debug.Print qry.Name

Next

VB6 в действии: проект DBStructure

Приложение DBStruct (см. рис. 17.24) позволяет открыть любую базу данных и просмотреть имена ее таблиц, их структуру, запросы, сохраненные в базе данных, и их определения. Таблицы и запросы базы данных отображаются в двух списках слева. Под именем каждой таблицы находятся названия ее индексов. Щелкните на имени таблицы, чтобы отобразить ее поля, или на имени запроса, чтобы отобра­зить его определение.

Начнем с кода кнопки Open Database.

Программа 17.14. Кнопка Open Database

Private Sub Command1_C1ick()

On Error GoTo NoDatabase

CommonDialog1.CancelError = True

CommonDialog1.Filter = "Databases|* mdb"

CommonDialogI ShowOpen

' Открытие базы данных

If CommonDialog1.fileName <> " " Then

Set DB = OpenDatabase (CommonDialog1.filename)

Label1.Caption = CommonDialog1.filename

End If

' Очистка элементов управления ListBox

FIdList.Clear

TbiList.Clear

Dim tbl As TableDef

Dim idx As Index

Dim TName As String




File

Объект File задает файл и предоставляет свойства, задающие свойства реального файла, и методы, которые позволяют копировать, перемещать и удалять файлы.

Для создания объекта File и исследования его свойств, выполните следующие действия.

1. Создайте переменную типа FileSystem Object, объявив ее следующим образом:

Dim FSys As New FileSystemObject

либо вызвав функцию CreateObject(), как показано ниже.

Set FSys = Create0b]ect ("Scripting. FileSystemObject")

2. Используйте переменную FSys для создания объекта, задающего указанный файл.

Set file = FSys.GetFile(fileName)

3. Обратимся к свойствам файла с помощью объектной переменной file.

FName = file.Name

FDate = file.DateCreated

FSize = file.Size

Рассмотрим свойства объекта File.

Свойства объекта File

Многие свойства объекта File аналогичны свойствам объекта Folder, который рассматривается в параграфе " Объект Folder" далее в этой главе.

Attributes. Это свойство используется для чтения и установки атрибутов файла. Для чтения используется следующий синтаксис.

thisFile.Attributes

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

thisFile.Attributes = thisFile.Attributes Or new_attribute

Переменная

new_attribute

принимает любое значение, приведенное в табл. 20.2. Для изменения нескольких атрибутов комбинируйте значения с помощью логической операции ИЛИ. Например, следующий оператор

thisFile.Attributes = new_attribute

изменяет заданный атрибут, но при этом очищает все другие. Если файл имеет атрибуты "только для чтения" и "скрытый", то его свойство Attributes равно 3 (1+2 согласно табл. 20.2). Если установить атрибут "архивный", присвоив свойству Attributes значение 32, то другие два атрибута очистятся. Комбинируя новый атрибут (32) и существующие с помощью операции ИЛИ, можно задать файлу одновре­менно атрибуты "только для чтения", "скрытый" и "архивный".

Таблица 20.2. Допустимые значения переменной newattribute




Shell

Объект Shell — это свойство объекта Wscript, предоставляющее доступ к специальным компонентам (переменной среды и специальным папкам), а также к нескольким методам для работы с системным реестром. Рассмотрим свойства объекта Shell. Перед работой с этими свойствами необходимо создать экземпляр объекта.

Set wShell = Wscript.CreateObiect ("Wscript.Shell")




WshShortcut

Объект WshShortcut предоставляет ярлык и позволяет работать с существующими ярлыками и создавать новые. Для создания WshShortcut используются следующие операторы.

Set WShell = Wscript.CreateObject ("Wscript.Shell")

strDesktop = WShell.SpecialFolders ("Desktop")

Set aShortcut = WShell.CreateShortcut(strDesktop & _

"\Encrypt.lnk")

Если файл Encrypt.lnk существует, то переменная aShortcut

предоставляет ярлык на Рабочем столе. Если он не существует, то он будет создан.

Примечание

Новый ярлык не появится, пока он не будет сохранен методом Save.

Свойства объекта WshShortcut и его метод Save рассмотрены в следующих параграфах. Эти свойства соответствуют параметрам, которые устанавливаются на вкладке Shortcut диалогового окна свойств ярлыка (рис. 20.12).

Arguments. Задает аргументы, передаваемые ярлыку.

Description. Задает описание ярлыка.

FullName. Задает полный путь к ярлыку.

Рис. 20.12. Вкладка Shortcut окна Properties

Hotkey. Задает горячую клавишу, запускающую данную программу. Горячая клавиша состоит из модификатора и клавиши. Возможные модификаторы:

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

myShortCut.Hotkey =

"ALT+SHIFT+F"

IconLocation.

Задает место расположения значка для ярлыка. Обычно несколько значков хранятся в одном файле. Формат этого свойства имеет вид: Path,index.

C:\Program Files\NetMeeting\conf.exe 1

Для ярлыка NetMeeting используется первый значок из файла conf.exe.

TargetPath. Задает объект, на который ссылается ярлык.

WindowStyle. Задает стиль окна приложения, на которое указывает ярлык, после того, как приложение запущено. Стили перечислены в табл. 20.10.

Таблица 20.10. Возможные значения свойства WindowStyle

Значение

Описание

0

1

2

Нормальное

Минимизированное

Максимизированное

WorkingDirectory.

Задает рабочий каталог ярлыка.

Save. Сохраняет ярлык в файле, имя которого определяется свойством FullName.




WshNetwork

Объект WshNetwork предоставляет свойства и методы для работы с разделяемыми устройствами (дисками и принтерами) в сети, а также свойства локальных компьютеров (сетевые имена, имена доменов и т.п.). Информация об этом объекте содержится на http://www.microsoft.com.scripting.

Глава 21. Visual Basic и Web

• Объекты для просмотра Web

• Элемент управления WebBrowser и объект InternetExplorer

• Использование гиперссылок в приложениях Visual Basic

• Модель написания сценария Internet Explorer

• Построение элементов управления для использования в Internet

Мы рассмотрели использование VBScript для написания сценария Web-страниц. В этой главе показано слияние рабочего стола и Web, приведены объекты и примеры. Первая рассматриваемая тема - элемент управления WebBrowser, который позволяет отображать HTML-документы в приложениях Visual Basic. При помощи этого элемента управления можно разработать форму для соединения пользователя с Web-узлом (или страницей) и воспроизведения домашней страницы, как с помощью Internet Explorer. Поскольку элемент управления WebBrowser не предусматривает никаких средств навигации, можно ограничить пользователя только собственным узлом (если он не содержит гиперссылки на другие узлы).

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

Элемент управления WebBrowser, как и Internet Explorer, может отображать HTML-страницы, заявленные заблаговременно и находящиеся на сервере (или жестком диске). Можно непосредственно манипулировать документом при помощи объектов Internet Explorer Scripting Object Model. С их помощью пишутся прило­жения Visual Basic, генерирующие код HTML и помещающие его на WebBrowser. Другими словами, возможна разработка приложений Visual Basic, которые генерируют HTML-документы "на лету" и отображают их при помощи элемента управления WebBrowser. Это очень удобно, особенно при разработке средств диалоговых консультаций.

Последняя тема этой главы — создание элемента управления

ActiveX для загрузки информации из Internet. Можно разработать элементы управления ActiveX, которые используют подсоединения к Internet для загрузки информации из сети. В этой главе показано, как это делается. Такие элементы управления называются Internet-enabled, и основной их функцией является подключение к серверу.

Примечание

Другая интересная тема — документы ActiveX. Они были введены с появлением VB5 и являются приложениями, которые могут выполняться в окне Internet Explorer. Доку­менты ActiveX могут запускаться на выполнение дистанционно — через броузер. Но поскольку документы ActiveX — не самые распространенные приложения, разрабаты­ваемые с использованием Visual Basic, эта тема в книге не рассматривается.




InternetExplorer

Объект InternetExplorer позволяет запустить экземпляр Internet Explorer из приложения и манипулировать им с помощью OLE. Он поддерживает те же свой­ства и методы, что и элемент управления WebBrowser, и имеет дополнительные возможности. Кратко рассмотрим свойства и методы этого объекта, но сначала создадим приложение, которое управляет InternetExplorer. (IExplore на компакт-диске).

Рис. 21.2. Страница Calendar.htm, открытая приложением Browser

VB6 в действии: проект Explore

Чтобы установить ссылку на Internet Explorer из проекта, добавьте ссылку на объект InternetExplorer Для этого выполните следующие действия.

1. Откройте новый проект, выбрав тип проекта Standard EXE

2. Выберите команду References (Ссылки) меню Project (Проект), чтобы открыть диалоговое окно References.

3. Установите флажок Microsoft Internet Controls.

Новый значок на панели элементов управления не появится. Но если открыть окно Object Browser, то можно обнаружить, что класс Internet Explorer был добавлен к проекту. В окне Members будут видны свойства и методы класса IntemetExplorer. С их помощью можно управлять Internet Explorer посредством OLE.

Построим приложение, управляющее одним или несколькими экземплярами IntemetExplorer (рис. 21.3). Пользователь может выбрать адрес из элемента управления ComboBox в окне Visual Basic и щелкнуть на кнопке Show URL, чтобы запустить экземпляр Internet Explorer, в котором воспроизводится выбранный пользователем URL.

Рис. 21.3. Использование приложения IExplore для управления Internet Explorer

Далее выполните следующие действия.

4. Создайте форму, подобную показанной на рис. 21.3.

5. Объявите переменную, которая обращается к элементам класса IntemetExplorer.

Dim IE As New IntemetExplorer

6. Добавьте следующий код инициализации в событие, обрабатываемое при загрузке формы.

Private Sub Form_Load()

List1.AddItem "microsoft"

List1.AddItem "sybex"

List1.AddItem "infoseek"

List1.AddItem "realaudio"




Response

Этот объект используется для пересылки информации клиенту. ASP-файлы могут содержать HTML-код, который просто пересылается клиенту. Если возникает необходимость управлять потоком вывода из программы, то используется метод Write объекта Response. Он поддерживает следующие методы и свойства.

Метод Write

Все то, что записано в объект Response с помощью метода Write, пересылается клиенту. Информация, записываемая с помощью метода Write, является HTML-документом (как и при использовании одноименного метода объекта Document). Приведем пример использования метода Write.

Программа 22.4. Использование метода Response.Write

<HTML>

<SCRIPT LANGUAGE=VBScript RUNAT=Server>

Response.Write "<HTML>"

Response.Write "<HEAD>"

Response.Write "<TITLE>Response.Write Demo</TITLE>"

Response.Write "</HEAD>"

Response.Write "<H1>"

Response.Write "Response Object:Write Method"

Response.Write "</H1>"

Response.Write "This document was created on the fly by an ASP

file on the server"

Response.Write "</HTML>"

</SCRIPT>

</HTML>

Внешние теги <HTML> определяют границы ASP-файла (в данном случае они необязательны), а теги, записанные в объект Response, ограничивают HTML-файл, который виден на экране клиента. Если существует метод, используемый едва ли Не в каждом ASP-файле, то это метод Response.Write. Примеры данной главы не являются исключением из правил.

Метод Write объекта Response является основным способом пересылки данных клиенту. Программа 22.4 достаточно тривиальна. Этот же результат можно было получить непосредственным использованием HTML-тегов или метода Write объекта Document.

Метод Redirect

Этот метод переадресует клиента на другой URL. Если URL вашего узла изменился, то напишите небольшое ASP-приложение для автоматической переадресации клиентов на новый URL.

<HTML>

<%

Response.Write "Our site was moved at a new URL."




Request

Для взаимодействия с пользователем сценарий должен запрашивать информацию, вводимую пользователем в форму, и читать значения из

cookies. Появление ASP позволило упростить процесс чтения данных, поставляемых клиентом, путем инкап­суляции всей совокупности сложных процедур в несколько свойств объекта Request. Этот объект - один из основных инструментов построения серверных сценариев Объект Request обладает пятью свойствами, и все они являются семействами.

QueryString.

Содержит значения, переданные серверу методом GET.

Form. Содержит все формы на странице.

Cookies. Содержит все cookie, записанные на клиентский компьютер Web-узлом.

ServerVariables.

Содержит все HTTP-переменные, определенные сервером

ClientCertificate.

Содержит все сертификаты клиента.

Семейство QueryString

Это семейство, наиболее часто используемое при разработке ASP-приложений Оно предоставляет доступ ко всем параметрам, переданным клиентом вместе с URL Если имена параметров на этапе разработки приложения известны, то их значения можно получить следующим образом.

reqProdName = Request.QueryString ("ProductName")

Если имена параметров на этапе разработки ASP-файла не известны или их нужно обрабатывать последовательно, то воспользуйтесь следующим циклом.

Set Params = Request.QueryString

For Each param in Params

{обработка параметра param}

Next

На рис. 22.5 показана простая HTML-страница (страница SRVRFORM.HTM в папке этой главы на компакт-диске) с единственной формой, посредством которой пользователь вводит информацию, выбирая требуемые пункты в списках.

Рис. 22.5. Типичная форма HTML-страницы

Элементы ListBox на форме имеют следующие имена: HardDisc, Memory, CD, Speaker и Software. Их возможные значения перечислены в тегах <OPTION> для каждого тега <SELECT>. Варианты выбора объема оперативной памяти (Select Memory) представлены значениями 32, 64, 128 и 256. Параметр запроса Memory имеет одно из этих значении, выбранных на форме.

Программа 22.5. Файл SRVRFORM.HTM




Server

Объект Server управляет средой, в которой выполняется серверный сценарий. Наиболее важным членом этого объекта является метод CreateObject, создающий новый экземпляр объекта зарегистрированного класса.

Метод CreateObject

Этот метод идентичен одноименной функции Visual Basic. В качестве аргумента он принимает реестровый идентификатор (Class ID) объекта и возвращает его экземпляр. Метод имеет следующий синтаксис.

Server. CreateObject ("progID")

Для получения доступа к базе данных с помощью ADO-компонента необходимо сначала создать объекты Connection и Recordset с использованием следующих операторов (подробная информация приведена в параграфе "Использование ADO").

Set ADOConnection = Server.CreateObject ("ADODB.Connection")

Set ADORS = Server.CreateObject ("ADODB.Recordset")

Аналогично, необходимо создавать объектные переменные для доступа к другим базовым компонентам ASP, например, File Access или Adviertisement Rotator. Объектные переменные следует создавать для доступа к компонентам ActiveX, разработанным вами. В параграфе " Использование ADO" можно узнать, как устано­вить связь с базой данных, используя объектные переменные. В параграфе "Взаимодействие с компонентами ActiveX" в конце этой главы рассмотрено, как создать объектную переменную для взаимодействия с пользовательскими компо­нентами ActiveX, работающими на сервере.

Метод MapPath

Это еще один широко используемый метод объекта

Server, который устанавли­вает соответствие между виртуальными папками и действительными путями на диске. Он чрезвычайно полезен при разработке серверных сценариев: все файлы, с которыми работает сценарий, расположены в виртуальных паПках. Можно реорга­низовать структуру папок на Web-узле, затем переименовать несколько виртуальных папок, и ваши сценарии будут работать. Однако бывают случаи, когда требуется знать полный путь к файлу, а получить его можно с помощью метода MapPath.



Объект Document


С точки зрения программирования объект Document - наиболее важный объект в иерархии. Он задает HTML-документ, отображаемый в окне броузера или в одном из фреймов. С помощью свойств и методов объекта Document можно управлять видом и даже содержанием документа. Свойство bgColor можно использовать для чтения или установки цвета фона документа. Свойство Title — для считывания заголовка документа. Метод Write - для задания содержания документа из кода сценария, создания документа на лету. В следующем параграфе рассмотрены свойства объекта Document и даны примеры их синтаксиса.



Объект FileSystemObject


VBScript предоставляет несколько новых объектов, доступных из Visual Basic. Наиболее важным (с точки зрения программиста на VB) является объект FileSystemObject, предоставляющий доступ к файловой системе компьютера, на котором выполняется приложение. Visual Basic предлагает несколько функций и операторов для доступа и манипулирования файловой системой, но объект FileSystemObject является более гибким средством, обеспечивающим методы и свойства для доступа к каждому каталогу и файлу на диске.

Чтобы получить доступ к файловой системе компьютера, на котором выполня­ется приложение, создайте переменную FileSystemObject с помощью функции Create0bject().

Set FSys = CreateObject ("Scripting. FileSystemObject")

Переменная

FSys

представляет файловую систему и определяется как объект.

Dim FSys As Object

Чтобы получить доступ к текстовым файлам на диске, используйте методы объекта FileSystemObject, описанные ниже.

Это один из способов доступа к файловой системе компьютера из Windows-сценария. В Visual Basic существует лучший метод, использующий раннее связывание для ускорения работы приложения. Вы можете добавить ссылку на объект Microsoft Scripting Runtime, выбрав команду References меню Project для открытия диалого­вого окна References. Укажите элемент Microsoft Scripting Runtime и щелкните на кнопке ОК. Как только ссылка будет добавлена к проекту, можно объявить переменную FSys с помощью оператора

Dim FSys As New Scripting.FileSystemObject

или

Dim FSys As New FileSystemObject

В окне Code после введения имени переменной FSys появится список компо­нентов объекта Script, и можно будет выбрать необходимый объект.

Поэкспериментируем с объектом FileSystemObject. Откройте новый проект и поместите командную кнопку на его форму. В окне Code формы введите следующее определение.

Dim FSys As New Scripting.FileSystemObject

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

Debug.Print FSys.FileExists ("C:\AUTOEXEC.BAT")


Если файл C:\AUTOEXEC.BAT существует, то строка "True" появится в окне проверки. Компонент FileExists переменной FSys - это метод, который возвращает значение True, если файл существует. В противном случае он возвращает значение False.

Объект FileSystemObject предоставляет свойства и методы для операций с файловой системой, включая создание новых текстовых файлов (или открытие уже существующих), чтение или запись в них. Visual Basic имеет собственные опе­раторы для доступа к текстовым файлам (и к двоичным), поэтому это подмножество объекта FileSystemObject не особенно интересно для программиста на VB. Они описаны здесь, потому что позволяют работать с текстовыми файлами при создании Windows-сценариев. Позже мы обсудим компоненты объекта FileSystemObject, которые полезны при написании Visual Basic-приложений и Windows-сценариев.

Операции чтения из текстовых файлов и записи в них являются основными при разработке сценариев Многие сценарии сохраняют свои результаты в текстовых файлах или считывают из них необходимые параметры (например, сценарии, обрабатывающие большое число файлов). Методы FileSystemObject для работы с текстовыми файлами также могут использоваться внутри сценариев в приложениях Visual Basic (см пример StatCIss ниже в этой главе).


Объект History


Объект History предоставляет методы для перемещения по списку хронологии броузера. Он позволяет обращаться к функциональным возможностям кнопок навигации броузера из кода.



Объект Links


Другой невидимый объект - Links - задает связь в HTML-документе и предос­тавляет свойства, позволяющие выяснить адресат связи. Число гиперсвязей в текущем документе задается свойством Links. Length. Все гиперсвязи в документе задается массивом Links. URL первой гиперсвязи — Links(O), Links(l) — это URL второй гиперсвязи и т.д. до Links(Links. Length-1).

Массив

Links возвращает объект Links, который предоставляет информацию об атрибутах гиперсвязей. Свойства объекта Links перечислены в табл. 21.4.

Таблица 21.4. Свойства объекта Links

Свойство

Действие

Href

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

Protocol

Возвращает или устанавливает протокол URL (обычно http)

Host

хост и порт URL

Hostname

хост URL — имя или IP-адрес

Port

или устанавливает порт URL

Pathname

или устанавливает имя пути URL

Search

или устанавливает поисковую часть URL, если она существует

Hash

или устанавливает хэш-часть URL

Target

Последним свойством объекта Frame является цель, которая была определена в <А> фрейме. Цель - окно или фрейм, в котором отображаются данные



Объект Location


Объект Location применяется к объектам Window и Frame и предоставляет информацию об окне (или фрейме) текущего URL. Примеры объекта Location уже приводились, но все его свойства не рассматривались. Перечислим все свойства объекта Location. Они возвращают информацию о URL текущего документа. Задавая их, можно перемещаться к другому документу.

Href. Это свойство возвращает или устанавливает полный URL объекта, который будет загружен в броузер. Используя это свойство, можно соединиться с другими URL с помощью VBScript-кода. Чтобы отобразить URL текущего документа, используется следующее выражение.

MsgBox "You are currently viewing " & document.location.href

' (Текущий документ...)

Можно отобразить другой документ в окне или фрейме с помощью следующего оператора.

document.location.href = "http://www.microsoft.com"

Как вы уже знаете их гл. 20, URL имеет определенные части. Свойства, приве­денные в табл. 21.3, возвращают (или устанавливают) их.

Таблица 21.3. Свойства URL

Свойство           

Действие

Protocol           

Возвращает или устанавливает протокол URL (обычно http)

Host   

Возвращает или устанавливает хост и порт URL. Хост и порт разделены             двоеточием. Значение порта необязательно и редко используется

Hostname           

Возвращает или устанавливает хост URL, который может быть как    именем, так и IP-адресом

Port      

Возвращает или устанавливает порт URL (необходимо задать номер порта в WWW URL)

Pathname 

Возвращает или устанавливает имя пути URL. Это свойство можно использовать, когда необходимо показать документ, находящийся вне корня Web



Объект Navigator


Объект Navigator возвращает информацию о броузере. Одна из главных проблем, возникающая при разработке Web-страниц, следующая: два основных броузера (Netscape Navigator и Internet Explorer Microsoft) не полностью совместимы. Каждый из них поддерживает некоторые возможности, которыми другой не обладает. Это следствие конкуренции между Netscape и Microsoft, хотя установка новых стандартов позволила бы решить эту проблему.

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

Свойства объекта Navigator доступны только для чтения. Они возвращают информацию о броузере, в котором документ просматривается.

AppCodeName (Код имени приложения). Возвращает код имени приложения. Internet Explorer возвращает "Mozilla".

AppName (Имя приложения).

Возвращает имя приложения. Internet Explorer возвращает "Microsoft Internet Explorer".

App Version (Версия приложения). Возвращает версию приложения. Internet Explorer 4 для Windows 95 возвращает "4.0 (compatible; MSIE 4.01; Windows 95)". Следующие версии Internet Explorer и Windows могут возвращать другую строку.

UserAgent (Агент пользователя). Возвращает агента пользователя приложения. Internet Explorer 4 возвращает "Mozilla/4.0 (compatible; MSIE 4.01; Windows 95).".

Предположим, подготовлена HTML-страница, которая может просматриваться любым броузером (обобщенная страница), и версия той же страницы, которая включает возможности, поддерживаемые только Internet Explorer 4. Можно легко обнаружить, какой броузер использует клиент, и если используется Internet Explorer 4 — отобразить усовершенствованную страницу, а для всех других броузеров — обобщенную HTML-страницу.

Чтобы определить значения различных свойств объекта

Navigator, необходимо запустить приложение HTMLEditor (описанное выше) и создать небольшой сценарий, подобный следующему.

SCRIPT LANGUAGE=VBScript>

Document.Write Window.Navigator.propName

</SCRIPT>

Здесь

propName является фактическим именем свойства объекта Navigator. Запустите документ, и значение свойства появится в нижней части окна HTMLEditor.



Объект TableDef: определения таблиц


Объект TableDef задает определение таблиц в объекте Database. Все объекты TableDef формируют семейство. Число таблиц находится в свойстве TableDefs. Count.

Каждая таблица в базе данных задается объектом

TableDef. Перечислим его наиболее важные свойства.

•  Count возвращает число строк в таблице.

•  Fields - семейство объектов Field. Каждый объект Field задает поле в таблице.

•  Indexes — семейство объектов Index. Каждый объект Index задает индекс таблицы.

Итак, объявим и откроем объект Database с помощью следующих команд.

Dim DB As Database

Set DB = OpenDatabase(dbName)

Для доступа к определениям таблиц базы данных используйте выражение DB.TableDefs, являющееся семейством объектов: по одному для каждой таблицы. С помощью элементов этого семейства можно обращаться к свойствам таблиц в базе данных. Чтобы реализовать обращение к каждой таблице самым простым способом, нужно объявить переменную TableDef

Dim tbl As TableDef

а затем просмотреть каждый элемент семейства

DB.TableDefs с помощью цикла For Each... Next.

For Each tbi In DB.TableDefs

Debug.Print tbl.Name

Next

Этот цикл отображает имена таблиц. В дополнение к таблицам данных базы данных Access содержат несколько системных таблиц. Имена этих таблиц начи­наются с MSYS и их можно пропустить. Для получения подробной информации о том, как обнаружить и проигнорировать системные таблицы, смотрите параграф "VB6 в действии: проект DBStructure" далее в этой главе.

Индексы таблицы

Большинство таблиц в базе данных имеет хотя бы один связанный индексный файл, а иногда и больше. Для доступа к индексам таблицы предназначено свойство Indexes объекта TableDefs. Свойство Indexes - это семейство объектов, каждый из которых соответствует одному индексу таблицы. Чтобы самым простым способом реализовать обращение к каждому индексу в таблице, нужно объявить объект Index.

Dim idx As Index

а затем просмотреть каждый элемент семейства

Indexes с помощью цикла For Each...Next

For Each idx In tbi Indexes


Debug.Print idx.Name

Next

Элемент tbl — это объект TableDef, который объявлялся в предыдущем параграфе. Следующий вложенный цикл отображает имена всех таблиц в базе данных и имена их индексов под каждой таблицей.

For Each tbl In DB.TableDefs

Debug.Print tbl.Name

For Each idx In tbl.Indexes

Debug.Print idx.Name

Next idx

Next tbl

Можно запрашивать определение каждого индекса с помощью свойства Fields и использовать свойство Unique, чтобы определить, требует ли данный индекс уникальных ключей.

Поля таблицы

Наиболее важное свойство объекта TableDefs — свойство Fields (Поля), которое является семейством объектов, каждый из которых соответствует полю таблицы. Чтобы обратиться к полям таблицы, определите в базе данных нужную таблицу. Это делается с помощью индексного значения, которое равно 0 для первой таблицы, 1 — для второй и DB TableDefs Count-1 — для последней таблицы. К полям первой таблицы в базе можно обращаться с помощью объекта, приведенного ниже.

DB TableDefs (0) Fields

Вместо индекса можно использовать имя таблицы. Следующий объект задает все поля в таблице Titles базы данных BIBLIO/

DB.TableDefs ("Titles").Fields

Чтобы обратиться к каждому полю в семействе Fields, объявите объектную переменную Field и просмотрите семейство с помощью цикла For Each...Next. Следующий фрагмент кода отображает имена и типы каждого поля в первой таблице базы данных.

Dim fid As Field

For Each fld In DB.TableDefs(0).Fields

Debug.Print fld.Name, fld Type

Next

Свойство Type (Тип) возвращает целочисленное значение, которое представляет тип поля. Необходимо написать простую процедуру, которая преобразует этот номер в строку "Integer", "String" и т.п.

Другие свойства объекта Field приведены ниже.

•  OrdinalPosition. Определяет порядок полей в таблице.

• AllowZeroLength. Булево свойство, указывающее, может ли поле содержать пус­тую строку.

•  Size. Размер поля в байтах.

• Value. Текущее значение поля.


Объектная модель


ADO

Объектная модель ADO проще DAO, несмотря на то, что она поддерживает больше типов баз данных и предоставляет больше возможностей программисту. Модель ADO состоит из трех объектов:

Connection (Подключение).

Это объект высшего уровня, предоставляющий подключение к источнику данных. Обычно сначала выполняется подключение к источнику данных, а затем (для получения требуемых записей из базы данных или ее изменения) выполняются команды, использующие объект Connection. Однако подключение можно выполнить и в момент создания объекта RecordSet. Объект ADO Connection программируется аналогично объекту Connection конструктора DataEnvironment.

Command (Действие).

Этот объект представляет собой SQL-выражение или сохраненную процедуру, обрабатываемую свойством Data Source. Объект Command может не вернуть результат (если он предназначен для внесения изменений в базу данных) или вернуть RecordSet с требуемыми записями. Для установки объекта Command необходимо задать SQL-выражение или сохраненную процедуру и их параметры (если нужно). Параметры добавляются к семейству параметров (Parameters Collection) объекта Command. Затем можно вызвать метод Execute (Выполнить), чтобы выполнить SQL-выражение или сохраненную процедуру свойства Data Source. Другая возможность состоит в создании объекта RecordSet с последующим связыванием его с объектом Command. С точки зрения программи­рования объект ADO Command эквивалентен объекту Command конструктора DataEnvironment.

RecordSet (Набор записей).

Этот объект содержит результаты действия объекта Command при работе с базой данных (при условии, что действие возвращает записи). Объект RecordSet можно создать без явного подключения (достаточно передать строку подключения, определяющую Data Source, методу Open объекта RecordSet). Для доступа к полям объекта RecordSet используется его свойство Fields collection (Семейство Fields). Объект ADO RecordSet представляет такие же записи, которые возвращаются конструктором DataEnvironment, с той лишь разницей, что к ним можно получить доступ из кода, а не перетаскивать их на форму.



Объекты


IE Scripting Object Model

Scripting Model - это иерархия объектов, с помощью которых можно получить доступ к свойствам HTML-документов, отображаемых в окне броузера, и к свойствам самого броузера. Эта модель напоминает организацию объектов в СУБД Access (см. гл. 17 — там рассматривалась иерархическая организация объектов, начинающихся с объекта Database). В Scripting Model каждый объект имеет свойства, являющиеся самостоятельными объектами, которые имеют собственные свойства (некоторые из них также являются объектами), методы и события.

Верхний объект в Scripting Model — Window. Документ отображается внутри этого объекта. Основные свойства объекта Window: его имя (свойство Name) и место расположения отображаемого документа (свойство URL). Прежде рассмотрим объекты Scripting Model в целом и узнаем, что они выполняют для Web-страниц.

Наиболее важное свойство объекта Window — объект Document. Объект Document — это HTML-документ, отображаемый в окне, которое имеет собственные атрибуты (фоновый цвет, строку заголовка и т.д.). Окно может содержать фреймы, которые могут содержать документы. Чтобы обратиться к документу во фрейме, сначала обращаются к соответствующему фрейм-объекту, а затем - к объекту-документу этого фрейма.


Session и Application

Объект Session (Сеанс) поддерживает переменные, относящиеся к конкретному сеансу взаимодействия клиент-сервер. Перед ознакомлением с членами этого объекта и способами его применения для построения ASP-приложений рассмотрим, как ASP-компоненты поддерживают сеанс в условиях протокола без сохранения предыстории.

Мы уже знаем, что HTTP является протоколом, не сохраняющим предысторию. Когда клиент запрашивает новый документ, инициируется новый процесс обмена. Каким же образом ASP знает, что новый запрос принадлежит существующему сеансу обмена? Ответ прост — ASP использует cookies (заготовки).

Когда клиент подсоединяется в первый раз, сервер посылает cookie с именем ASPSESSIONID, который запоминается на клиентском компьютере. При всех последующих обращениях к серверу ASPSESSIONID пересылается вместе с заголовком запроса.

Примечание

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

ASP обрабатывает этот

cookie для восстановления значений переменных, сохраненных ранее в объекте Session. Время действия ASPSESSIONID истекает по окончании сеанса связи. Когда этот же клиент подсоединяется к серверу следующий раз, пересылается новый cookie и создается новый сеанс. Для сохранения информации между сеансами следует сохранить cookie, время действия которого истекло, чтобы при следующем подключении клиента к серверу можно было прочесть его и исполь­зовать в качестве ключа для поиска требуемой информации (права доступа и т.п.).

Примечание

Некоторые броузеры не поддерживают cookie (хотя бывает это очень редко). Такие броузеры не поддерживают также объект Session. Это — единственное ограничение на использование ASP.

Объект Application (Приложение) подобен Session с той лишь разницей, что он поддерживает переменные, относящиеся не к отдельному сеансу, а к приложению. Простейшими примерами его использования являются вывод приветственного сообщения в окне клиента и счетчика пользователей. Все, что нужно для реализации счетчика пользователей, это ввести переменную, областью видимости которой является приложение, и увеличивать ее значение на 1 при посещении исходной страницы (являющейся ASP-документом) вашего приложения.



Объекты активного сервера


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

Для разработки интерактивных страниц необходим инструмент программиро­вания. Эту роль мог бы играть VBScript (или иной язык написания сценариев), но у него есть очень серьезные ограничения. Язык для написания клиентских сценариев должен быть настолько безопасным, что выполнение этого требования существенно уменьшает его возможности. Выход можно найти в перенесении большей части нагрузки на сервер. Инструментальным языком при этом остается VBScript, однако, если программа выполняется на сервере, VBScript получает доступ ко всем объектам на сервере. Это значит, что на сервере VBScript во многом подобен Visual Basic, а серверный сценарий напоминает VB-программу.

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

Database, осно­ванного на объекте Active Data Objects (ADO). ADO инсталируется вместе с ASP и его можно использовать в ASP-страницах для доступа к базам данных (см. гл. 18). Компонент ADO обеспечивает эффективный доступ к базам, совместимым с протоколом ODBC или OLE DB. Таким образом, можно использовать ADO в клиентских сценариях (при условии, что этот компонент установлен на компьютере-клиенте) для организации Web-интерфейса, позволяющего получить доступ к корпо­ративным базам данных без разработки дополнительного серверного сценария.

ASP подчиняются парадигме разработки на основе компонентов. Это означает, что все функциональные возможности для разработки Web-узла обеспечиваются объектами, принадлежащими одной из двух категорий:

• встроенные;

• базовые (или основные).

Встроенные объекты предоставляют методы и свойства для доступа к деталям поступающих запросов (например, к параметрам запроса) и генерирования резуль­татов, возвращаемых клиенту. Базовые объекты обеспечивают функциональные возможности, не являющиеся обязательными, но широко используемые в Web-разработках. Примеры базовых объектов - ADO для доступа к базам данных и компонент файловой системы, используемый при чтении и записи в файлы на сервере. В следующих двух параграфах рассмотрены эти объекты и примеры их использования в Web-разработках.



Объекты для просмотра


Web

Чтобы использовать методы Web и документы с гиперссылками в приложениях Visual Basic необходимы два объекта:

• элемент управления WebBrowser;

объект InternetExplorer.

WebBrowser — это элемент управления ActiveX, который отображает HTML-документы в формах Visual Basic. InternetExplorer — это объект автоматизации OLE, использующийся для управления Microsoft Internet Explorer (и элементом управления WebBrowser) из программы. Эти два объекта имеют много общего, поэтому рассматриваются в одном параграфе. Основное внимание уделено элементу WebBrowser.



Объекты, которые представляют текст


Базовым объектом для доступа к тексту в документах Word является объект Range,

который представляет собой непрерывный сегмент текста. Чтобы извлечь некоторый текст из документа, можно воспользоваться методом Range объекта Document, который принимает в качестве параметров позиции начального и конечного символов в тексте. Синтаксически это выглядит так:

Document.Range(start, end)

Параметры start и end — два числовых значения. Непривычным является то, что первый символ документа имеет номер 0. Следующий оператор позволяет извлечь первые 100 символов документа, представленного объектной переменной Document.

Range 1 = Document.Range (0, 99)

Эти символы присваиваются объектной переменной Range). Переменная Range 1 может быть объявлена как вариантная, но ее также можно объявить как переменную типа Range:

Dim Range 1 As Range

В приведенных операторах перед использованием переменной Document ее необходимо установить, чтобы затем можно было сослаться на существующий объект:

Set Documenti = Documents(1)

Переменная

Document1 может быть объявлена как вариантная, но ее также можно объявить как переменную типа Document:

Dim Documenti As Document

Также можно заменить переменную Document1 на встроенный объект ActiveDocument,

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

Application.ActiveDocument.Selection

Слова, предложения и абзацы являются более значимыми элементами текста, нежели символы. Соответственно, объекты Word, Sentence и Paragraph более подходят для работы с текстом и, обычно, именно они используются при обращении к документам. Но эти объекты не поддерживают все свойства объекта Range. Впрочем, все эти элементы текста могут быть преобразованы в объект Range, обладающий свойством Range. Например, следующее выражение возвращает третий абзац в указанном документе как объект Range:

Document1.Paragraphs(3).Range

После этого можно обратиться к свойствам объекта

Range, чтобы обработать третий абзац.


Однако объект Paragraph не обладает ни свойством Font, ни методом Select. Чтобы изменить вид третьего абзаца в документе, необходимо сначала преобразо­вать абзац в объект Range:

Set Rangel = Documenti.Paragraphs (3).Range

Rangel.Font.Bold = True

Document1 — правильно объявленная переменная типа Document, a Rangel — правильно объявленная переменная типа Range. Впрочем, можно объединить оба оператора в один и избежать, тем самым, необходимости создания объектной переменной Rangel:

Document1.Paragraphs(3).Range.Font.Bold = True

С помощью приведенного ниже оператора можно выделить тот же параграф:

Document.Paragraphs(3).Range.Select

Как только абзац (или любой другой фрагмент текста) выделен, к нему можно применить все средства обработки (например, редактировать, перемещать в другое место, форматировать).

Наиболее часто используются два метода объекта Range: InsertAfter, с помощью которого можно вставить строку текста после указанного объекта Range, и InsertBefore, с помощью которого можно вставить строку текста перед указанным объектом Range. Следующие операторы позволяют вставить заголовок в начало документа и заключительный абзац в конец:

AppWord.ActiveDocument.Select

AppWord.ActiveDocument.Range.InsertBefore _

"This is the document's title"

'(Это заголовок документа)

AppWord.ActiveDocument.Range.InsertAfter

"This is the closing paragraph"

'(Это заключительный абзац)

С помощью метода Select

в объекте ActiveDocument можно выделить текст целиком. Преобразовав после этого выделенный текст в объект типа Range, можно применить к нему методы, присущие объекту соответствующего типа. Методы InsertBefore и InsertAfter позволяют поместить некоторый текст перед и после объекта Range.

VB6 в действии: проект WordVBA

Располагая информацией о методах и объектах, можно разработать программу, которая сможет открыть документ, поместить в него некоторый текст, форматировать

его, а затем сохранить в файле на диске. Начать следует с создания экземпляра Word и установления связи с ним. В этом проекте демонстрируются возможности:



•  создания нового документа;

•  вставки текста и его форматирования,

•  подсчета количества абзацев, слов и символов в новом документе и вывода полученных результатов в окно сообщений (рис. 14.14).

Эти действия выполняются непосредственно из приложения Visual Basic, в то время как Word работает в фоновом режиме. Пользователь не видит окно Word (даже в виде значка на панели задач). Новый документ сохраняется в файле C:\SAMPLE.DOC, и позже его можно будет открыть в Word для редактирования.



Рис. 14.14. В проекте WordVBA демонстрируется создание и обработку DOC-файла из приложения Visual Basic.

Программа, обслуживающая кнопку Create DOC file, проста. Для работы с текстом используется свойство Paragraph объекта Document, чтобы управлять текстом (можно вставлять новые абзацы и работать с ними). Следует обратить внимание на то, как выполняется выравнивание первого абзаца текста с помощью свойства Alignment объекта Paragraph.

Программа 14.10. Кнопка Create DOC file

Private Sub Commandl_Click()

Dim thisDoc As Document

Dim thisRange As Range

Dim prnTime As Date

Dim breakLoop As Boolean

Me.Caption = "Creating document..."

' (Создание документа...)

Set thisDoc = WordApp.Documents.Add

thisDoc.Range.InsertBefore "Document Title" & vbCrLf & vbCrLf

' (Заголовок документа...)

Set thisRange = thisDoc.Paragraphs(1).Range

thisRange.Font.Bold = True

thisRange.Font.Size = 14

thisRange.ParagraphFormat.Alignment = wdAlignParagraphCenter

thisRange.InsertAfter "This sample document was created _

automatically with a Visual Basic application." _

& vbCrLf

' (Этот образец документа был создан

' автоматически приложением Visual Basic...)

thisRange.InsertAfter "You can enter additional text here" _

SvbCrLf

' (Сюда можно ввести текст...)

thisRange.InsertAfter vbCrLf & vbCrLf

thisRange.InsertAfter "This project was created for _

Mastering VB6"

' (Этот проект был создан для книги по VB6)

thisRange.InsertAfter "(Sybex, 1999) and was tested with _



Word 97 "

' ( (изд-ва Sybex, 1999) и был испытан с

' помощью Word 97.)

thisRange.InsertAfter vbCrLf

thisRange.InsertAfter "Your text follow"

' (Далее следует ваш текст)

thisRange InsertAfter Textl.Text

Me.Caption = "Saving document... "   ' (Сохранение документа...) thisDoc.SaveAs "c:\sample.doc"

Me Caption = "Printing document..."  ' (Печать документа...)

thisDoc.Printout True, True

prnTime = Time

breakLoop = False

While WordApp.BackgroundPrintingStatus <> 0 And Not breakLoop

If Minute(Time - prnTime) > 1 Then

Reply = MsgBox (" Word is taking too long to print." _

 vbCrLf & "Do you want to quif" , vbYesNo)

 '(Документ печатается слишком долго.. Будете ждать?)

If Reply = vbYes Then

   breakLoop = True

Else

   prnTime = Time

End If

End If

Wend

WordApp.Quit

MsgBox "Document saved and printed!"

' (Документ сохранен и распечатан!)

Command2.Enabled = True

Command3.Enabled = True

Me Caption = "Word VBA Demo"

End Sub

Кнопка Massage DOC File позволяет продемонстрировать работу с текстом в документе Word с помощью автоматизации OLE. Первоначальный текст содержит множество ненужных пробелов между словами. Чтобы заменить эти пробелы на одиночные (типичная задача при редактировании), можно воспользоваться диалоговым окном Find & Replace (Поиск и замена). Приложение WordVBA выполняет эту операцию, вызывая метод Find.

Для обращения к методу Find требуется указать множество параметров, боль­шая часть которых является необязательными. Для приложения WordVBA необходимо определить строку, которую следует найти, и строку, на которую ее следует заменить. Поэтому надо указать, что программа должна отыскивать два последо­вательно расположенных пробела и заменять их одним пробелом. Но на этом процесс не закончится, поскольку в документе могут содержаться три последова­тельно расположенных пробела, а в результате выполнения указанной процедуры их количество будет уменьшено до двух. Поэтому операция Find & Replace (Поиск и замена) должна быть выполнена еще раз. Как только программа отыщет два последовательно расположенных пробела, операция замены будет выполнена еще раз.

Программа 14.11. Обработка документа

Word

Private Sub Command2 Click ()

Dim thisDoc As Document

Dim thisRange As Range

WordApp.Documents.Open ("c:\sample doc")

WordApp.Visible = False

Set thisDoc = WordApp.ActiveDocument

thisDoc.Content.Find.Execute FindText:="VB5", _

ReplaceWith:="VB6", Replace:=wdReplaceAll

While thisDoc.Content.Find.Execute(FindText:= " ", _

Wrap:=wdFindContinue)

  thisDoc.Content.Find.Execute FindText:= " ", _

ReplaceWith:= " ", Replace:= wdReplaceAll, _

Wrap:=wdFindContinue

Wend

End Sub


Объявление 32-разрядных функций и структур


В некоторых API-функциях в качестве параметров используются структуры. В приложении MousePos (папка MousePos данной главы на компакт-диске) приводится пример объявления и использования простой структуры. В этом приложении для получения информации о положении мыши в момент выполнения щелчка используется функция GetCursorPosQ. Эта функция должна возвратить вызвавшей ее программе два значения: координаты Х и Y мыши. Эти значения хранятся в структуре POINTAPI, которая состоит из двух элементов - Х и Y. Доступ к ним можно получить из программы с помощью выражений PointAPl.X и PointAPl.Y.

Чтобы создать проект MousePos, выполните следующие действия:

1. Откройте окно API Viewer, выбрав команду API Viewer в меню Add-Ins.

2. В открывшемся окне в меню File (Файл) выберите команду Load Text File (Загрузить текстовый файл).

3. Выберите файл Win32api.txt и выполните двойной щелчок на элементе GetCursorPos в списке Available Items (Доступные объекты).

4. В окне списка Selected Items (Выделенные объекты) появится следующее объявление:

Declare Function GetCursorPos Lib "user32" _

Alias "GetCursorPos" (IpPoint As POINTAPI) As Long

Параметр, необходимый для вызова функции - это структура данных, назы­ваемая POINTAPI. Она хранит координаты точки экрана. Чтобы найти определение структуры данных POINTAPI с помощью API Viewer выполните следующие действия:

5. В раскрывающемся списке API Type (API-типы) выберите Types (Типы). Список Available Items (Доступные объекты) будет содержать названия всех структур данных, используемых API-функциями.

6. Найдите структуру данных POINTAPI и выполните двойной щелчок на ее названии. В окне списка Selected Items (Выделенные объекты) появится ее определение.

Type POINTAPI

х As Long

у As Long

End Type

7. Щелкните на кнопке Сору, чтобы скопировать это определение в буфер обмена (вместе с объявлением функции GetCursorPos()).

Совет

Объявления функций можно помещать в любом месте, но обычно их помещают в Module (Модуль): тогда другие процедуры смогут получить к ним доступ.



Обновление изображения


Теперь можно написать код, который обновляет изображение и вызывает событие TimeOut. Код, который будет написан в этом разделе, не имеет никакого отношения к конструированию элемента управления ActiveX. Этот код необходим при реализации таймера как самостоятельного приложения.

Совет

Если вы еще не совсем привыкли к среде конструирования ActiveX, то можно разработать обычное приложение, которое делает то же самое (то есть отсчитывает время, показывает прошедшее или оставшееся время на элементе управления Label, и обнаруживает, когда подходит время сигнала). Затем можно скопировать необ­ходимые процедуры и вставить их в окне проекта ActiveX.

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

Программа 16.16. Событие Timer элемента управления Alarm

Private Sub Timerl_Timer()

Dim TimeDiff As Date

Dim StopNow As Boolean

If Time - m_AlarmTime > 0 Then

If NextDay = False Then

StopNow = True

Else

TimeDiff = 24 - Time + m_AlarmTime

End If

Else

If NextDay = True Then

StopNow = True

Else

TimeDiff = m_AlarmTime - Time

End If

End If

If m_CountDown Then

Label1.Caption = Format$(Hour(TimeDiff) &  ":" & _

Minute(TimeDiff) & ":" & Second(TimeDiff), "hh:mm:ss")

Else

Label1.Caption = Format(Hour(Time - startTime)  & ":" & _

Minute(Time - startTime) & ":" & _

SecondfTime - startTime), "hh:mm:ss")

End If

If StopNow Then

Timeri.Enabled = False

RaiseEvent TimeOut

End If

End Sub

Способ остановки таймера и вызова события TimeOut зависит от того, настроен ли элемент управления для обратного отсчета. При обратном отсчете он отображает оставшееся время, а при прямом отсчете он отображает время, прошедшее с момента запуска таймера (переменная startTime


устанавливается методом StartTimer). Когда достигается значение AlarmTime, таймер останавливается. Это условие в коде проверяется последней If-структурой. Переменная NextDay устанавливается в методе StartTimer. Когда подходит время подачи сигнала, переменная NextDay изменяет свое значение, и это событие сообщает о том, что сигнал включен.

Можно предположить, что момент для инициирования события TimeOut может быть вычислен путем сравнивания AlarmTime с текущим временем:

If Time = AlarmTime Then

Timeri.Enabled = False

RaiseEvent TimeOut

End If

Но этот код никогда не будет работать. Если компьютер слишком занят в момент, когда подходит время сигнала (например, запуск другого приложения или проверка жесткого диска), событие Timer для последней секунды может быть не вызвано. Если это событие было пропущено, нужно будет ждать 24 часа, прежде чем подойдет время следующего сигнала (и потом он снова может не сработать!). Реализация, которая выполнена в нашем примере, включит сигнал, если даже это произойдет на секунду или две позже.

Посмотрите, насколько просто генерируются собственные события. Просто не­обходимо вызвать метод RaiseEvent из собственного кода, и Visual Basic поймет, что о событии сообщено основному приложению. В приложении любое условие в любое время может инициировать событие. Кроме того, в начале кода наряду с объявлением переменных нужно добавить объявление события TimeOut.

Event TimeOut()

Откройте проект Alarm и исследуйте код объекта UserControl вместе с кодом тестового проекта. Код очень простой, именно поэтому он был выбран для реализации вручную. Естественно, проще реализовать пользовательские элементы управления с помощью мастера интерфейса элемента управления ActiveX, но важно понять, что происходит и что мастер делает автоматически.


Обработка ошибок


Элемент управления Script имеет событие Error, вызываемое в случаях возник­новения ошибки. Ошибку может вызвать элемент управления (вызов метода с не­правильным аргументом или попытка установить несуществующее свойство) или сам сценарий Она может генерироваться в основном приложении, но не раньше, чем пользователю предложат воспользоваться Script Debugger. Пока разрабатываются и тестируются сценарии, можно позволить Visual Basic запустить отладчик и помочь в отладке. Завершенное приложение не должно выдавать подобных сообщений.

Может показаться, что нынешняя версия элемента управления не позволяет подавлять диалоговое окно, что делает затруднительным распространение прило­жений. Пользователи могут не иметь инсталированного Script Debugger, и эти сообщения приведут к путанице. Нынешний элемент управления Script далек от совершенства, но, возможно, следующая версия будет более гибкой или будет иметь редактор кода программы.

Необходимо мириться с ограничениями и недостатками элемента управления Script. Для обработки ошибок используйте объект Error, который является свойством элемента управления Script и отличается от объекта Err в Visual Basic. Объект Error имеет два свойства, которые указывают место ошибки в сценарии:

• Line - номер строки с ошибкой;

• Column — положение первого символа оператора, вызвавшего ошибочную ситуацию.

Эти свойства используются для установки указателя на место ошибки. Когда в качестве редактора используется элемент управления TextBox, переход на заданный символ в заданной строке текста этого элемента не является тривиальной задачей. Не существует методов или свойств, позволяющих выполнить это непосредственно.

Объект Error элемента управления Script имеет дополнительные свойства, которые перечислены в табл. 20.5.

Таблица 20.5. Дополнительные свойства объекта Error элемента управления Script

Свойство

Описание

Number Description

Text

Source

Номер ошибки

Описание ошибки

Строка с ошибочным оператором

Имя процедуры или класса, в которых произошла ошибка

<
После обработки ошибки для ее сброса вызывается метод

Clear объекта Error. Рассмотрим обработчик ошибок в коде кнопки Execute Script. Если элемент управ­ления Script генерирует ошибку выполнения и свойство ScriptControll.Error.Number не равно нулю, то можно использовать свойство Error элемента управления Script для получения информации об ошибочном операторе. Но в большинстве случаев элемент управления Script генерирует ошибку автоматизации и не инициализирует объект Error. Обработчик ошибок просто отображает ошибку в окне сообщений.

CodeError:

If ScriptControll.Error.Number <> 0 Then

msg = ScriptControll.Error.Description & bvCrLf

msg =

msg & "В строке " & ScriptControll.Error.Line _

& ", столбце" & ScriptControll.Error.Column

MsgBox msg, ,"Ошибка в сценарии"

Else

MsgBox "ERROR # " & Err.Number & vbCrLf & Err.Description

End If

Наиболее частый источник ошибок - вызов неправильных методов или объектных переменных. Следующий оператор активизирует Excel и вызывает метод Evaluate.

Set EXL = CreateObject ("Excel.Application")

MsgBox "Логарифм числа 99 равен" & EXL.Evaluate ("Log(99)")

Если пропущено имя переменной EXL или приложение Excel отсутствует на машине, то в обоих случаях будет выдано одно сообщение об ошибке автоматизации. Это означает, что сценарий не имеет доступа к объекту. Если вызвать функцию InStr() с ошибочным аргументом (или неправильным числом аргументов), то в обоих случаях появится одно сообщение об ошибке. Объект Error элемента управления Script может локализовать только простые синтаксические ошибки. При работе с объектами элемент управления Script не оказывает существенной помощи.


Обработка ошибок класса


Класс AXStat содержит программный код, который может инициировать ошибки из кода класса. Если говорить о данном приложении, эти ошибки иден­тичны ошибкам, которые генерируются Visual Basic, и они могут быть перехвачены. Если, например, пользователь пытается получить доступ к несуществующему элементу (индекс которого больше свойства Count), то класс генерирует ошибку. Класс может обрабатывать ошибку, выдавая соответствующее сообщение, но это не лучший способ обработки ошибок, которые возникают в классах. Разумнее инициировать ошибку и позволить приложению ее обработать.

Для генерирования ошибки исполнения в классе (или в управляющем элементе ActiveX, как это можно увидеть в следующей главе) необходимо воспользоваться методом Raise

объекта Err. Номер ошибки может быть любым целым значением, но следует убедиться в том, что оно не конфликтует с номерами ошибок Visual Basic. Диапазон от 0 до 512 зарезервирован для Visual Basic и не стоит использовать номера из этого диапазона. Можно использовать любой другой номер ошибки, но рекомендуется использовать малые значения и прибавлять к ним константу vbErrorObject. Например, если класс может определять 8 типов ошибок, то можно назначить им номера от 1 до 8 и прибавить к ним константу vbErrorObject.

Если другой элемент управления использует такие же номера ошибок, то можно выяс­нить, каким элементом управления сгенерирована ошибка, исследуя свойство Source объекта Err. Для выяснения действительного номера ошибки приложение может вычесть эту же константу из значения Err.Number.

Совет

Интересным свойством константы vbErrorObject

является то, что ее значение — очень большое отрицательное число (-2147221504). Таким образом, все номера ошибок, возвращаемые пользовательскими классами, будут отрицательными числами и их очень легко отличить от стандартных ошибок Visual Basic.

Две кнопки с правой стороны тестовой формы генерируют ошибки исполнения, вызывая члены класса AXStat с некорректными аргументами. Следующий программ­ный код показывает, как они вызывают методы Item и Remove с соответствующим кодом, перехватывающим ошибки.


Программа 15.16. Обработка ошибок сгенерированных классом AXStat

Private Sub Command5_Click()

On Error Resume Next

STATS.Remove 9999

If Err.Number <> 0 Then

MsgBox "ERROR # " & Err.Number - vbObjectError _

& vbCrLf & Err.Description & vbCrLf & "In " & Err.Source

' (Ошибка №... в...)

End If

End Sub

Private Sub Command6_Click ()

On Error Resume Next

STATS.Item 9999

If Err.Number <> 0 Then

MsgBox "ERROR #" & Err.Number - vbObjectError _

& vbCrLf & Err.Description & vbCrLf & "In " & Err.Source

' (Ошибка N". . . в. . . )

End If

 End Sub

Номер ошибки и ее источник устанавливаются в программном коде класса, методом Raise объекта Err, как показано ранее. Для определения действительного номера ошибки, сгенерированной классом, вычтите константу vbErrorObject

из значения Err.Number. Еще лучше, объявить несколько констант в коде, которые соответствуют значениям ошибок. Ниже приведен перечислимый тип с ошибками, которые генерируются классом AXStats:

Public Enum AXStatErrors

AddError = 1

RemoveError = 2

End Enum

Константы значений ошибок появятся в броузере объектов под классом AXStatsErrors, и их можно использовать в коде приложения в виде выражений AXStatErrors.AddError и AXStatErrors. Remove Error.

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

Ответ прост. По умолчанию Visual Basic в режиме конструирования останавли­вается в месте возникновения ошибки. Поэтому можно видеть строку, которая вызвала ошибку и исправить соответствующую процедуру в модуле класса. Если создать исполняемый файл и запустить его вне среды разработки, ошибка испол­нения будет перехвачена работающим приложением. Можно также изменить поведение механизма перехвата ошибок Visual Basic в процессе конструирования. Откройте меню Tools и выберите команду Options. В диалоговом окне Options, ко­торое появится на экране, выберите вкладку General, как показано на рис. 15.8.



В секции Error Trapping ( Перехват ошибок) вкладки General опция Break in Class Module (Останов в модуле класса) выбрана по умолчанию. Вот почему Visual Basic прерывает выполнение как только возникает ошибка и тестовый проект не имеет шанса обработать ее с помощью собственного обработчика ошибок. Выберите опцию Break on Unhandled Errors (Останов на необработанных ошибках) (как показано на рис. 15.8), закройте диалоговое окно Options и запустите тестовый проект снова. Щелкните кнопку Remove Error или Item Error - на этот раз проект не завершится ошибкой исполнения. Вместо этого появится диалоговое окно с сообщением об ошибке подобное, изображенному на рис. 15.9.



Рис. 15.8. Изменение поведения механизма перехвата ошибок, заданного по умолчанию, во время конструирования.



Рис. 15.9. Перехват ошибок исполнения, генерируемых классом AXStats


Обращение к API-функциям из


Visual Basic

Единственное отличие функций Visual Basic от API-функций заключается в том, что последние необходимо объявлять перед использованием. По сути, требуется сообщить Visual Basic имя и местоположение DLL-библиотеки, в которой находится требуемая API-функция, и указать типы и количество ее параметров. После этого ее можно использовать так же, как и функцию Visual Basic.

Объявление API-функций

Для объявления API-функций используется оператор Declare. Одним из способов является ввод имени функции с указанием ее параметров.

Declare Function mciSendString Lib "winmm.dll" _

Alias "mciSendStringA" (ByVal IpstrCommand As String_

ByVal IpstrReturnString As String, ByVal uReturnLenght_ As Long, ByVal hwndCallback As Long) As Long

Примечание

Очень длинную строку, содержащую объявление, обычно разбивают на несколько строк меньшей длины, каждая из которых заканчивается символом "_" (символ подчер­кивания). Но можно этого и не делать.

API-функция mciSendString()

является частью библиотеки Winmm, располо­женной в файле Winmm.dll в подпапке System папки Windows Суффикс А — это наследство, доставшееся от старых версий API, в которых сосуществовали 16- и 32-х разрядные функции. В Windows 95/98 необходимо использовать 32-разрядные функции.

Почти для всех API-функций необходимо передавать параметры по значению. Только те параметры, которые изменяются самой функцией, необходимо переда­вать по ссылке. По умолчанию, Visual Basic передает аргументы по ссылке, поэтому для передачи аргументов по значению необходимо использовать ключевое слово ByVal.

Использование приложения API Viewer

Предполагается, что пользователю нет необходимости запоминать параметры каждой функции и даже их имена - он может обратиться к справочной системе. Получить доступ к ней можно непосредственно из IDE-среды — окно API Viewer приведено на рис. 13.1.

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


1. Выберите команду API-Viewer в меню Add-Ins. Если в меню Add-Ins (Надстройки) нет пункта API Viewer, необходимо открыть диалоговое окно Add-Ins Manager (Диспетчер надстроек) и выполнить правый щелчок на элементе Visual Basic 6 API Viewer, чтобы добавить данный пункт в меню Add-Ins.



Рис 13.1. Окно приложения API Viewer

2. В диалоговом окне API Viewer в меню File (Файл) выберите команду Load Text File (Загрузить текстовый файл) или Load Database File (Загрузить файл базы данных) Загрузка файла базы данных выполняется быстрее, но лишь в том случае если при этом не происходит преобразование текстового файла в файл базы данных

3. В окне списка Available Items (Доступные объекты) выберите требуемую функцию и щелкните на кнопке Add (Добавить). API-Viewer отобразит выбранную функцию (функции) в окне списка Selected Items (Выделенные объекты)

4. Выберите функции, которые необходимо вставить в прикладную программу, а затем щелкните на кнопке Сору (Копировать) для копирования объявления функций в Clipboard (Буфер обмена)

5. Откройте окно Code (Исходный код) вашего приложения и вставьте объявления функций

Совет

Пакет Win32 Software Development Kit содержит полное описание каждой функции, включая все структуры и сообщения. Microsoft Developer Network (MSDN) предоставляет все необходимое для разработки Windows-приложений. Для получения подробной информации о MSDN посетите сайт

http.//www.microsoft.com/msdn.

Большинство API-функций требует большого числа параметров, причем некоторые из них имеют сложный тип. Типы параметров API функции пере числены ниже.


Обращение к классу


EventTimer из других проектов

Для использования класса в другом проекте сначала нужно добавить ссылку на этот класс. Имеется в виду то, что нужно сделать компонент доступным для системы, зарегистрировав его, как описано в предыдущем параграфе. Если DLL- или ЕХЕ-файл компонента был создан и уже зарегистрирован в системе, то любой проект или другое приложение системы могут использовать его. Чтобы добавить класс EventTimer в проект, выполните следующие действия.

1. Откройте новый проект, затем меню Project и выберите команду References, чтобы открыть диалоговое окно References (Ссылки). Это окно содержит все объекты, на которые можно ссылаться в данном проекте.

2. Выберите элемент EventTimer (объекты упорядочены по имени их проектов, а не по имени классов) и нажмите ОК. После того как класс был добавлен в проект, можно посмотреть его интерфейс с помощью Object Browser.

3. Из меню View выберите команду Object Browser, чтобы открыть окно, показанное на рис. 156. В верхнем раскрывающемся списке выберите необходимую ссылку.

Рис. 15.6. Просмотр членов класса EventTimer с помощью Object Browser

4. Проект EventTimer предоставляет один класс EventTimerClass, имя которого появилось в окне Classes. В окне Members можно увидеть свойства, методы и события этого класса.

Если выбрать мышью свойство ElapsedTime в окне Members, то на нижней панели окна Object Browser появится его описание. Это свойство объекта EventTimer EventTimerClass и оно доступно только для чтения потому что класс содержит только процедуру Property Get этого свойства. Другими членами высту­пают методы и события класса. Разработчик возможно догадается что делает класс, просто посмотрев на члены которые он предоставляет



Общие методы элемента управления


OLE Container

Чтобы управлять встроенными или связанными объектами, в элементе управ­ления OLE Container, в дополнение к уже упомянутым, предусмотрены следующие методы.

CreateEmbed

С помощью этого метода создается встроенный объект. Синтаксис метода имеет вид:

CreateEmbed sourcedoc, class

Параметр

sourcedoc — имя файла документа, используемого в качестве шаблона для встроенного объекта. Чтобы создать новый встроенный документ, в качестве параметра sourcedoc

указывается строка нулевой длины ("").

Параметр

class — необязательный параметр, определяющий имя класса встро­енного объекта. Этот параметр требуется только в том случае, если параметр sourcedoc опущен. Чтобы найти зарегистрированные классы, выберите свойство Class (Класс) в окне Properties (Свойства) элемента управления OLE Container и щелкните на кнопке с многоточием.

CreateLink

Этот метод позволяет создать связанный объект из содержимого файла. Синтаксис метода CreateLink:

CreateLink sourcedoc, sourceitem

Параметр

sourcedoc — это файл, из которого будет создан объект, а параметр sourceitem —

данные внутри файла, которые должны быть в связанном объекте. Например, чтобы связать содержимое элемента управления OLE Container с блоком ячеек рабочего листа Excel, следует задать файл с помощью параметра sourcedoc, a диапазон связанных ячеек - с помощью параметра sourceitem. Параметр sourceitem может указывать на одиночную ячейку (например, R10C12) или на блок ячеек (например, R1C1:R10C20). Можно также задать именованный блок.

После того как связанный документ создан, значение свойства Sourceitem устанавливается в строку нулевой длины, а его первоначальное значение присое­диняется к свойству SourceDoc. Например:

"c:\data\revenus\revl997.xls|RCl:R20C25 "

Самый простой способ определения синтаксиса этих двух команд - это выбрать связываемый объект, а затем при проектировании вставить его с помощью коман­ды Paste Special в элемент управления OLE Container. После того как объект будет связан, просмотрите значение свойства SourceDoc и используйте его в собственной программе.


DoVerb verb

Метод DoVerb выполняет команды ( являющиеся глаголами, например, Edit, Play и т. п.). Объекту известно, как выполнять заданное действие. Синтаксис метода:

DoVerb verb

Значения необязательного параметра verb перечислены в табл. 14.3.

Таблица 14.3. Значения параметра verb

Константа

Значение

Описание

VbOLEPrimary

0

Действие для объекта, заданное по умолчанию

vbOLEShow

-1

Открывает объект для редактирования.

Активизирует приложение, создавшее документ, в окне OLE Container

VbOLEOpen

-2

Открывает объект для редактирования

Активизирует приложение, создавшее документ, в отдельном окне

vbOLEHide

-3

Для встроенных объектов позволяет скрыть приложение, создавшее объект

vbOLEUIActivate

-4

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

VbOLEInPlaceActivate

-5

Когда пользователь перемещает фокус в окно элемента управления

OLE Container, то с помощью этой операции можно создать окно для объекта и подготовить объект, который нужно отредактировать

vbOLEDiscardUndoState

-6

Когда объект активизирован для редактирования, этот метод позволяет отбросить все изменения, которые приложение, создавшее объект, может отменить

InsertObjDIg

Этот метод позволяет отобразить диалоговое окно Insert Object (Вставка объекта). Установки пользователя, выполненные в этом окне, передаются приложению с помощью значений свойств элемента управления OLE Container.

PasteSpecialDIg

Этот метод позволяет отобразить диалоговое окно Paste Special (Специальная вставка). Установки пользователя, выполненные в этом окне, передаются прило­жению с помощью значений свойств элемента управления OLE Container.

Object Browser позволяет выяснить, какие встроенные константы используются в различных методах и свойствах элемента управления OLE Container.



1. Выберите команду Object Browser (Просмотр объекта) в меню View (Вид).

2. Выберите библиотеку объектов Visual Basic, а в нем объект Constant, чтобы отобразить названия констант в списке Method/Properties (Метод/Свойства).

Если немного поэкспериментировать с методами OLE и элементом управления OLE Container, то можно сделать вывод: в пограничных ситуациях OLE далека от совершенства. У пользователя нет возможности полностью контролировать внешний вид встроенного или связанного объекта, а иногда и панель приложения-сервера остается невидимой. Несмотря на то, что работа над OLE идет уже несколько лет, нельзя считать ее завершенной.

Существует не так уж много созданных в Visual Basic приложений, которые выполняют связывание и встраивание документов, предоставленных приложениями-серверами. Однако другой аспект OLE — OLE-автоматизация — вполне совершенна и является наиболее мощным средством основных Windows-приложений, например, Microsoft Office. Автоматизация OLE рассматривается во второй части главы, а сейчас мы кратко рассмотрим операции перетащить-и-опустить, применяемые в OLE.


Общие свойства элемента управления


OLE Container

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

Class

Это свойство определяет тип объекта, хранящегося в элементе OLE Container. Если запустить приложение OLERTime, то, выбирая объекты различных типов, зарегистрированных в системе, и щелкая затем на кнопке Object Info, можно посмотреть значения свойства Class.

DispIayType

Это свойство указывает, отображается объект с содержимым (значение свойства 0) или только значок OLE-сервера (1).

• vbOLEDisplayContent

(0) — отобразить объект с содержимым;

•  vbOLEDisplayIcon

(1) — отобразить объект в виде значка.

OLETypeAllowed

Значение этого свойства обуславливает тип создаваемого объекта:

• 0 — связанный;

•  1 — встроенный;

• 2 — любой.

Тип объекта определяется в диалоговом окне Insert Object. Соответствующие константы приведены ниже:

•  vbOLELinked

(0) - объект можно связать;

• vbOLEEmbedded (1) — объект можно встроить;

• vbOLEEither (2) — объект можно связать или встроить.

OLEDropAllowed

Если значение этого свойства - True, то во время выполнения приложения можно поместить объект в элемент управления OLE Container, перетаскивая его

мышью. К аналогичным результатам приводит копирование объекта в буфер обмена и последующий вызов приложением метода Paste Special для элемента OLE Container.

SizeMode

Значение этого свойства определяет, как будет отображаться объект — в виде значка или реального документа в окне элемента управления

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

• vbOLESizeClip (0).

Это значение установлено по умолчанию. Размеры изображения объекта равны размерам исходного документа. Если размеры объекта больше, чем размеры окна элемента управления OLE Container, то часть изображения отсекается.

•  vbOLESizeStretch

(1). Размер изображения объекта изменяется так, чтобы заполнить все окно элемента управления OLE Container. При этом первона­чальные пропорции объекта могут измениться.


•  vbOLESizeAutosize

(2).
Размеры окна элемента управления OLE Container изменяются таким образом, чтобы отобразить весь объект

• vbOLESizeZoom (3). Размеры объекта изменяются так, чтобы объект занял как можно большую часть окна элемента управления OLE Container, а изображение при этом не исказилось.

SourceDoc

При связывании объекта значение этого свойства определяет файл-источник. Когда вы внедряете объект, это свойство определяет, какой файл будет использован в качестве шаблона.

Sourceltem

Этим свойством обладают только связанные объекты. Его значение определяет связываемые данные, находящиеся внутри файла. Например, если выполняется связывание с блоком ячеек рабочего листа Excel, то значение свойства Sourceltem - это диапазон ячеек, которые будут связаны.

OLEType

При выполнении программы это свойство доступно только для чтения. Оно возвращает статус объекта: 0 — для связанных объектов, 1 — для встроенных объектов, и 2 —объект не был вставлен. Соответствующие константы приведены ниже.

• vbOLELinked (0).

Объект связывается с элементом управления OLE.

• vbOLEEmbedded (1).

Объект встраивается в элемент управления OLE.

• vbOLENone (2). Элемент управления OLE Container не содержит объектов.

AutoActivate

Значение этого свойства определяет, будет содержимое элемента управления OLE Container активизировано двойным щелчком или перемещением фокуса в его окно Свойство AutoActivate может принимать следующие значения.

•  vbOLEActivaleManual

(0).
Объект не активизируется автоматически. Для его активизации необходимо использовать метод DoVerb.

• vbOLEActivateGetFocus

(1).
Объект активизируется для редактирования при каждом попадании фокуса в окно элемента управления OLE Container.

• vbOLEActivateDoubleclick

(2).
Значение по умолчанию. Объект в окне элемента управления OLE Container активизируется при выполнении на нем двойного щелчка.

•  vbOLEActivateAuto

(3).
Объект активизируется, когда элемент управления получает фокус либо на объекте выполняется двойной щелчок.


Определение индексов с помощью


Visual Data Manager

Visual Data Manager можно также использовать для организации индексов внутри базы данных. В нижней части окна базы данных находится список текущих индексов базы. Щелкните на кнопке Add Index, чтобы открыть диалоговое окно Add Index To (рис. 17.9). Опции диалогового окна Add Index To (Добавить индекс к) перечислены в табл. 17.6.

Примечание

Null является специальным значением (см. гл. 3). Поле пустое, если оно не было инициализировано (другими словами, если оно ничего не содержит). В общем случае проверяйте значения поля на равенство Null перед его использованием в операциях.

Рис. 17.9. Диалоговое окно Add Index To

Таблица 17.6. Опции диалогового окна Add Index To

Опция

Описание

Name

Имя индекса. Вы можете использовать имя индекса только при программировании наборов записей типа Table. В SQL-запросах технология Rush-More (Делай быстрее) автоматически использует индексную информацию для оптимизации запросов

Indexed Fields

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

Available Fields

Окно списка доступных полей щелчок кнопкой мыши на одном из полей добавит его в список индексных полей

Primary

Выберите эту опцию, если поле индекса рассматривается как первичный ключ для таблицы

Unique

Выберите эту опцию, если необходимо использовать уникальные значения для поля. Если вы индексируете таблицу Customers (Заказчики) по полю имени заказчика, то индекс может не быть уникальным. Возможно совпадение имен нескольких заказчиков Индекс, основанный на ID заказчика, уникален. Два заказчика не могут иметь один ключ, даже если имеют одно имя

IgnoreNulls

Это свойство указывает, может ли какое-нибудь из полей, используемых в индексе, содержать значение Null. Если это свойство установлено в False, а свойство Required - в True, a соответствующее поле содержит значение Null, то генерируется ошибка выполнения программы



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


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

Windows и определения текущего каталога. Перечислим их.

•  GetDriveType()

•  GetDiskFreeSpace()

•  GetWindowsDirectory()

•  GetCurrentDirectory()

Эти функции предоставляют дополнительные возможности, которых нет в Visual Basic. Например, вы можете определить, есть ли свободное пространства на диске и является ли данное устройство приводом CD-ROM.

Функция GetDriveTypeQ

Эта функция позволяет определить тип дисковода.

Объявляется она следующим образом

Private Declare Function GetDriveType Lib "kernel32" Alias _

"GetDriveTypeA" (ByVal nDrive As String) As Long

Вы передаете функции имя диска, который необходимо проверить с помощью параметра nDrive, и функция возвращает значение типа Long, которое указывает тип диска. В табл. 13.2 приведены типы устройств и их описания

Таблица 13.2. Описание типов устройств

Значение

Описание

0

1

DRIVEREMOVABLE

DRIVEFIXED

DRIVEREMOTE

DRIVECDROM

DRIVERAMDISK

Тип диска определить невозможно

Данный каталог не является корневым

Сменное устройство, например ZIP-накопитель

Несменное устройство, например жесткий диск С

Устройство удаленного доступа, например сетевой диск

CD-ROM-устройство

RAM-диск

VB6 в действии: проект Drives

Приложение Drives (рис 13.2) обеспечивает вывод на экран окна, содержащего информацию о выбранном диске (тип и свободный объем памяти), о текущей папке и о папке Windows системы. Каждый раз, когда пользователь выбирает другое устройство, информация в окне формы изменяется. В приложении Drives используются три API-функции: GetDiskFreeSpace(), GetCurrentDirectory() и GetWindowsDirectory()

Рис. 13.2. Приложение Drives

Функция GetDiskFreeSpace()

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


GetDiskFreeSpace() не предос­тавляет информацию о свободном дисковом пространстве, но его величина может быть вычислена на основании данных о количестве байтов на сектор, секторов на кластер и свободных кластеров Функция объявляется следующим образом:

Private Declare Function GetDiskFreeSpace Lib "kernel32" _

Alias "GetDiskFreeSpaceA" (ByVal IpRootPathName As

_

String, IpSectorsPerCluster As Long, IpBytesPerSector_

As Long, IpNumberOfFreeClusters As Long _

IpTotalNumberOfClusters As Long) As Long

Назначение параметров этой функции понятны и соответствуют их (значимым) именам.

Чтобы определить размеры свободного пространства на диске С, используются следующие операторы:

retValue

- GetDiskFreeSpace("с:\” Sectors, Bytes,_

freeClusters, totalClusters)

FreeSpace = Sectors * Bytes *

freeClusters

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

Функция GetCurrentDirectory()

Эту функцию следует применять в случаях, когда необходимо определить текущий каталог, из которого была запущена программа. Данная функция анало­гична свойству Арр. Path Visual Basic, и принимает два параметра, один из которых — длина буфера, а второй — указатель на строковую переменную (буфер), в которой будет сохранен путь к текущему каталогу. Функция должна объявляется следующим образом:

Private Declare Function GetCurrentDirectory Lib

"kernel32"

Alias "GetCurrentDirectoryA" (ByVal nBufferLength

_

As Long, ByVal IpBuffer As String) As Long

После вызова функции параметр lpBuffer содержит текущий путь

Функция GetWindowsDirectory()

Эта функция позволяет узнать, в какую папку на жестком диске инсталлиро­вана Windows. Эта информация нужна для дополнительной инсталляции файлов инициализации или справки в каталог Windows. Параметры этой функции иден­тичны параметрам GetCurrentDirectory(). Ее объявление имеет вид:

Private Declare Function GetWindowsDirectory Lib "kernel32" _



Alias "GetWindowsDirectoryA" (ByVal IpBuffer As _

String, ByVal nSize As Long) As Long

Полный текст программы Drives приведен ниже.

Программа 13.3. Проект Drives

Option Explicit

Private Declare Function GetDriveType Lib "kernel32" _

Alias "GetDriveTypeA" (ByVal nDrive As String) As Long

Private Declare Function GetDiskFreeSpace Lib "kernel32" _

Alias "GetDiskFreeSpaceA" (ByVal IpRootPathName _

As String, IpSectorsPerCluster As Long,_

IpBytesPerSector As Long, _

IpNumberOfFreeClusters As Long, _

IpTotalNumberOfClusters As Long) As Long

Private Declare Function GetCurrentDirectory Lib "kernel32" _

Alias "GetCurrentDirectoryA" (ByVal nBufferLength _

As Long, ByVal IpBuffer As String) As Long

Private Declare Function GetWindowsDirectory Lib "kernel32"

Alias "GetWindowsDirectoryA" (ByVal IpBuffer As String,_

ByVal nSize As Long) As Long

Const DRIVE_CDROM = 5

Const DRIVE_FIXED = 3

Const DRIVE_RAMDISK = 6

Const DRIVE_REMOTE = 4

Const DRIVE_REMOVABLE = 2

Private Sub Commandl_Click()

End

End Sub

Private Sub Drivel_Change()

Dim driveType As Long

Dim freeSpace As Long, Sectors As Long

Dim Bytes As Long

Dim freeClusters As Long, totalClusters As Long

Dim retValue As Long

Dim buffer As String * 255

Dim DName As String

Screen.MousePointer = vbHourglass

DoEvents

DName = Left(Drivel.Drive, 2) & "\"

driveType = GetDriveType(DName)

Select Case driveType

Case 0

Label5.Caption = "UNDETERMINED" Case DRIVE_REMOVABLE

Label5.Caption = "REMOVABLE"

Case DRIVE_FIXED

Label5.Caption = "FIXED"

Case DRIVE_REMOTE

Label5.Caption = "REMOTE"

Case DRIVE_CDROM

     Label5 Caption - "CDROM"

Case DRIVE_RAMDISK

Label5 Caption - "RAMDISK"

End Select

‘Вычисляем свободное пространство на диске

retValue   GetDiskFreeSpace(DName, Sectors, Bytes,_

freeClusters, totalClusters)

Label6 Caption = Sectors * Bytes * freeClusters



‘Определяем путь к текущему каталогу

retValue = GetCurrentDirectory(255, buffer)

Label7 Caption = buffer

‘Определяем путь к каталогу Windows

retValue =

GetWindowsDirectory(buffer, 255)

Label8 Caption = buffer

Screen MousePointer

= vbDefault

DoEvents

Debug

Print App = Path

End Sub

Private Sub Form_Load()

Drivel_Change

End Sub

Прочие файловые функции

Иногда пользователю требуется информация о файле, например, о его разме­щении, атрибутах или размере. Приложение Filelnfo (рис. 13.3) на компакт-диске демонстрирует возможности получения информации о файле с помощью API-функций.



Рис. 13.3. Приложение Filelnfo

VB6 в действии: проект Filelnfo

Приложение Filelnfo использует следующие функции:

•  GetFullPathName()

•  GetFileAttnbutes()

•   GetFileSize()

Рассмотрим их подробнее.

GetFullPathName(). Функция возвращает полный путь к файлу. Объявляется она следующим образом:

Private Declare Function GetFullPathName Lib "kernel32" _

Alias "GetFullPathNameA" (ByVal IpFileName As String, _

ByVal nBufferLength As Long, ByVal IpBuffer As String, _

ByVal IpFilePart As String) As Long

В приложении Filelnfo эта функция используется для получения пути к файлу, указанному пользователем в стандартном диалоговом окне File Open (Открыть файл)

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

GetFileAttributes().

Функция возвращает длинное целое значение, указывающее на состояние файла только для чтения, скрытый или нормальный. Она аналогична функции GetFileAttributes() в Visual Basic. Объявляется следующим образом:

Private Declare Function GetFileAttributes Lib "kernel32"

Alias

"GetFileAttributesA" (ByVal IpFileName As String) As Long

В табл. 13.3 приведены значения атрибутов файла. Использование этих функции продемонстрировано в программе Filelnfo.

Таблица 13.3. Атрибуты файлов

Значение

Описание

FILE_ATTRIBUTE_ ARCHIVE

Архивный файл

FILE_ATTRIBUTE_ COMPRESSED

Сжатый файл

FILE_ ATTRIBUTE_ DIRECTORY

Имя каталога

FILE_ATTRIBUTE_ HIDDEN

Файл или каталог является скрытым: при обычном выводе на экран его не видно

FILE_ATTRIBUTE_ NORMAL

Файл не имеет атрибутов

FILE_ATTRIBUTE_ READONLY

Файл предназначен только для чтения

FILE_ ATTRIBUTE_ SYSTEM

Файл является частью операционной системы

<


GetFileSize().

Чтобы определить размер файла, следует открыть его с помощью функции CreateFile(), использовав в ней параметр OPEN_EXITING (чтобы проверить, что открываемый файл существует). После этого можно воспользоваться функцией GetFileSize(), чтобы получить размер файла в байтах. Естественно, после выполнения операции файл необходимо закрыть с помощью функции CloseHandle().

Приведем исходный текст программы Filelnfo.

Программа 13.4. Проект Filelnfo

Option Explicit

Private Declare Function GetFileAttributes Lib "kernel32"_

Alias "GetFileAttributesA" (ByVal IpFileName As String) As     Long

Private Declare Function GetFullPathName Lib "kernel32" _

Alias "GetFullPathNameA" (ByVal IpFileName As String, _

ByVal nBufferLength As Long, ByVal IpBuffer As String,_

ByVal IpFilePart As String) As Long

Private Declare Function CreateFile Lib "kernel32" Alias _

"CreateFileA" (ByVal IpFileName As String, _

ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, _

ByVal IpSecurityAttributes As Any, _

ByVal dwCreationDisposition As Long, _

ByVal dwFlagsAndAttributes As Long, _

ByVal hTemplateFile As Long) As Long

Private Declare Function GetFileSize Lib "kernel32"

(ByVal hFile As Long, IpFileSizeHigh As Long) As Long

Private Declare Function CioseHandle Lib "kernel32" _

(ByVal h0b]ect As Long) As Long

Const FILE_ATTRIBUTE_ARCHIVE = &H20

Const FILE_ATTRIBUTE_COMPRESSED =

&H800

Const FILE_ATTRIBUTE_DIRECTORY =

&H10

Const FILE_ATTRIBUTE_HIDDEN =

&H2

Const FILE_ATTRIBUTE_NORMAL =

&H80

Const FILE_ATTRIBUTE_READONLY =

&H1

Const FILE_ATTRIBUTE_SYSTFM &H4

Const GENERIC_READ =

&H80000000

Const OPEN_EXISTING =

3

Const GENERIC_WRITE = &H40000000

Private Sub Commandl_Click()

Dim retValue As Long

Dim filePath As String * 255

Dim attrFlag As Long, attrStr As String

Dim fileName As String, filePointer As Long

Dim fileSize As Long



CommonDialogI.ShowOpen

If CommonDialogI fileName <> "" Then fileName = _

CommonDialogI fileName

‘Определение пути к файлу

retValue = GetFullPathName(fileName, 255, filePath, 0)

Label5 Caption – filePath

‘Определение атрибутов файла

attrFlag = GetFileAttributes(fileName)

If (attrFlag And FILE_ATTRIBUTE_ARCHIVE) Then

_

attrStr =

"Archive"

If ( attrFlag And FILE_ATTRIBUTE_COMPRESSED) Then _

                     attrStr = attrStr & "Compressed"

If (attrFlag And FILE_ATTRIBUTE_DIRECTORY) Then _

            attrStr = attrStr & "Directory"

If (attrFlag And FILE_ATTRIBUTE_HIDDEN) Then _

attrStr = attrStr & "Hidden"

If (attrFlag And FILE_ATTRIBUTE_NORMAL) Then _

attrStr = attrStr & "Normal"

If (attrFlag And FILE_ATTRIBUTE_READONLY) Then _

attrStr = attrStr & "Read-Only"

If (attrFlag And FILE_ATTRIBUTE_SYSTEM) Then _

attrStr = attrStr & "System"

Label6.Caption = attrStr

‘ Определение размера файла

filePointer = CreateFile(fileName, GENERIC_READ Or _

GENERIC_WRITE, 0&, 0&, OPEN_EXISTING, _ FILE_ATTRIBUTE_NORMAL, 0&)

fileSize = GetFileSize(filePointer, 0&)

Label7.Caption = fileSize

CloseHandle (filePointer)

End Sub


Основные понятия


Прежде чем приводить примеры использования определенных API-функций, ознакомимся с некоторыми основными понятиями. Win32 API состоит из функций, структур и сообщений, позволяющих создавать приложения для Windows 95/98 и Windows NT.

API-функции Windows можно разделить на следующие функциональные группы:

• Windows Management (Управление Windows);

•  Graphic Device Interface - GDI (Интерфейс графических устройств);

•  System Services (Kernel) (Системные ресурсы (Ядро системы));

•  Multimedia (MMSystem) (Средства мультимедиа).

Функции, входящие в состав этих элементов, организованы в виде DLL-библиотек (Dynamic Link Libraries - библиотеки динамической компоновки), и для получения доступа к ним можно воспользоваться любым языком программиро­вания. DLL загружается только на время выполнения программы, поэтому нет необходимости включать ее в приложение на этапе компоновки. Поскольку API-функции используются также и Windows, DLL-библитотеки всегда доступны вашим приложениям.

Функции группы Windows Management (Управление Windows) —

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

Graphic Device Interface (Интерфейс графических устройств) предоставляет функции, использующиеся для организации управления всеми графическими устройствами, поддерживаемыми системой, включая монитор и принтер. Кроме того, они позволяют задавать шрифты, перья и кисти. GDI также поддерживает операции вывода линий и окружностей, а также операции побитовой обработки изображений с помощью функции BitBlt(). (Подробнее с операциями обработки битов изображения можно познакомиться в гл. 7 "Цвет и пиксели в Visual Basic").

Функции группы System Services (Системные ресурсы) используются для полу­чения доступа к ресурсам компьютера и операционной системы. Мы рассмотрим, как можно использовать эти функции для определения доступности некоторых ресурсов системы во время работы приложения.

Функции из группы Multimedia (Средства мультимедиа) позволяют воспроизво­дить звук, MIDI-музыку и цифровое видео. Для этого следует воспользоваться MCI-командами и интерфейсом MCI-сообщений, которые подробно рассматрива­ются в Приложении В "Using Multimedia Elements to Enhance Applications"

("Исполь­зование элементов мультимедиа для расширения приложений") на компакт-диске.



Основные теги


HTML

Независимо от того, что вы собираетесь делать в Web, некоторые основные понятия HTML необходимо усвоить. Программисту на Visual Basic изучить и использовать HTML достаточно просто. В этой главе приведена информация по HTML, необходимая для создания функционирующих Web-страниц. Опишем теги, сгруппированные по категориям, для создания простых HTML-документов.

Заголовки

Заголовки разделяют части документа. Подобно документам, подготовленным текстовым процессором, HTML-документы могут иметь заголовки, вставляемые тегом <Нn>. Существует шесть уровней заголовков от <Н1> (наивысший) до <Н6> (самый низкий). Для размещения в начале документа заголовка первого уровня используется тег <Н1>.

<H1>Welcome to Our Fabulous Site</H1>

К этой же группе относится тег <HR>, который отображает горизонтальную линию и используется для разделения частей документа. Документ, изображенный на рис. 19.2 и демонстрирующий использование HTML-тегов, сгенерирован следующим HTML-файлом.

<HTML>

<HEAD>

<TITLE>

Document title

</TITLE>

</HEAD>

<BODY>

<Hl>Sample HTML Document</Hl>

<HR>

<H3>The Document body may contain:</H3>

<H4>Text, images, sounds and HTML commands<H4>

</BODY>

</HTML>

Рис. 19.2. Простой HTML-документ с заголовками и линией

Форматирование абзаца

HTML не разрывает строки абзаца до тех пор, пока в текстовом файле не вставить символ перехода на новую строку. Формат абзаца определяется используемыми в документе шрифтами и размером окна броузера. Чтобы начать новый абзац, нужно дать точное указание броузеру вставить символ перехода на новую строку, используя тег <Р>. Тег <Р> также заставляет броузер вставить дополнительное вертикальное пространство. Чтобы форматировать абзацы без дополнительного вертикального пространства, используется тег <BR>.

Как протестировать HTML-теги

Хотя существуют WYSIWYG-инструменты для создания HTML-документов, простой редактор, например Notepad, также позволяет проверить несколько тегов, о которых говорилось в этой главе. Для этого создайте простой текстовый файл с описанной ранее структурой HTML-файла. Сохраните его как TEST.HTM (можно использовать любое имя, но расширение должно быть НТМ). Когда этот файл будет сохраняться впервые, выберите All Files в поле Save As Type диалогового окна Save As. Если не изменить расширение по умолчанию, то будет добавлено расширение ТХТ, и файл будет назван TEST.HTM.TXT.


После сохранения документа переключитесь в Internet Explorer и откройте документ, выполнив команду Open меню File. Теперь можно переходить от текстового редактора в броузер и обратно, редактировать HTML-файл и сохранять его, пере­ключаться в окно Internet Explorer и загружать обновленную версию этого файла нажатием клавиши F5.

Форматирование символов

HTML предлагает набор тегов, предназначенных для форматирования слов и символов. В табл. 19.1 перечислены основные теги форматирования символов. Тег FONT и его аргументы описаны ниже.

Таблица 19.1. Основные теги форматирования символов

Тег

Действие

<В>

<I>

<TT>

<ЕМ> <CODE>

Включает атрибут полужирного начертания

Включает атрибут курсивного начертания

Включает атрибут машинописного стиля, используется для распечатки листингов

Выделяет текст, идентичен тегу <I>

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

Тег <FONT>. Задает имя, размер и цвет используемого шрифта. Принимает один или более аргументов, описанных ниже.

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

<FONT SIZE=1>tiny type</FONT>

А следующий тег отображает текст максимального размера

<FONT SIZE=7>HUGE TYPE</FONT>

• FACE. Задает шрифт, использующийся для отображения текста. Если заданный шрифт отсутствует на компьютере клиента, то броузер заменит его наиболее близким. Следующий тег отображает текст шрифтом Comic Sans MS

<FONT FACE = "Comic Sans MS"> Some text </FONT>

Можно задать несколько шрифтов Броузер использует первый заданный шрифт. Если он недоступен, то пробует подключить следующий и т.д.

<FONT FACE = "Comic Sans MS, Arial"> Some text </FONT>

Если шрифт Comic Sans MS отсутствует на клиентском компьютере, то броузер отображает текст шрифтом Arial (стандартный шрифт Windows, имеется на любой машине). Некоторые интересные шрифты используемые для оформления Web страниц (Verdana, Comic Sans MS и Tahoma), устанавливаются отдельно с Internet Explorer.

• COLOR. Задает цвет текста шестнадцатеричным числом (#FFOOFF) либо именем Internet Explorer распознает следующие имена цветов

Aqua        Gray          Navy            Silver

Black       Green         Olive           Teal

Blue         Lime          Purple          White

Fuchsia    Maroon      Red              Yellow

Следующие строки отображают текст красным (Red) цветом.

<FONT COLOR=Red>Thi4 is red text</FONT>

<FONT COLOR= #FF0000>This is red text</FONT>

Можно комбинировать несколько атрибутов в одном теге

<FONT>

<FONT FACE "Arial, Sans" SIZE=5 COLOR=Red>


Открытие базы данных


Для получения доступа к базе данных NWIND из кода активной серверной страницы необходимо создать объект Connection методом Server. CteateObject.

Set DBConnection = Server.CreateObject("ADODB.Connection")

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

DBConnection.Open "NWINDDB"

Первый аргумент метода Open — имя источника данных, соответствующего открываемой базе данных. После получения из базы требуемых записей следует освободить объект Connection, вызвав его метод Close.

DBConnection.Close

Совет

Описанный метод предпочтительнее при работе с базами данных Microsoft Access. Если вы работаете с базами SOL Server, то переменную DBConnection следует создавать в коде обработчика события Application_OnStart. Тогда она будет доступна всем клиентам, которым необходим доступ к базе NWIND. Система управления базами данных SQL Server поддерживает многоканальный доступ, а драйвер Microsoft Access ODBC — нет. (Он создает набор подключений, из которых используется первое доступное.) Именно поэтому после завершения работы с базой данных необходимо освобождать объект Connection.



Отображение баз данных


Visual Data Manager - одно из самых простых специальных средств разработки баз данных. Эти средства позволяют исследовать и изменять структуру базы данных и, в некоторых случаях, вводить данные. Можно получить доступ к структуре базы данных из приложения с помощью ряда объектов.

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



Содержание раздела