Ключевые свойства элемента управления
Как уже известно, объект 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 |
Создание специальных частей интерфейса
В этом окне, можно добавить свойства, события и методы, которые являются уникальными для данного элемента управления. Для этого выполните следующие действия.
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 |
Когда объект активизирован для редактирования, этот метод позволяет отбросить все изменения, которые приложение, создавшее объект, может отменить |
Этот метод позволяет отобразить диалоговое окно 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> Отображает текст шрифтом с постоянным шагом, используется для распечатки листингов |
• 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.
Содержание раздела