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

         

Отображение нескольких имен авторов


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

Можно, например, добавлять имена авторов в элемент управления ComboBox или ListBox. Можно легко модифицировать программу, чтобы она отображала все имена авторов, если считать, что имена второго и третьего авторов любого издания появляются именно после первой совпадающей записи в таблице Title Authors. Можно вызвать метод MoveNext для объекта AUTHORISBN RecordSet и если его поле ISBN такое, как ISBN текущей книги, то у книги - другой автор и его имя можно отобразить. Если поле ISBN отлично от поля ISBN текущей книги, то у книги больше авторов нет.

Методы Move объекта RecordSet работают с учетом значения индекса RecordSet. Например, вызов метода MoveNext для объекта RecordSet с индексом осуществляет переход на следующую запись в индексе.



Отслеживание перемещения мыши


В практике программирования на Visual Basic часто используется событие MouseMove. Это событие позволяет пользователю контролировать движение мыши. С помощью события MouseMove можно получить информацию о коорди­натах мыши, как только ее указатель помещен на форму. В некоторых ситуациях требуется контролировать координаты определенной точки непосредственно из обработчиков событий Click или DblClick событий (обычно они не позволяют получить информацию о координатах места, в котором выполнен щелчок) или отслеживать перемещение мыши за пределами окна формы Чтобы иметь возмож­ность в любой момент определить текущее положение мыши, следует использовать функцию GetCursorPos.

Private Declare Function GetCursorPos Lib "user32" _

(lpPoint As POINTAPI) As Long

Примечание

Параметры функции GetCursorPos() рассматривались в параграфе "Объявление 32-х разрядных функций и структур".

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

В приложении MouseMov (рис. 13.5) для отслеживания перемещения мыши используется бескйнечный цикл. При этом предусматривается возможность пере­дачи управления Windows с помощью оператора DoEvents. Это позволяет Windows обрабатывать другие события (например, остановку программы) при выполнении пользователем щелчка на кнопке Stop. Если бы оператор DoEvents не использовался, то приостановить выполнение программы было бы нельзя.

Рис. 13.5. Приложение MouseMov позволяет отслеживать положение указателя мыши, даже если указатель находится за пределами окна формы приложения

Функция GetCursorPos() возвращает переменную POINTAPI, которую затем можно передать функции WindowFromPoint(), чтобы получить дескриптор окна, на котором находится указатель мыши. Как только дескриптор окна получен, можно определить имя класса окна с помощью функции Get'ClassName(), которая возвра­щает имя класса окна. Если полученное имя - SysListView32, то это значит, что мышь находится на Рабочем столе Windows. В противном случае мышь находится в другом окне.

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


Программа 13.7. Приложение MouseMov

Option Explicit



Private Declare Function GetCursorPos Lib "user32" _

(lpPoint As POINTAPI) As Long

Private Declare Function WindowFromPoint Lib "user32"

(ByVal xPoint As Long, ByVal yPoint As Long)    As Long

Private Declare Function GetClassName Lib "user32" Alias _

"GetClassNameA" (ByVal hwnd As Long,_

ByVal IpClassName As String, ByVal nMaxCount As Long) As Long

Private Type POINTAPI

X As Long

Y As Long

End Type

Private gStop As Boolean

Private Sub Commandl_Click()

Dim mousePT As POINTAPI

Dim prevWindow As Long, curWindow As Long

Dim X As Long, Y As Long

Dim className As String

Dim retValue As Long

‘ Отслеживание положения курсора

If Commandl.Caption = "Start" Then

Commandl.Caption = "Stop"

gStop = False prevWindow = 0

‘ Отслеживать до тех пор, пока процесс не будет прерван

‘ пользователем

Do

  ‘ Остановка отслеживания

  If gStop = True Then Exit Do

  Call GetCursorPos(mousePT)

  X = mousePT.X

  Y = mousePT.Y

       ‘ Получение информации об окне, на котором расположен

  ‘ указатель мыши

    curWindow = WindowFromPoint(X, Y)

    If curWindow о prevWindow Then

    className = String$(256, "")

    prevWindow = curWindow

         retValue = GetClassName(curWindow, className, 255)

 className = Left$(className, InStr(className,_

vbNullChar) - 1)

 If className = "SysListView32" Then

 Labell.Caption = "The mouse is over the desktop."

‘(Указатель мыши находится на рабочем столе.)

 Else

             Labell.Caption = "The mouse is over" & className

                        ‘(Указатель мыши находится на...)

End If

End If

DoEvents

   Loop

   ‘ Остановка отслеживания положения указателя

   Else

     Command1.Caption = "Start"

     gStop = True

  End If

End Sub

Private Sub Form QueryUnload(Cancel As     Integer,

            UnloadMode As Integer)

gStop = True

End Sub

Этот проект создан на основе проекта MousePos, который находится в соответ­ствующей папке на компакт-диске.


Панели


Страницы, которые были показаны ранее, занимали все окно броузера. Тем не менее, используя панели (frame), на экране можно отобразить несколько документов. Панели создаются тегом <FRAMESET>. Такой подход связан с определенными издержками, поэтому мы будем создавать плавающие панели (с возможностью прокрутки содержимого) с использованием тега <IFRAME>. Плавающую панель с изображением (или несколько панелей) можно разместить на странице где угодно. Пользователь не может изменить размер плавающей панели, но в рамках этой главы нас это устраивает, поскольку плавающую панель реализовать проще, чем неподвижную, создаваемую тегом <FRAMESET>.

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

<IFRAME SRC=url WIDTH=xxx HEIGHT=yyy>

Переменная

url — это URL документа, отображаемого на панели, а ххх

и ууу — размеры панели. Чтобы поместить панель посредине документа и показать до­машнюю страницу Sybex, введите следующие строки в HTML-файл, а потом от­кройте его в Internet Explorer.

<CENTER>

<Hl>Floating Frame Example</Hl><BR>

<IFRAME SRC="http://www.sybex.corn" WIDTH =500 HEIGHT=300>

</CENTER>

Результат показан на рис. 19.5 (между тегами

<CENTER> и </CENTER> все будет центрировано).

Страница, изображенная на рис. 19.6, создана для одного HTML-документа, содержащего два тега <IFRAME>. Содержание каждой панели задается атрибутом SRC, а для их размещения на странице используется тег <CENTER>.

Рис. 19.5. Плавающая панель, отображающая начальную страницу Sybex

Рис. 19.6. Панели страницы FFRAMES НТМ вложены в другую плавающую панель

Ниже приведена распечатка файла FFRAMES.HTM, который можно найти в папке данной главы на компакт-диске.

<HTML>

<HEAD>

<TITLE>Floating Frames</TITLE>

</HEAD>

<BODY BGCOLOR=black>

<FONT NAME="Verdana" COLOR=lightyellow>

<CENTER>

<Hl>Here they are...</Hl>


<H4>...side by side</H4>

<P>

<IFRAME

SRC="http://home.microsoft.com/"

NAME="MS"

WIDTH=325

HEIGHT=325

SCROLLIHG=YES

MARGINWIDTH=0

MARGINHEIGHT=0

HSPACE=8>

</IFRAME>

<IFRAME

SRC="http://home.netscape.com/"

NAME="NS"

WIDTH=325

HEIGHT=325

SCROLLIHG=YES

MARGINWIDTH=0

MARGINHEIGHT=0

HSPACE=8>

</IFRAME>

</FONT>

</CENTER>

</BODY>

</HTML>

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


Параметры API-функций


При использовании API-функций необходимо предусмотреть объявление функций и их параметров. Win32 API предназначен для программистов, работающих на языке С или С ++. Поэтому в документации используются структуры данных, принятые в С. Их необходимо преобразовать к их эквивалентам в Visual Basic. В табл. 13.1 приведены объявления, предусмотренные в языке С, и соответствующие VB-эквиваленты. В последнем столбце приведено описание способа передачи параметров API-функциям. Все типы данных передаются по значению, кроме Integer Pointer и Long Integer Pointer (указатели).

Таблица 13.1.

Соответствие типов данных в С и Visual Basic

Объявление С

Тип данных Visual Basic

Способ передачи параметров

Integer

Integer

ByVal

Integer Pointer (LPINT)

Integer

ByRef

Long

Long

ByVal

Long Integer Pointer

Long

ByRef

Stung Pointer (LPSTR)

String

ByVal

Handle

Long

ByVal

Char

String

ByVal

Void Pointer

Any

ByRef

Передача параметров по значению

Чтобы использовать API-функции в VB-приложении, необходимо ознакомиться с двумя механизмами передачи параметров — ByVal

и ByRef. Подробно они рассмотрены в гл. 3.

Когда параметры передаются по значению, вызываемая процедура работает с локальными копиями переменных. Процедура может изменить их значения, но не саму переменную в вызывающей программе. В Visual Basic для индикации такого способа передачи используется ключевое слово ByVal. Ниже приведен текст проце­дуры AnySub(), в которой параметр anyNumber передается по значению, ему присваи­вается значение 10. При выходе из процедуры исходное значение переменной восстанавливается.

Программа 13.1. Передача параметров по значению

Sub AnySub(ByVal anyNumber as Integer)

anyNumber = 10

Debug.Print anyNumber

End Sub

Если вызвать процедуру AnySub() следующим образом,

х = 1

Call AnySub(х)

Debug.Print x

то в окне проверки появится сообщение:

AnyNumber = 10

х = 1

С помощью оператора Print в процедуре AnySub() отображается значение, присвоенное переменной anyNumber внутри процедуры (локально). Значение, присвоенное переменной х в вызывающей программе (1), также появляется в окне проверки. Значение 10, присвоенное переменной anyNumber в процедуре AnySub(), вне этой процедуры недействительно.


Передача параметров по ссылке
При передаче параметров по ссылке процедуре предоставляется доступ к пере­менной в вызывающей программе. Процедура, параметр которой передается таким образом, получает адрес области памяти, хранящей значение параметра. Это дает ей возможность изменять значение параметра. В Visual Basic такой механизм передачи значений параметров устанавливается по умолчанию. В следующем примере процедура AnySub() изменяет значение параметра.
Программа 13.2. Передача параметров по ссылке
Sub AnySub(mylnt As Integer)
mylnt
= 20      ' теперь переменная mylnt имеет значение 20
End
Sub
Если теперь вызвать эту процедуру,
Dim x
As Integer
{Требуемые операторы}
х
= 4
Debug.Print "Before calling AnySub x = " &
x
' (Перед вызовом AnySub x
=...)
Call AnySub(x)
Debug.Print "After calling AnySub x = " & x
' (После вызова AnySub x
=...)
то в окне Debug появятся следующие строки:
{Перед вызовом AnySub х = 4
После вызова AnySub х = 20
Изменение значения переменной х процедурой AnySub() носит глобальный характер, поскольку значение параметра передавалось по ссылке. Если нет оснований разрешать вызываемой процедуре глобальное изменение значений параметров, то параметры необходимо передавать по значению. Некоторые API-функции сохраняют результаты работы, изменяя значения переданных им параметров, поэтому предполагается, что параметр такой функции должен переда­ваться по ссылке. В языке С такие параметры называются указателями (pointers), так как они указывают на область памяти, в которой хранится значение переменной.

Печать и сохранение документов


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

Printout:

Printout Background, append, range, outputfilename, from, to, _

item, copies, pages, PrintToFile, Collate,

_

ActivePrinterMacGX, Manual Duplex Print

Все параметры необязательные и соответствуют свойствам, которые вы можете установить в диалоговом окне Print программы Word. Значение параметра Background определяет, будет ли печать выполняться в фоновом режиме. Обычно этому параметру присваивают значение True (при автоматизации приложений).

Совет

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

AppWord.ActiveDocument.Printout from:=1, to:=3

При использовании VBA для указания Word напечатать документ процесс по­становки документа в очередь на печать выполняется не мгновенно. Если попы­таться закрыть Word сразу после вызова метода Printout, то он сообщит, что завер­шение работы в данный момент приведет к отмене процедуры печати. Чтобы удостовериться в том, что документ был записан в буфер (это означает, что можно правильно завершить работу Word), необходимо организовать цикл, в котором будет выполняться проверка значения свойства BackgroundPnntingStatus. До тех пор, пока это значение не равно 0, приложение выполняет запись информации в буфер. После того как будет переписана вся информация, можно выйти из Word. Этот прием будет использован в параграфе " VB6 в действии проект WordVBA" далее в этой главе.

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

SaveAs FileName, File Format, LockComments, Password, _

AddToRecentFiles, WritePassword, ReadOnlyRecomitiended, _

EmbedTrueTypeFonts, SaveNativePictureFormat, _

SaveFormsData, SaveAsOCELetter

Как и в случае с методом Print, параметры метода SaveAs соответствуют установкам диалогового окна Save As приложения. Если файл был предварительно сохранен, следует использовать метод Save, для обращения к которому вообще не требуется задавать параметры. Он позволяет выполнить сохранение документа в файле, используя опции, определенные в методе SaveAs (при самом первом сохранении документа) Чтобы сохранить активный документ в файле с другим именем, следует воспользоваться следующим выражением:


AppWord.ActiveDocument.SaveAs "с:\Documents\Report99.doc"

К свойствам объекта Document также относится свойство Saved,

которое воз­вращает значение True

или False,

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

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

Программа 14.9. Открытие и печать DOC-файла

Dim WordApp As Word.Application

Dim thisDoc As Document

Dim prnTime As Date

Dim breakLoop As Boolean

Set WordApp = CreateOb]act ("Word Application")

WordApp.Visible - False

WordApp.Documents.Open ("c:\sarriple.doc")

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 quit7", vbYesNo)

'(Word слишком долго выполняет

'печать ... Остановить печать?)

If Reply = vbYes Then

breakLoop = True

Else

prnTime = Time

End If

End If

Wend

WordApp.Quit

MsgBox "Document saved and printed!"

' (Документ сохранен и напечатан')

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

Из-за аппаратных ошибок этот процесс может никогда не закончиться, и, сле­довательно, приложение будет заблокировано. Каждую минуту, программа спра­шивает пользователя, будет ли он ждать или нет. Если пользователь принимает решение завершить распечатку, переменная breakLoop принимает значение True, что приводит к прерыванию цикла While...Wend. Это достаточно простой подход, хотя он требует больших затрат времени работы процессора. Гораздо более эффек­тивным представляется использование в форме элемента управления Timer, позво­ляющего программно контролировать процесс печати документа.


Перечислимые свойства


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

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

Тип данных, который содержит малое число значений, называется Enumerated (перечислимым) типом. Integer, Double и другие числовые типы данных являются базовыми и могут представлять числовые значения. Если приложение использует переменную, которая может принимать только ограниченное число целочисленных значений, можно использовать перечислимый тип. Свойство TextAlignment как раз и является такой переменной, поскольку может принимать только одно из нескольких целочисленных значений. Дни недели, например, или месяцы года также являются примерами данных перечислимого типа. Для того чтобы создать перечислимый тип, сначала необходимо объявить значения перечислимого типа. Таким образом VB узнает, какие из значений являются допустимыми. Вставьте следующее объявление перечислимого типа в начало кода сразу после оператора Option Explicit:

Enum Align

[Top Left]

[Top Middle]

[Top Right]

[Center Left]

[Center Middle]

[Center Right]

[Bottom Left]

[Bottom Middle]

[Bottom Right]

End Enum

Это объявление сообщает Visual Basic, что любая переменная, объявленная как Align,

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


Теперь необходимо заменить тип свойства TextAlignment с Integer на Align (этот перечислимый тип мы только что объявили), так как тип свойства TextAlignment должен быть именно перечислимым. Откройте проект FLEXLabel и выполните следующие изменения:

1. Выберите объект UserControl, откройте окно с его кодом и в начале кода вставьте следующее определение типов:

Enum Align

[Top Left]

[Тор Middle]

[Top Right]

[Center Left]

[Center Middle]

[Center Right]

[Bottom Left]

[Bottom Middle]

[Bottom Right]

End Enum

2. Измените определения процедур Property Let и Property Get свойства TextAlignment таким образом, чтобы они имели тип Align (вместо Integer). Сделать это можно следующим образом:

Public Property Get TextAlignment() As Align

TextAlignment = m_TextAlignment

End Property

Public Property Let TextAlignment (ByVal New_TextAlignment _

As Align)

M_TextAlignment = New_TextAlignment

PropertyChanged "TextAlignment"

End Property

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


Первичный ключ


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

Когда не имеется явного поля или набора полей, которые могут использо­ваться для формирования композитного первичного ключа, система управления базами данных Visual Basic (механизм JET) может автоматически генерировать уникальный числовой ключ для каждой записи. Этот ключ предназначен для добавления к таблице поля и установки его типа AutoNumber. Автонумеруемое поле автоматически увеличивается на единицу всякий раз, когда добавляется новая запись. Это гарантирует уникальность ключа, хотя сам ключ не обязательно может что-нибудь означать. До тех пор, пока все таблицы ссылаются на одну запись с помощью одного и того же ключа, последний не обязательно должен иметь содер­жательный смысл. Иногда автоматически нумеруемый первичный ключ создается для конкретных целей, например, при использовании автоматически нумеруемого поля для номера счета.

Независимо от типа первичного ключа целесообразно делать первичный ключ таблицы полем типа Long (см. гл. 3). Таким образом вы значительно упрощаете разработку других таблиц.



Подход, ориентированный на работу с данными


OLE позволяет сконцентрироваться на работе с данными. Пользователю доста­точно знать, что

необходимо сделать, а не как

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

Excel или для работы с текстом - только WordPerfect. OLE-приложение предоставляет пользователю доступ к функциональным возможностям электронной таблицы, текстового процессора или графической программы, и все это — внутри одной программы, называемой приложением-контейнером (container application). Visual Basic позволяет создавать компоненты, которые могут использовать функциональные возможности других прикладных программ, и приложения, содержащие составные документы.

Примечание

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



Подключение к Web-серверу


Чтобы подключиться к Web-серверу, запустите Internet Explorer и введите следующий адрес в поле Address броузера.

http://127.Ci.0.1

Это адрес локального компьютера, действительный на любой машине -зарезервированный IP-адрес для подключения к серверу, запущенному на компьютере, с которого поступил запрос на подключение. После введения этого адреса Web-сервер отображает документ по умолчанию. Вы можете скопировать в корневой каталог сервера любой HTML-документ и открыть его, передав его имя после адреса сервера. Еще лучше — создайте виртуальную папку для каталога C'\INETPLIB\WWWROOT, назовите ее MVB6 и скопируйте в нее HTML-файлы, которые будут тестироваться в это главе. По следующему адресу можно открыть файл Calendar.htm в окне броузера.

http://127.0.0.1/MVB6/Calendar.htm

В следующем параграфе мы научимся разрабатывать выполняемые на сервере приложения, которые можно запускать с компьютера клиента. Оказывается, что разработка таких приложений не составляег особого труда. Это такие же сценарии, которые можно встроить в HTML-страницу, только выполняются они на сервере. Их называют активными серверными страницами (Active Server Pages — ASP) и, имея навыки программирования на Visual Basic, можно немедленно присгупать к их программированию.

Visual Basic предоставляет специальный тип проекта — тип IIS Application — позволяющий автоматизировать процесс разработки активных серверных страниц. Даже при наличии таких средств достаточно сложно создать сценарий, имеющий практическое применение, без знания основ работы сценариев на сервере и объектов для взаимодействия с клиентом, предоставляемых ASP.



Подключения


Для явного подключения к источнику данных объявите переменную Connection с помощью выражения:

Dim ADOConn As New ADODB.Connection

Вызовите метод Open объекта ADOConn, передавая в качестве аргумента строку подключения.

ADOConn.Open "DSN=AdvWorks;UID=xxx;PWD=xxx"

(Здесь ххх -идентификатор пользователя и пароль соответственно.) Аргумент DSN — имя источника данных Data Source.

Когда объект Connection создан, его можно назначить свойству ActiveConnection объектов RecordSet или Command.



Получение информации


Outlook сохраняет разнотипную информацию в различных файлах. Информация о контактах хранится в файле Contacts (Контакты), входящие сообщения хранятся в папке InBox и т.д. Большинство пользователей, однако, изменяет структуру папок, предлагаемьи Outlook, добавляя дополнительные подпапки к заданным по умолчанию. Например, чтобы упорядочить информацию о контактах, можно создать подпапки Business и Personal в папке Contacts (Контакты). Аналогично, в папке InBox можно создать папки Business, Personal и Junk.

Типичной задачей, которую требуется решать, является поиск желаемой инфор­мации. В последующих примерах будет рассматриваться способ доступа к контактам и входящим сообщениям в папках Contacts и InBox, соответственно.

VB6 в действии: проект Contacts (Контакты)

В качестве первого примера того, как, используя средства OLE, можно работать с Outlook, будет рассмотрено приложение Contact, форма которого приведена на рис. 14.20. В этом приложении подразумевается, что все объекты, относящиеся к контактам, хранятся в папке Contacts. Если контакты пользователя организованы по-другому, например, в отдельных подпапках в папке Contacts, следует скопировать (на время) несколько соответствующих файлов в эту папку, чтобы можно было проверить приложение. Чуть позже, в параграфе "Рекурсивный просмотр папки Contacts" будет рассмотрена рекурсивная процедура просмотра всей папки Contacts (включая подпапки).

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


Программа начинает свою работу с обращения к Outlook ( после щелчка на кнопке Start Outlook). Ниже приведен код обработчика нажатия соответствующей кнопки.



Рис. 14.20. В проекте Contacts выполняется поиск информации о контактах объекта в папке Contacts в Outlook

Программа 14.18. Обращение к Outlook

Private Sub Commandl_Click ()

On Error GoTo OutlookNotStarted

Set OLApp - CreateOb^ect ("Outlook Application")

On Error GoTo NoMAPINameSpace

Set mNameSpace - OLApp GetNamespace ("MAPI")

List1.Clear

List2.Clear

Command2.Enabled = True

Exit Sub

OutlookNotStarted:

MsgBox "Could not start Outlook"

' (Невозможно запустить Outlook)

Exit Sub

NoMAPINameSpace:

MsgBox "Could not get MAPI NameSpace"

' (Невозможно получить место нахождения MAPI)

Exit Sub

End Sub

Если обращение к Outlook было успешным, кнопка View Contact становится доступной. Если щелкнуть на этой кнопке, программа создаст семейство, содер­жащее все объекты, находящиеся в папке Contacts, и отсортирует семейство allContacts согласно названиям компаний. Повторяющиеся названия будут удалены из списка (это обеспечивается оператором If, находящимся в конце подпрограммы). Текст программы обработчика кнопки View Contact приведен ниже.

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

Private Sub Command2_Click()

Set allContacts = _

mNameSpace.GetDefaultFolder(olFolderContacts).Items

all Contacts.Sort = "CompanyName"

On Error Resume Next

For Each mContact In allContacts

If Trim(mContact.CompanyName) <> "" Then _

List1.Addltem mContact.CompanyName

If List1.List(List1.Newlndex) =

List1.List(List1.Newlndex - 1) Then

List1.Removeltem List1.Newlndex

Next

End Sub

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

Программа 14.20. Получение списка контактов в выбранной  компании

Private Sub Listl_Click()

Dim CompanyName As String

Dim filterString As String



If List1.Listlndex = -1 Then Exit Sub

CompanyName = Listi.Text

filterString = "[CompanyName] = " " " & CompanyName & " " " "

Set thiscontact =

allContacts.Find(filterString)

If IsNull(thiscontact) Then

MsgBox "Fatal error in locating a contact.Program will exit"

' ( Фатальная ошибка при поиске контакта. Работа

' программы будет завершена)

End

End If

List2.Clear

While Not thiscontact Is Nothing

If Trim(thiscontact.FullName) <> " " Then _

List2.Addltem thiscontact.FullName

Set thiscontact = allContacts.FindNext

Wend

End Sub

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

Программа 14.21. Вывод информации о контакте

Private Sub List2_Click()

Dim ContactName As String

Dim filterString As String

If List2.ListIndex = -1 Then Exit Sub

ContactName = List2.Text

filterString= "[FullName]= " " " & ContactName & " " " "

Set thiscontact = allContacts.Find(filterString)

If IsNull(thiscontact) Then

MsgBox "Fatal error in locating a contact. Program will exit"

 ' Фатальная ошибка при поиске контакта. Работа

 ' программы будет завершена)

End

End If

IblName.Caption = "" & thiscontact.Full Name

IblPhone.Caption = "" & thiscontact.BusinessTelephoneNumber

IblFAX.Caption = "" & thiscontact.BusinessFaxNumber

IblEMall.Caption = "" & thiscontact.EmaillAddress

End Sub

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

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



Приложение Messages (рис. 14.21) позволяет выбирать сообщения, основываясь на информации об их отправителе или дате отправления. Критерии поиска задаются пользователем путем ввода соответствующих значений в окна, расположенные в правом верхнем углу формы. После ввода следует щелкнуть на кнопке Show Selected Messages (Показать выбранные сообщения), чтобы отобразить сообщения, отвечающие заданным критериям. Программа будет выводить только имя отправи­теля сообщения и тему. Затем, каждый раз, когда пользователь будет выбирать одно из сообщений в этом списке, щелкая на нем, подробная информация о нем будет отображаться в окнах соответствующих элементов управления в нижней части формы (включая текст сообщения). Если сообщение, содержит присоединенные файлы, их имена отображаются в окне сообщения. Запустите этот проект и поэкспериментируйте с ним. Впрочем, имеются две проблемы, о которых следует знать. Во-первых, приложение Messages может просматривать только сообщения в папке InBox. Если сообщения находятся в подпапках папки InBox, следует переместить (на время) несколько сообщений в папку InBox. Вторая проблема заключается в том, что имена отправителя читаются из папки Contacts. Если имена в папке Contacts не соответствуют именам, которые появляются в сообщениях, то нельзя будет увидеть сообщения, посланные выбранным контактом.



Рис. 14.21. В проекте Messages демонстрируется возможность чтения входящих сообщении Outlook из VB-приложений


Пользовательские элементы управления ActiveX на Web-страницах


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

Microsoft предлагает большое количество элементов управления ActiveX для использования на Web-страницах. Некоторые из них поставляются вместе с Internet Explorer, включая такие элементы управления, как Structured Graphics, Filter и Sequencer. Дополнительную информацию и примеры использования можно найти по адресу http://www.microsoft.com/workshop. Практически, каждый элемент управления ActiveX, размещенный на форме Visual Basic, можно использовать и на Web-странице (если он загружен и проинсталлирован на компьютере клиента). В следующих пара­графах рассказывается, как использовать на Web-страницах пользовательские элементы управления ActiveX, созданные в предыдущих главах.

Страница ALARM.HTM

В этом параграфе рассматривается создание Web-страницы с использованием элемента управления ALARM (см. гл. 16). Зачем утруждать себя размещением будильника на Web-странице (кроме как для наглядной демонстрации возможностей пользовательских элементов управления при помощи VBScript)? На рис. 19.8 показана одна причина. Страница содержит таймер, который позволяет пользователю читать страницу за 60 секунд. Пользователь всегда может оставить страницу, введением другого URL в поле Address броузера или нажатием кнопки Back. Если пользователь продержит эту страницу открытой 60 секунд, то сценарий автоматически предоставит ему или ей другую страницу.


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

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



Рис. 19.8. Пользовательский элемент управления Alarm на Web-странице

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

Начнем с тегов HTML для размещения, например, экземпляра элемента управления Alarm на Web-странице.

<OBJECT ID="AlarmCtl" NAME="AlarmCtl"

classid="cisid:7282EB2E-B8A9-11CF-B2FB-005348C101FC"

border="0"

width="120" heigth="33">

<PARAM NAME="CountDown" value "True">

</OBJECT>

Teг <OBJECT> вставляет элемент управления ActiveX на страницу, но его синтаксис, мягко говоря, специфический. Однако вам нет потребности вводить его вручную. Каждый элемент управления ActiveX имеет свойства NAME и ID, подобно встроенным элементам управления. Свойство CLASSID представляет собой длинную строку, которая идентифицирует элемент управления в системном реестре. Чтобы создать определение объекта на странице, используют WYSIWYG-редактор HTML, такой как Frontpage Express (поставляется вместе с Internet Explorer). Создадим новую HTML-страницу и вставим требуемый элемент управления ActiveX, выполнив следующие действия.

1. Выберите команду ActiveX диалогового окна Other Component меню Control Insert, чтобы открыть диалоговое окно ActiveX Control Properties.





2. Откройте  раскрывающийся  список  Pick a Control  и  найдите пункт AlarmProjectAlarmCtl. Таким образом, элемент управления ActiveX Alarm будет занесен в список Registry (Если Alarm ProJect.AlarmCtI в списке не появился, то следуйте инструкциям следующей врезки ''Регистрация пользовательских элемен­тов управления ActiveX").

3. Установите имя элемента управления как AlarmCtl.

4. Щелкните на кнопке Properties, чтобы установить дополнительные свойства пользовательского элемента управления. Для элемента управления Alarm установите в свойстве Count Down значение True.

5. Щелкните на кнопке ОК, чтобы закрыть диалоговое окно.

6. Выберите команду HTML меню View, чтобы открыть текстовый редактор, отображающий исходный код страницы. Выберите определение тега <OBJECT> и скопируйте его в Clipboard.

7. Переключитесь в текстовый редактор HTML-документа и вставьте определение тега <OBJECT>.

Как видите, вставить тег <OBJECT> на Web-страницу для пользовательского элемента управления не сложно. Это определение не изменяется, даже когда тег устанавливается на другом компьютере. Также тег <OBJECT> можно скопировать из любой Web-страницы, содержащей его.

Регистрация пользовательских элементов управления ActiveX

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

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

1. Создайте ОСХ-файл элемента управления, выбрав команду Make control.ocx (control — это имя пользовательского элемента управления) меню File.

2. Переключитесь на сеанс работы с DOS, чтобы отобразилась командная строка DOS, перейдите в папку, в которой сохранен ОСХ-файл, и введите команду:

С:\windows\system\regsvr32 control.ocx

Замените

control.ocx именем ОСХ-файла, необходимым для регистрации.

3. Выйдите из DOS.

Новый элемент управления может использоваться в любом проекте, даже на Web-страницах. В среде разработки Visual Basic имя пользовательского элемента управления появится в диалоговом окне Components (чтобы открыть это диало­говое окно, выберите команду Components меню Project). Такое же имя появится в диалоговом окне свойств элементов управления ActiveX Frontpage.



Значение элемента управления CLASSID будет отличаться в конкретной систе­ме. Поэтому, нельзя использовать файл ALARM.HTM в том виде, в котором он нахо­дится на компакт-диске. Необходимо изменить атрибут CLASSID на значение, гене­рируемое вашей системой.

8. Введите соответствующий текст и теги HTML на страницу, сохраните ее как ALARM HTM и откройте с помощью Internet Explorer.

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

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

<SCRIPT LANGUAGE="VBScript">

Sub window_onLoad()

AlarmCtl.AlarmTime = Time + #00:01.00#

Call AlarmCtl.StartTimer()

End Sub

Sub AlarmCtl_TimeOut()

Call window.navigate ("http://www.sybex.corn")

End Sub

</SCRIPT>

Событие window_onLoad инициируется при загрузке страницы. В этом событии необходимо инициализировать свойства элемента управления. Установите свойство AlarmTime на минуту вперед от текущего времени и начните отсчет. Свойство CountDown было установлено при определении тега <OBJECT> следующей командой в обработчике события onLoad.

AlarmCtl.CountDown =

True

Свойство AlarmTime не может быть установлено в режиме разработки — только в сценарии страницы.

Когда истечет указанный промежуток времени, будет инициировано событие AlarmTime. В его обработчике нужно запрограммировать броузер на переход на другую страницу с использованием метода Window.Navigate.

Программа 19.2. Страница Alarm.htm

<HTML>

<HEAD>

<SCRIPT LANGUAGE="VBScript">

Sub window_onLoad()

AlarmCtl.AlarmTime = Time + #00:01.00#

Call AlarmCtl.StartTimer()

End Sub



Sub AlarmCtl_TimeOut()

Call window.navigate ("http://www.sybex.corn")

End Sub

</SCRIPT>

<TITLE>Alarm Demo Page</TITLE>

</HEAD>

<BODY>

<OBJECT id="AlarmCtl " NAME="AlarmCtl"

classid="clsid:7282EB2E-B8A9-llCF-B2FB-005348C101FC"

border="0"

width="120" heigth="33">

<PARAM NAME="CountDown" value="True">

</OBJECT>

<CENTER>

<Hl>The Alarm Page Demo</Hl>

<FONT SIZE=4>

You will be given 60 seconds to read the important information on

this page and then you'll be taken to our home page.

<BR>

The little alarm clock at the top of the page will count down every

second and when it reaches zero, your computer will be connected to

SYBEX home page.

<FONT SIZE = 3>

<HR>

If you are not connected to the Internet, you'll get an error message

instead.

<HR>

</BODY>

</HTML>

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

1. Откройте Internet Explorer.

2. Выберите команду Open в меню File, и в диалоговом окне откройте файл Alarm.htm.

3. Подождите 60 секунд, и сценарий загрузит домашнюю страницу SYBEX.

Элемент управления Alarm хорошо работает в Internet Explorer, и нет необ­ходимости в его доработке. Он ведет себя точно так, как в среде Visual Basic. Он предоставляет свои свойства и методы, а его события можно программировать.

Страница UINPUT.HTM

Страница UINPUT.HTM (рис. 19.9) демонстрирует использование элемента управления ActiveX CTextBox на Web-странице. Воспользуйтесь схемой из предыду­щего параграфа для создания с помощью Frontpage определения тега <OBJECT>, a затем добавьте текст и HTML-теги Тег <OBJECT> для вставки элемента управления CTextBox показан ниже.

<OBJECT id="CTextBox"



NAME= "CTextBoxl"

classid="clsid 7282EB5A-B8A9-11CF B2FB-005348C101FC"

border="0"

WIDTH="150" HEIGHT="19">

</OBJECT>



Рис. 19.9. Страница UINPUT HTM использование элемента управления CTextBox для получения от пользователя обязательных и необязательных данных

Сценарий страницы прост. Он инициализирует элементы управления, задавая их свойства Mandatory и Text.

Sub window_onLoad()

CTextBox1.Mandatory=1

CTextBox2.Mandatory=1

CTextBox6.Mandatory=1

CTextBox1.Text=" "

CTextBox2.Text=" "

CTextBox3.Text=" "

CTextBox4.Text=" "

CTextBox5.Text=" "

CTextBox6.Text=" "

EndSub

Если эти элементы управления используются для сбора данных от пользователя, то на форме будет кнопка Submit. Чтобы до передачи данных на сервер удостове­риться, что требуемым полям присвоены значения, используйте событие onClick кнопки. На компакт-диске находится страница LABEL3D.HTM, которая использует пользовательский элемент управления FLXLabel (гл. 16) для отображения выпуклого и тисненого текста в окне броузера. Чтобы протестировать элемент управления FLXLabel на Web-странице, необходимо зарегистрировать элемент управления в системе, а затем разместить на странице атрибут CLASSID элемента управления со значением, заданным Visual Basic.


Предметный указатель


символы

<> (знаки меньше и больше), ограничители HTML-тэгов...................... 351

> (знак больше) в поиске записей.. 278-279

< (знак меньше), в поиске записей.. 278—279

! (восклицательный знак), метасимвол в операторе

LIKE................. 287

" (двойная кавычка) в параметрах формы.................................. 491

' (одинарная кавычка), в критерии......... 259

# - (знак решетки)

- метасимвол в операторе LIKE............. 287

- представление даты............................... 427

% (знак процента)

- в разделе Form Web-страницы............. 491

- в тэгах серверного сценария................ 498

& (амперсант),

разделитель параметров ...........................491

* - (символ звездочка)

- метасимвол в SQL-операторе............... 285

- метасимвол в операторе LIKE............. 287

, (запятая)

- в разделителе списка полей................. 285

- с аргументом Wscript............................. 430

- (дефис), задание диапазона

в операторе LIKE...................................... 287

/ (наклонная черта)

- в HTML-тэгах........................................ 352

- в параметрах формы.............................. 491

? (вопросительный знак)

- в разделе Form Web-страницы............. 491

- метасимвол в операторе LIKE............. 287

[] (квадратные скобки)

- в списке полей....................................... 285

- метасимвол в операторе LIKE............. 287

_ (символ подчеркивания),

признак продолжения строки.................... 18

- (знак минус) в операторе LIKE........... 287

+ (знак плюс),

в разделе Form Web-страницы................. 491

= (знак равно) при поиске записей,

использование.................... 271-279

А

ActiveX-документ (см. также

модуль класса).......................... .........141, 439

ActiveX-конструктор

DataEnvironment ...............................309-314

— иерархия команд............................314-320

- мастер DataReport..........................326-329

- элемент DataGrid...........................321-323


- элемент MSHFlexGrid...................323-325

ActiveX-элемент

— доработка ........................................241—248

- фон......................................................... 196

- цвет.................................................. 196, 199

ActiveX ЕХЕ-компонент........................... 531

AD0.....................................................307-308

- активные серверные страницы.................................502, 518-527

— использование SQL-операторов.....336-337

— объектная модель .........................335—336

— определение типа блокировки....338-340

- определение типа курсора........ . .338-340

- подключение.......................................... 336

— применение............................................ 336

- проект Data.....................................308-310

— элемент управления Data..............330—335

API-функции Windows.......................... 16-19

- аргументы ...........................................20-21

- в приложении Filelnfo ......................27-30

— взаимодействие с приложениями....47—51

— графические........................................56-68

-доступ..................................................18-20

— используемые структуры...................21—23

- координаты объекта..........................41-44

— объявление................................... 18, 21-23

- определения свободного

дискового пространства ....................23—27

— перемещения мыши..........................39-41

- работа с меню ....................................31-39

— работа с реестром ..............................51—56

— упорядочивание окон........................44—47

— утилита просмотра.............................18-20

ASCII-файлы, объект

File ........................405

ASCII-файлы, объект

FileSystemObject...393 ASPSESSIONID cookies.................... 513-514

С

САВ-файлы................................................ 381

Common Gateway Interface (CGI).... 349-350

cookies......................................................... 517



D

DHTML-тэг.......................................383-384

DLL, вызов

API-функций.......................... 17

DLL, регистрация.............................. 162-163

Е

Excel, ячейки

..................... .............. 119-121

F

Frame, тэги

........................................363-365

FTP ( File Transfer Protocol)........................ 348

G

GIF-формат, использование в Web-страницах............. 357

H

HTML

- форматирование символов........... 355—356

- цвет.......................................................... 356

HTML-страница................................ 348-349

HTML-таблицы, ячейки................... 361-364

HTML-тэг.... ..............................354, 382-383

- <А>

....................... ........................356-357

- <В>........................................ .........352, 355

- <BODY>................................................. 353

-<BR>....................................................... 355

- <CENTER> ....................................363-365

- <ЕМ>...................................................... 355

- <FONT> .........................................355-356

- <FRAMESET> ...............................363-365

- <HEAD>................................................. 352

- <HTML>................................................. 352

- <!>................................................... 351, 355

-<IFRAME>.....................................363-365

-<IMG>............................................358-359

- <INPUT>

- элемент

CheckBox.............................. 369

- элемент

Command......................370-371

- элемент

RadioButton.......................... 369

- элемент Text ...............................367-368

- <OBJECT>..............................376-377, 381

- <OPTION> .............................................370

-<Р>.......................................................... 355



- <SCRIPT>............................................... 373

-<SELECT>......................................369-370

- <STYLE>........................ 382-383, 385-386

- <TABLE> ........................................360-364

- <TD>...............................................360, 362

- <TEXTAREA>........................................ 368

- <ТН>....................................................... 360

- <TITLE> .................................................352

- <TR>

....................................................... 360

-<ТТ>........................................................355

- чувствительность к регистру................ 352

HTTP ( Hypertext Transfer Protocol).......... 348

I

Internet Explorer.........................355, 487-488

Internet, адрес.....................................347-348

intranet.............:........................................... 347

IP-адрес....................................................... 351

J

JPEG-изображения, в

Web-страницах....357

О

OLE.........................................................68-69

- компонентное программное

обеспечение.............................................. 69

- пример WordPad ................................73-74

- составные документы........................69—70

- терминология

.....................................70-73

- центрирование документа ......................70

OLE-приложения, серверы

..................70-71

Р

Peri-сценарии............................................. 491

S

SQL-операторы, чувствительность

к регистру................................................... 285

U

URL.............................................................350

- в гиперссылках           351

- взаимодействие "клиент сервер" 492—493

V

VBA        101, 390

W

Web         346-347

Web-изображения, виртуальные пути 359

Web-изображения, размеры     359

Web сервер, адрес          351

Web-страницы   350



- активные серверные   528—530

- стартовые         358

А

Автоматизация

- Excel     105, 118

- анализ алгебраических

выражений         124—125

- использование

семейства Worksheets    119

- приложение ExcelVBA          121-123

- функция GetObject()   105

- OLE 72, 101-102

- объектные переменные 101-102, 104-105

- приложения Excel       119—124

- приложения Outlook 98          125-140

- приложения Word       107—118

-- экземпляры     102—103

- Outlook 98        125-127

- приложение Contacts  128-130

- приложение Messages 131—135

- просмотр контактов    136—140

- Word     68, 106

- печать документов      108—109

- проверка правописания         114—118

- семейство Documents  107-109

- сохранение документов         109—110

- текстовые объекты      110

Активные серверные страницы          496-499

Аргументы

- API-функций   20-21

- COLOR            356

- FACE    356

- взаимодействие "клиент-сервер" 491-493

- передача по значению            20—21

- передача по ссылке     21—22

Атрибут

- ACTION           367

- Alias      402

- ALIGN, HTML-таблицы        361

- ALIGN, Web-изображения    359

- ALT       359

- Archive  402

- BACKGROUND         353

- BGCOLOR       353

- CELLPADDING         361

- CELLSPAC1NG          361

- CHECKED       369

- CODEBASE     381

- COLS    369

- COLSPAN        362

- Compressed       402

- Directory           402

- HEIGHT, в

Web-изображениях 359

- Hidden  402

- HSPACE           359

- MAXLENGTH 367

- METHOD         367

- MULTIPLE      370

- NAME  367

- Normal  402

- ReadOnly          402

- ROWS   369

- ROWSPAN      362

- SELECTED      370

- SIZE, тэга FONT 355-356

- SRC, Web-изображений         359

- System   402

- TEXT    353

- USEMAP          359

- VALIGN          361

- Volume  402

- VSPACE           359

- WIDTH, HTML-таблицы        361

- WIDTH, в

Web-изображениях 359

- машинописного стиля

typewriter 355 Атрибуты

- элементов ActiveX      191

- в HTML            353



- файлов  28

Б

База данных NWIND    250

Базы данных и их

программирование        250-251

— использование

Visual Data Manager       265-268

- использование элементов Data        

- концепции отношении           263-265

- объект Database           301-302

- объект QueryDef          304-306

- объект TableDef           302-303

- отображение    301-307

— проверка допустимости

данных 270-271 277

работа с наборами

записей 251-253, 278-283

— целостность ссылок 272—273

— элементы связанные с данными     295-299

Базы данных объекта QueryDef           304-306

Базы данных внешние ключи  264

Библиотека

— объектов ADO          336

— типов 152

— динамической компоновки (DLL)

— для API функции     17

— регистрация  162—163

Блокировка типа Read only      338-340

Буфер обмена

- в API функциях           19

— в элементе OLE Container   83

Быстродействие индексов баз данных 265

В

Ввод данных

- в базы данных 272-277

— с помощью Visual Data Manager     268—269

Взаимодействие

- клиент сервер 349-350            490-492

— контакты сервера     493—495

— подключения сервера          495

— строка параметров    492—493

— между процессами   143

- с Internet

— в VBScipt       367-372

— размер           235

- с приложением-сервером       101—102

Вкладка

- Advanced, в свойствах Data Link 311

- Aggregates

- в свойствах Command 1         319

- в свойствах Command2          318

-All          312

- Bands    325

- Color, страниц свойств           217—218

- Columns            322

- Component        160

- Connection        311

- Format   323

- General

- свойств проекта          158—159

- элемента Command 1  312—313

- элемента Data  332

- Provider 310

- RecordSource    332

- Relation, установка свойств

элемента Command2     316—317

- Relation, установка свойств

элемента Command3     318

- System DSN     520

- Text Properties  217-222

Внутреннее объединение         288—289

Время, в активных

серверных страницах 497—498, 500—502

Всплывающие меню,



в элементе OLE Container        82—84

Вставка API функций   19

Встраивание объектов

- в период разработки   75—78

- во время исполнения  84—91

- сценариев в страницы            373

Встроенные объекты 71-72, 503-504

- сохранение       80-81

- чтение 80-81, 80-81

Встроенные элементы  367, 373

Выбор объекта Startup  159

Выделение диапазонов в Excel 120

Выравнивание

- по центру

- в HTML панели           363-365

- в HTML-таблице         361

- в элементе FLEXLabel            184

- Web-изображений.................................. 359

- в

HTML-панелях........................... 363-365

- в

HTML-таблицах.................................. 361

- в элементе

FLEXLabel.................. 184, 191

- элементов управления..................... 230-231

Выражения

- в

Excel..................................................... 118

- в

SQL-операторах.......................... 286-287

- в

Word..................................................... 110

Г

Гиперссылки.............................................. 351

- в приложениях...............................456—458

- тэги для создания.......................... 356-357

- цвет.......................................................... 356

Горизонтальный разделитель в HTML... 355

Горячие клавиши

- использование с ярлыками .................. 437

- свойство AccessKeys .............................. 231

Д

Дескрипторы окон ................................44—45

Дескрипторы меню..................................... 31

Диалоговое окно

- Add Field ........................................266-267

- Add Index........................................266-267

- Add Procedure.................................236-238

- Color Selection........................................ 206

- Commandl Properties.............312-313, 319

- Command2 Properties..................... 316-318

- Command3 Properties..................... 317-318

- Components

- элементов

ActiveX...................... 208-209

- элемента

Internet................................ 440



- Connect Property Pages.......................... 221

- Insert Object........................... 73-74, 84-86

- встраивание объектов.......................... 75

- приложение

OLERTime...................... 89

- связывание объектов........................... 79

- Join Tables............................................... 293

- Object Type................................................ 85

- ODBC Data Source Administrator.....519-520

- ODBC Microsoft Access 97 Setup.....519-520

- Paste Special..................................83-84, 96

- окно

Print............................................... 108

- Project Properties

- вкладка Component............................ 160

- вкладка General..........................158—159

- References................................................ 443

- автоматизация OLE ........................... 103

- библиотеки объектов ADO............... 336

- Run ..................................................428-429

-Settings.............................................487-488

- Table Structure......................................... 266

- свойств элемента управления ActiveX.. 376

Директива «INCLUDE....................499-500

Дисковое пространство, определение

с помощью API-функций......... ..... .....23—27

Документы

- ActiveX............................................. 141, 439

- Cookie.htm ......................................465-466

-HTML..............................................351-352

- составные............................................69-70

Драйверы ODBC................................519-520

Дружественные члены модуля класса..... 147

Дублирование в базах данных.................. 269

3

Заголовки

- в DataReports................................... ..... 327

- в DHTML ......................... .............382-383

- в HTML...................................354, 360-361

- в SQL-запросах...................................... 285

- в страницах DataReports .......................327

- изменения...............................................450



- объекта Document.................................. 462

- страниц................................................... 352

- группы в DataReports....................... ....328

Загрузка элементов ActiveX...................... 381

Загрузка, отображение процесса......453-454

Задание имени проекта............................. 159

Задание типа проекта................................ 158

Задания в Outlook 98................................. 125

Закрытые члены модуля класса............... 147

Заливка фигур........................................62-63

Замена Web-изображения текстом.......... 359

Замкнутые фигуры, заполнение ..........62-63

Записи

- в таблицах...............................................251

- добавление...................................... 272, 274

- навигация        258—259

- поиск 260-262, 278-283

- удаление           272, 276

Запись и чтение cookies            516-519

Запросы, к другим приложениям        47-51

Значение

- adLock 337

- adOpen 337

- для выравнивания HTML-таблиц

- BOTTOM          361

- CENTER           361

- MIDDLE          361

- аргумента w Flags       45

- константы

- FILE_ATTRIBUTE     28

- ForAppending

— в методе OpenAsTextStream            404

— в методе OpenTextFile          394

- ForReading

- в методе OpenAsTextStream   404

- в методе OpenTextFile 394

- ForWriting         404

- REFRESH       448

- LEFT     361

- RIGHT  361

Значок

- использование в методе Popup          435

- окна справки   435

- останова           435

- элемента ActiveX        192-193

И

Идентификатор контекстной справки 159

Изменение размеров окна        474-475

Изображения

- API-функции   56-68

- атрибут BORDER       359

- использование в HTML          358-359

- использование в элементах,

взаимодействующих с Internet            488

- копирование    56-58

Имена     400

- источников данных    332

Импорт данных в Excel            124

Индекс

- базы данных    264-265

- обработка         285, 267-268

- объекта TableDef         302-303



- поля      267

Индикация процесса загрузки 453-454

Инициализация элементов ActiveX 227-229

Интерфейс графических

устройств (CGI) 17, 349-350

Интерфейс разработчика          178

Исполняющий механизм

Windows Scripting Host,

см также объект WScript           391, 426-427

- для выполнения сценариев    427-430

- для написания сценариев       426—427

Использование сценариев        349

Испытание         355

Итоговый отчет для элемента ActiveX 192

К

Категория System Services API            функций 17

Квадраты, рисование    60

Класс

- AXStat 166-167, 424-425

- использование для

обработки ошибок         169—172

-тестирование    167-168

- CTimer  146

- закрытые и дружественные члены 147

- инициирование событий       152-153

- тестирование   147-150

- DisplayClass      420-421

- EventTimerClass           153, 163-164

- String     172-174

Классы в DHTML          382-383

Классы в автоматизации OLE 103

Клиентский сценарий, использующий

серверный сценарий     500-502

Клиенты сервера           493-495

- в автоматизации OLE 101-102

- во взаимодействии

"клиент-сервер" 493-495

Клиенты Web     346

Ключевое слово

- As в SQL-операторах  285

- ByVal    20

- Enum     207

- FILE      500

- FROM   285

- HREF   357

- VIRTUAL        500

- WHERE            285

- WithEvents       153

Ключи

- cookies  517

- баз данных       264—265

- в Реестре          51-53

- поиска записей            280

Кнопка

- Abort     435

- Add Record     274

- Alarm Time       235

- Calculate Expression 124—125

- Cancel

- в приложении Data Entry 274-275

— во всплывающем окне

435

- Check Document          116-117

- Command, в VBScnpt 370-371

- Convert to Binary         174

- Convert to Leaps           174

- Convert to String          174

- Copy Fast          65-67

- Create Data Set 167

- Create DOC File           112

- Delete Record   276

- Display Caption            182

- Display Data     167-168

- Draw Now        62

- Execute Script   417-419



- Execute SQL     300

- Find First           263

- First       259-260

- Get Rates          483

- Ignore    435

- Last       259-260

- Make New Sheet           121

- Message DOC File        113

- Next      259-260

- No         435

- Object Info       86-87

- OK, в приложении Data Entry 274-275

- OK, во всплывающем окне 435

- Open Database

— в приложении

DBStructure 304—305

— в приложении SQLExec      299—300

- Open HTML File          442

- Previous 260

- Read File           397

- Reset     370

- Retry     435

- Send Data         371

- Show Selected Messages          131

- Show Statistics  167-168

- Show URL

— в приложении Browser        442

— в приложении I Explore       444-445

- Start Outlook    129

- Start Timer        233

- Stop Timer       233

- Submit   370-371

- View Contacts  129-130

- Yes        435

Кнопки навигации

- в конструкторе

DataEnvironment       313—314

- в элементе Data           259-260

Команда

- ActiveX Control меню

Insert

подменю Other Component       376

- Add Ins

— мастера ActiveX Control Interface 186

— мастера Property Page           215

— утилиты API Viewer            19

- Copy, в элементе OLE Container 83

- Create Embedded Object         84

- Create Link       84

- Cut, в элементе OLE Container          83

- Delete Link       84

- Edit       82

- Insert Control    327

- Insert Object     83

- Load Database File       19

- Load Text File   19

- New Query       292

- New Table         265-266

- Open, в элементе OLE Container 82

- Paste Special     83-84

- Paste в элементе OLE Container         83

- Play       82

- Start .     428-429

- удаления           83

Командный файл           426—427

Команды конструктора ActiveX

DataEnvironment            314—320

Композитные ключи     263

Компонент

- StrmgClass        530

- DataEnvironment          308

- DataReport        308-309

Компонентное программное

обеспечение       69

Компоненты ActiveX    141

- элемент управления Script     418-420



- использование в активных

серверных страницах    529-531

- построение класса

обработки ошибок         169—172

- регистрация     162—163

- свойство Collection     164-169

Константа

- LEFT, выравнивание HTML таблиц 361

- Null       267

- vbAlign 230

— в методе DoVerb       95

— свойства OLETypeAllowed 79

- vbASync           480-481

- vbBOFAction   256

- vbDataAction    271

- vbDataErr          271

- vbEOFAction    256

- vbErrorObject   169

- vbOLEActivate 94

- vbOLEDisplayContent 92

- vbOLEDisplaylcon       92

- vbOLEEither     92

- vbOLEEmbedded         92

- vbOLELmked   92

- vbOLENone      94

- vbOLESize        93

- vbRSType        257

- TOP выравнивание ячеек       361

Конституэнтные элементы      190

Конструктор DataEnvironment 311—312

- метод MoveNext          313-314

- метод MovePrevious    313—314

Конструктор отчетов

DataReport Designer       326-329

Контакты в приложении Outlook        125-126

Контейнеры для элементов ActiveX   209-214

Контекст устройства для изображений 32

Контекст устройства для рисования 65—68

Контекстное меню для

элемента OLE контейнер         82—84

Контроль одновременного доступа 339

Конфликты имен           142

Концепция отношений

в базах данных   263—265

Координаты в объектах            41-44

Копирование     *

- изображений    56—58

- папок    398-399

- пикселей          63—68

- файлов  398, 403

Критерии в SQL операторах    284—285

Критерии метода Find  260

Курсор типа Dynamic    339

Курсор типа Static         339

Кэш в Internet Explorer  487-488

Л

Линии рисование          58—61

Лицензионная защита компонентов 159

Логические операции в фильтрах e-mail 133

Локальные сети 347

M

Массивы объектов        459-460

Мастер ActiveX Control Interface         186-187

- выбор элементов         188

- генерируемый код      194—200

- завершение      192

- отображение членов   190

- стартовый экран          186

- создание компонент   189

- установка атрибутов   191

Мастер Property Page Wizard    215



- выбор страниц свойств          215

- добавление свойств    216—219

- стартовый экран

.................................... 215

Меню

- Insert, команда

Object.............................. 73

- Project, команда

References ................. 443

- Tools, команда Add Procedure .....236-238

- View, команда

HTML............................ 377

- View, команда

Internet Options............. 487

- динамические

...................................35-39

- в элементах OLE-контейнер............ 82-84

- использование растровых

изображений.......................................31—35

Метод

-Abandon................................................... 513

- AbsolutePosition...................................... 341

-•Activate.................................................... 108

-Add

— рабочей страницы.............................. 119

— семейств..............................................

165

— семейства

Documents......................... 107

- AddCode......................... 414-415, 422-423

- AddFolder................................................ 407

- AddNew...........................................342, 272

- AddObject................................................ 419

- ASyncRead ......................................479-488

-Back......................................................... 476

— элемента

ActiveX................................ 199

— объекта

Ambient................................. 213

- Calculate.................................................. 119

- CancelASyncRead ...........................480-481

- CancelUpdate.......................................... 276

-Cells......................................................... 120

- Clear

— объекта

Document.............................. 467

— объекта

Error...................................... 422

— объекта

Response................................ 505

— семейств..............................................

166

- Close объекта

DBConnection................ 521



- Close объекта

Document........................ 467

- Copy....................................................... 404

- CopyFile.................................................. 398

- CopyFolder.............................................. 399

- CreateEmbed............................................. 94

- CreateLink................................................. 94

- CreateShortcut......................................... 436

- CreateTextFile......................................... 393

- Delete в наборе

записей................ 273, 276

- Delete объекта File.................................404

-DeleteFile.................................................399

- DeleteFolder............................................ 399

-DoVerb.......................................................95

- DownloadRates................................483-485

-Echo..........................„.............................431

- EditCopy.................................................... 99

- Evaluate....................................119, 124-125

- Execute

— объекта

Connection.................... 337, 343

— объекта

DBConnection...............521-522

— элемента

Command.................... 337, 343

- FctchVerbs.................................................98

- FileExists.................................................. 399

-Find

— переменная AllMessages..................... 133

— чувствительность к регистру ...........261

— элемент Data...............................260-262

- FindFirst.................................................. 260

- FindLast................................................... 260

- FindNcxt..........................................260, 133

- FindPrevious............................................ 260

- FolderExists .............................................399

- Forward.................................................... 477

- GetCurrencyName................................... 483

- GetCurrencyValue ...................................483



- GetData..................................................... 99

- GetDefaultFolder..................................... 125

- GetFile.............................................400, 406

- GetFileName........................................... 400

- GetFolder................................................. 400

- GetFormat, для

OLE................................99

- GetObject................................................. 431

- GetSpellingSuggestions............11-115, 118

-Go............................................................477

- GoBack элемента

WebBrowser

и объекта Internet Explorer.................... 447

- GoForward в приложении I Explore...... 445

- GoForward элемента

WebBrowser

и объекта Internet Explorer.................... 447

- GoHome.................................................. 447

- GoSearch................................................. 447

-HitTest....,...........................................41-44

— функция

GetCursorPos()................41-44

-   InsertAfter................................................ 110

-   InsertBefore............................................. 110

-   InsertObjDIg........................................89, 95

-   Integer2Binary......................... 172, 174, 530

-   Item......................................................... 166

- семейства

Documents......................... 107

- LoadPicture .............................................488

-Lock.........................................................513

- LowerCaps............................... 172-175, 530

- MapPath.................................................. 513

- Move........................................................ 404

- MoveFile.................................................. 399

- MoveFirst

- конструктора

DataEnvironment...313-314

- набора записей................................... 523

- элемента

Data..................................... 258

- MoveFolder............................................. 399



- MoveLast

- конструктора

DataEnvironment... 313—314

- набора записей................................... 523

- элемента

Data..................................... 258

- MoveNext, набора записей ................... 523

- MovePrevious набора записей............... 523

- MovePrevious элемента

Data................. 258

- Navigate................................................... 447

- аргумент Flags ....................................447

- Number2String................ 172, 174, 530-531

- Open

- в приложении

DBConnection........... 521

- набора записей................................... 337

- объекта

Document.............................. 467

- семейства

Documents......................... 107

- OpenAsTextStream.......................... 404-405

- OpenDatabase()....................................... 250

- OpenTextFile................................... 393-394

- PaintPicture............................................. 480

- PasteSpecialDIg .........................................95

- Popup...............................................434-436

- Printout.................................................... 108

- PropertyChanged..................................... 201

-Quit.......................................................... 431

- Raise ........................................ 165, 169-170

- RaiseEvent...............................204, 238, 241

- Range....................................................... 110

- Read......................................................... 394

- ReadAll.................................................... 394

- ReadFromFile......................................80-81

- ReadLine объекта

InStream................... 398

- ReadLine объекта

TextStream................ 395

- ReadProperty ...................................202-204

- Redirect.................................................... 505

- Refresh элемента

Data........................... 273

- Refresh элемента

WebBrowser и

объекта Internet Explorer....................... 448



- Refresh2...................................................448

- Remove,

семейств................................... 165

- семейства

Documents......................... 107

- Run ..................................................414-415

- Save в

Word............................................. 109

- Save переменной

WshShortcut.............. 438

- SaveAs..................................................... 109

- SaveToFile ...........................................80-81

- Seek в наборах записей......................... 280

- Seek в приложении

ManyTbls............... 283

- Select

объекта
Active Document............. Ill

- Select ячеек

Excel................................... 120

- Show, класса Display Class...................... 420

-Size...........................................................235

-Skip.......................................................... 395

- SkipLine................................................... 395

- SpellingErrors...................................114, 117

- StartTimer................................ 233, 237-238

- Stop.......................................................... 448

- StopTimcr........................................ 233, 238

-Union....................................................... 121

- Unlock..................................................... 513

- Update .............................................273, 276

-Write

- объекта

Document..............460—461, 467

- объекта

Response........................504-505

- объекта

TextStream............................. 395

- WriteBlankLines ......................................395

- WriteLine объекта

TextStream............... 395

- WriteLine объекта

OutStream................ 398

-WriteLn.................................................... 467

Методы

- модуля класса......................................... 146

- объекта

Document,................................. 467

- объекта File.....................................404-405



- объекта History           476-477

- объекта InternetExplorer          447-449

- объекта TextStream      395-396

- объекта Wscnpt            431

- объектов сценария      460—462

- элемента Alarm 233, 236—239

- элемента Data  258-259

- элемента OLE Container         94—96

- элемента WebBrowser 447—449

Модель сценариев

- объект History 476—477

- объект Links   478-479

- объект Location            478

- объект Navigator          477-478

- объекты            458

— методы           460—462

— свойства        458-460

Модуль класса   141—143

- закрытые и дружественные члены 132

- инициирование           152—158

- класс CTimer    145-150

- концепция модулей    143—145

- обработка ошибок       169—172

- свойства           150-151

- свойство Instancing     161

Мультимедиа, API-функции    18

Н

Набор данных типа DynaSet    252

Набор записей (см также базы данных

и их программирование) 252—253, 278—283

- типа ForwordOnly       253

- типа Table         252-253

- в ADO 307, 336-338

- манипулирование       341—343

- применение     522—523

- редактирование           342—343

- создание           522-523

- типы блокировки        338-340

О

Область видимости HTML-тэгов 352

Обработчик ошибок

- FncError            417

- в модуле класса           169—172

- в приложении Graph   417

- в свойстве Let  150-151

- в элементе Script         421—422

Обработчик события     213

- Form_MouseDown()     475

- Form_MouseMove()     475

- Form_MouseUp()          475

- Form_Resize()   474-475

- в сценариях    373

- UserControl_AmbientChanged()          213

- wmdow_onLoad           378

Объединения в SQL      287-289

Объект

- ActiveDocument           107,110

- Advertisement Rotator 504

- Ambient            212-214

- Application

— в активных серверных страницах 503, 513-514

— в приложении Word 106

- Appointmentltem          126

- ASyncProperty  480-481

- Browser 159, 163-164

- Browser Capabilities     504

- Command

— использование в ADO 307, 335, 337



— использование в RecordSets            522—523

- Connection

— в конструкторе ActiveX

DataEnvironment            311

— использование в ADO 307-309, 335-337

— использование для баз данных       521—522

- Contactltem       127

- Content Linking            503

- Data Access      251

- Database 503, 520, 301-302

— в источниках данных ODBC          519-520

— в странице ALLPRODS ASP          523-527

— наборы записей        522—523

— открытие       521-522

- DBConnection 521-522

- Document 458-460, 462

— в приложении HTMLEditor            472-477

— методы           467

— на странице Calendar htm    470—472

— на странице Cookie  463—466

- на странице Navigate htm 468-470

- свойства           462—467

- цвет фон           459 462

- Error      421-422

- Extender            209-212

- Field      303

- размеры            303

- Fields     278

- File        401

- методы  404-405

- свойства           401-403

- функция

CreateObJect() 401

- File Access        503

- FileSystemObJect         392-393

- доступ к файлам и папкам 398—400

- метод CreateTextFile    393

- метод OpenTextFile     393-394

- объект TextStream       398

- приложение FileMover            405-406

- функция

CreateObJect()          392

- Folder   407-408

- Frames   459-460

- History  476-477

- InStream            398

- IntemetExplorer            443-445

- методы  447—449

- приложение Internet Explorer 443-445

- свойства          446—447

- события           449

- Links     478-479

- Mailltem            127, 133

- Navigator          477-478

- Outstream          398

- Paragraph          110-110

- PropertyBag      203

- QueryDef         304-306

- Range в Excel   119-120

- Range в Word 106 110-110

- Request 503, 506-513

- Response           498

- Server функция

CreateObJect() 503, 512-513, 522, 529

- Session 503, 513-514

- Shell      431

- метод CreateShortcut   436

- метод Popup     434-436

- семейство Environment           432—433

- TableDef           302-303



- TextStream

- в приложении MakeFile          396-398

- методы  395—396

- объекта File      404-405

- объекта

FileSystemObJect       393

- свойства           395-396

- URLShortcut    436

- UserControl 177, 186, 190, 192

- рисование        205-206

- свойства           229

- DefaultCancel   212

- события            204-205

- создание           222—223

- Window object  458-460

-Word      110

- Wscnpt

- аргументы        428-430

- методы  431

- свойства           430-431

- функция CreateObJectO          431

- WshNetwork     438, 438

- WshShortcut     436-438

- координаты      41-44

- предоставляемый OLE           70, 100

- ярлыки  436-438

Объектные переменные

- в автоматизации OLE 101—105

- в модуле класса           151—152

- позднее связывание    104

- раннее связывание      104

Объявление переменных

в автоматизации OLE   104—105

Объявление API-функций 18,21-23

Окно

- Add Custom Members  189

- Add Properties  216-219

- Create Custom Interface Members 189

- Create New Data Source          331,519

- Data Link Properties     311-312

- Finished 192

- Query Builder   293

- Registry Editor  50-52

- Selecting Interface Members    188

- Selecting the Property Pages     215

- Set Attributes........................................... 191

- Set Mapping............................................ 190

- позиция поверх

других.....................44—47

- приложения

ENWARS.VBS..................432

- размеры...........................................474-475

— изменяемые

................................474—475

- сообщения......................................434-436

Окружность, построение ......................58—61

Оперативное редактирование OLE....72, 81-82

Оператор                   '

-#datc#..................................................... 287

- BETWEEN.............................................. 286

- Declare....................................................... 18

- End Enum............................................... 207



- IN.......................................................... 286

- LIKE в SQL-опсраторе ......................... 286

- LIKE метода

Find.................................. 261

- ORDER BY............................................. 287

-Set............................................................ 152

- SELECT в

SQL....................................... 285

Операция "псретянуть-и-опустить"....... 72-73, 96-102

Операции отношения в методе Find....... 261

Операции отношения в методе Seek....... 280

Описание

- проекта.................................................... 159

- ошибок.................................................... 421

- ярлыка..................................................... 437

Оптимистический

режим блокировки ............................339—340

Опция

- AutoActivate.............................................. 94

- AutoIncrField.......................................... 267

- Available Fields........................................ 268

- Binary Compatibility............................... 160

- Bottom Alignment элемента FLEXLabel... 184

- Break on Unhandled Errors ....171-172, 426

- Break в модуле класса................... 170-171

- DefaultValue............................................ 267

- Every Visit............................................... 488

- File Data

Source...................................... 331

- FixedField................................................ 267

- GlobalMultiUse....................................... 161

- GlobalSingleUse...................................... 161

- IgnoreNulls.............................................. 268

- Indexed Fields......................................... 268

-Link......................................................75,79

- Multiuse................................................... 161

- Name, индексов..................................... 268

- Name, полей........................................... 267

- No Compatibility..................................... 160



- OrdinalPosition метода AddField........... 267

- Primary..................................................... 268

- Private свойства

Instancing.................... 161

- Project Compatibility............................... 160

- PublicNotCreatable.......................... 161-162

- Remote Server......................................... 160

- Require License Key................................ 159

- Required.................................................. 267

- System Data Source................................. 331

- Top alignment.......................................... 184

- Type......................................................... 267

- Unattended Execution............................. 160

- Unique..................................................... 268

- Upgrade элементов

ActiveX................... 159

- Use ODBC Data Source Name ......331-332

- User Data Source....................................331

- ValidationRule......................................... 267

- ValidationText.......................................... 267

-VariableField............................................ 267

- Version Compatibility.............................. 160

- View Report

Summary............................. 192

Открытие текстовых файлов............393-394

Открытие файлов в HTMLEditor............. 475

Отношение Left Outer Joins...................... 288

Отношение Right Outer Joins.................... 288

Отображение баз данных.......................... 301

- объекта Database ............................301-302

- объекта

TableDef............................302-303

Очередь печати в Word..................... 108-109

Очистка объекта Document......................467

П

Память при рисовании.........................65—68

Папка

- Calendar................................................... 127

- Class Modules.......................................... 145

-Contacts.................. 127-128, 131, 136-140

-   InBox............................................... 127, 131



-   OutBox............................................. 127, 131

-   Start menu............................................... 433

-   извлечение.............................................. 400

- использование в Outlook 98 ......... 125-126

- константы olFolder................................ 125

- копирование................................... 398—399

- объект FileSystemObject................. 398-400

- перемещение.......................................... 399

- просмотр.........................................409-411

- Рабочий

стол.......................................... 433

- существование........................................ 399

- удаление.................................................. 398

Первичные ключи баз данных......... 264-265

- опции...................................................... 268

Передача аргументов, по значению ....20-21

Переменная

- FSys.........................................392-393, 401

-hWnd......................................................... 45

- Maximized и Minimized......................... 438

- Zoom......................................................... 93

Переменная среды

-COMSPEC.............................................. 433

- HOMEDRIVE......................................... 433

- НОМЕРАТН........................................... 433

- NUMBER_OF_PROCESSES................ 433

-OS............................................................ 433

-PATH....................................................... 433

- РАТНЕХТ............................................... 433

- PROCESS................................................ 433

- PROMPT................................................. 433

- SYSTEMDRIVE..................................... 433

- SYSTEMROOT....................................... 433

-TEMP...................................................... 433

-TMP......................................................... 433

- VOLATILE.............................................. 433



-WINDIR.................................................. 433

-PROCESSOR.......................................... 433

Перемещение

- по записям с использованием

элемента Data................................. 258-259

- папок....................................................... 399

- файлов.................. .................................. 404

Период выполнения

- изменение меню................................35-39

- связывание и встраивание объектов.... 84-91

Период разработки

- встраивание объектов........................75-78

- оперативное редактирование OLE....81-83

- связывание объектов.........................79-80

- сохранение встроенных объектов....80-81

- считывание встроенных объектов ...80-81

Пессимистическая блокировка ........339-340

Печать Word-документа....................108-109

Пиксели в графических функциях............ 58

Пиксели функции рисования..............63-68

Пиктограмма восклицательного знака....435

Плавающие панели ...........................363—365

Подключение к Web-серверу ...................496

Подпрограмма

-Hide...................................................... 275

- ShowButtonsQ .........................................276

- StartCountingO

- в приложении CTimer....................... 144

- в приложении TimerMod ..........144—145

- StopCountingO

- в приложении CTimer....................... 144

- в приложении TimerMod .................. 144

- UserControl_Click()........................ 196, 204

- LJserControl_DblClick().......................... 196

- UserControl_KeyDown()........................ 196

- UserControl_KeyPress().......................... 196

-

UserControl_MouseMove()..................... 197

- UserControl_MouseUp()....................... 197

- UserControl_OLEGiveFeedback().......... 197

- UserControl_OLESetData().................... 197

- UserControl_ReadPropeities()................ 198

- UserControl_Resize().............................. 198

- UserControl_WriteProperties()........ 198-199



- UserControlKeyUp()............................... 196

- UserControlOLEStartDrag().................... 197

- UserControlUnitProperties()........... 198, 202

- TMR_Hour()........................................... 157

- TMR_Minute()......................................„ 157

- txtCaption_Change() .......................218-219

Подразделы реестра...............................51-53

Подсветка гиперссылок ....................356-357

Поиск записей 260-262, 278-283

Поиск сообщений e-mail           133

Пользовательский интерфейс

элемента Alarm  232-233

Поля        251

- фиксированной длины           267

- в SQL-операторах       285

- в объекте TableDef      303

- добавление       266—267

- доступ   278-283

Право доступа к базам данных 311

- коллективный доступ 312

Префикс db, для свойства Options 256-257

Приложение контейнер            71

Приложение

- AD01    343

- AD02    343

- ADODC           330-335

- AllContacts       136-140

-API Viewer        18-20

- APIDraw           60-62

- AutoMssg          136

- Browser 440-443

- CLDesign          241-242

- Contacts            128-130

- CopyPix            63-68

- CTextBox         242-243

- Data Entry 274-277, 296-297

- Datal      254-255

- Data2     258-259

- Database Structure        301-302

- DataRep           314-320

- DBList  296-297

- DBStructure      304-306

- DemoPage         456-458

- Denvl     309-314

- Drives   24-27

- EventTimer        153-158

- EventTimer, элемент

Timer 156—158

- ExcelVBA         121-123

- Fileinfo  27-30

- FileMover          405-406

- FmdDemo         262-263

- FLabel   179

- Graph    416-417

- HTMLEditor   472-474

- загрузка и отображение

файлов    475-476

- изменение размеров окна       474-475

- Internet Explorer           443-445

- lExplore, метод

GoBack           445

- LVWDemo       42-43

- MakeFile           396-398

- ManyTbIs          280-283

- MenuBMP         31-35

- MenuMod         35-39

- Messages           131-135

- MouseMov        39-41



- функция

GetCursorPos()         39

- Mouse Pos         21-23

- функция

GetCursorPos()         21-22

- OLEDDAUTO            97-101

- OLERTime        84-86

- диалоговое окно

Insert Object 91-92

- кнопка Object Info      86-87

- форма frmOLE 92-93

- форма frmType 91

- Paint     74-75

- Personal Web Server 464, 493-495

- Query    47-51

- функция

GetCursorPos()         48-49

- Rates, элементы для

взаимодействия с Internet         481-488

- Registry 52-56

- Script Editor      417-419

-SpellDoc 115-118

- функция Get0bject()    116

- SQLExec           299-300

- SQLTbIs           294-295

- StatCIss 423-426

- SuperBrowser

- индикация прогресса  453-454

- создание           451-454

- элемент TabStnp          451-454

- TimerMod         143-145

- элемент Timer  143—145

- WinTop            45-47

- WordPad, использование OLE 74-75

-WordVBA         111-113

- WSCRIPT EXE            428-430

Приложения

- активных серверных страниц           527-529

- использование гиперссылок в           456—458

- передача запросов       47—51

- применение элемента Script  423-426

Провайдер OLE DB      310

Проверка допустимости данных

в базах данных 270—271, 277

Проверка правописания           114—118

Проект

- HTMLEditor   472-477

- Rates     481

- типы

- ActiveX DLL    158

-ActiveXEXE      158

- Data       308-309

- Standard EXE   158

-для ADO            308-310

- имена    159

Промежутки между

Web изображениями     359

Протокол ODBC 331    519-520

- TCP/IP 347-348

Протоколы        347—350

- Web       347-350

- без сохранения предыстории 518

Процедура          220

- DrawCaption()

- в приложении FLabel 182

- в элементе UserContiol           205-206

- GetElapsedTime()         146

- Head3 onMouseOut()   390

- Head3_onMouseOver()            390

- InitProperties()  202

- MakeSheet()      121-123

- OLEDrag()        198

- Property Get 146, 150, 201-202

- Property Let 146, 150-151, 201-202, 224

- PropertyPage_ApplyChanges() 218-221



- PropertyPage_SelectionChanged()       218-220

- ReadRates()      484-485

- ResetTimer()

- в приложении CTimer 146

- в приложении TimerMod     144—145

- ScanSubFolders()          139

- Showlmage()     488

- извлечение имени       423

- в модуле класса           142

Путь к cookie      517

Путь к файлу      28

- к включаемому            500

Р

Раздел

- Detail в отчете  329

- HKEY CLASSES_ROOT       51

- HKEY CURRENT_USER      51

- HKEY LOCAL_MACHINE 51

- Start Mode вкладки Tab          160

Разделители в HTML    355

Разделы элемента MSHFlexGnd 325

Разработка элементов

управления ActiveX 177-178, 185-192

Растровая (BMP) графика

- использование в OLE 73-74

- использование в меню           31-35

- копирование    56-58

Растровая операция

- BLACKNESS  57

- DSTINVERT    57

- MERGECOPY 57

- MERGEPAINT            57

- NOTSRCCOPY           57

- NOTSRCERASE         57

- PATCOPY        57

- PATINVERT    57

- PATPAINT       57

- SRCAND         57

- SRCCOPY        57

- SRCERASE      57

- SRCINVERT    57

- SRCPAINT       57

- WHITENESS   57

Растровые операции

в функциях BitBlt() и StretchBlt() 57

Расширение

- ASP       496

- htm        352

Регистрация

— перья......................................................... 59

— компонентов ActiveX..................... 162—163

— элементов ActiveX.......................... 377-378

Редактирование

— наборов записей ....................................343

— страниц свойств............................. 219-222

Редактор

— HTML-страниц...................................... 348

— приложение Script Editor.............. 417—419

Реестр

— подраздел Window Height....................... 52

— подраздел Window Width ........................52

— функции для работы........................51—56

Режимы просмотра в конструкторе

DataEnvironment..................... ............... 316

Рекурсивное программирование,

сканирование папок....... 136-140, 409—411

Рисование

— заливка фигур . . . .............. .  ........62—63



— используемые функции ...................57-62

— кисти.... .... ........... .. ................... 59

—линии..............   ....................   ......58—61

— на объекте UserControl ....................... 205

— окружности...........................   ........58—61

— повышение скорости........................65—68

— приложение APIDraw........................60-62

— функции отображения пикселей.....63—68

С

Свободное дисковое пространство,

определение, API-функции.................23—27

Свойства

— элементов управления ActiveX.....223-225

- сохранение и извлечение.......... 202-204

- установка и чтение.................... 201-202

- время жизни элемента.............. 225—226

- инициализация........................... 227-229

— модуля класса................................. 150—151

— объекта

- ASyneProperty .............................480-481

- Document ....................................462-467

- File.............................................401-403

- Folder.........................................407-408

- IntemetExplorer........................... 446-447

-Link...................................................... 479

- Location............................................... 478

- Navigator.............................................. 477

- TextStream ...................................395-396

- Wscript .........................................430-431

- сценария......................................458—460

- описание................................................. 191

- отображение.......................................... 190

- перечислимые

................................206-208

- приложения Outlook 98............. 127-128

- элемента

- Alarm........................... 232-233, 236-239

- FLEXLabel......................   .............. 184

- UserObject..........................  ...............229

- WebBrowser............................... 446-447

Свойство

- AccessKeys................................   . .   231

- Alarm Time. ..........    . ...... 233-237



- Align.................    . . ... ....... ..    230-231

- Alignable........................ ............ .230

- aLinkColor.... ........................... ..  462

- AllowZeroLength,

в определении TableDef........... .... ....304

- AllowZeroLength, метода AddField . .. 267

-Anchor.............. ........................... 466

- AppCodeName .... ...... ...... . .   .... 477

- Appearance, элементов

ActiveX.... 193, 195

- Appearance, элемента

CTextBox.........246

- Application............................... .. 430, 446

- AppName................................................. 477

- AppVersion ..............................................477

-Arguments.............................................. 436

-ASyncType.......................................480-481

- AtEndOfLine...................................... ....395

- AtEndOfStream...........................395, 398

- Attributes, объекта

File..................401-403

- Attributes, папки.....................................407

- Average................................................... 166

- BackgroundPrintingStatus........................ 110

- Backstyle.................................................. 195

- bgColor...........................................459, 462

- BOF.................................................256, 260

- BOFAction..............................................256

- Bookmark............................................258

- BorderStyle, элемента

ActiveX.......193, 195

- BoundColumn.............................. ..........298

- Buffer....................................................... 506

- BusinessAddress....................................... 127

- Busy......................................................... 446

-Cancel...................................................... 212

- CanGetEocus........................................... 229

- Caption и надписи

- в

ActiveX-элементах................... 198, 201

- в элементах

DataReport..................... 328



- в элементах

FLEXLabel..................... 184

- Class...............................................77, 87, 92

- CLASSIC................................................ 376

- Column, объекта

Error........................... 421

- Column, объекта

TextStream................. 396

- Container................................................. 446

- ContentType............................................ 505

- ControlContainer..................................... 230

-Cookie..............................................462-466

- Cookies.................................................... 506

- Count

- объекта Fields ..................................... 278

- объекта

QueryDef............................... 304

- объекта

RecordSet.............................. 340

- объекта TableDef ............................... 301

- свойства

Procedures............................ 422

- семейств..............................................

164

- элемента

Rates.................................... 483

- CountDown.................... 232-233, 236-237

- Counts семейства

Documents................ 107

- CursorLocation........................................ 338

- CursorTypes..................................... 338-340

- DatabaseName................................. 250, 254

- DataBindingBehavior............................... 162

- DataField......................................... 254, 256

- DataSource элемента

Data............. 254—256

- DataSource, элемента

MSHFlexGrid.... 324

- DataSource Behavior................................ 162

- DateCreated, папки................................ 407

- DateCreated, файла................................ 403

- DateLastAccessed, папки .......................407

- DateLastAccessed, файла........................ 403

- DateLastModified, папки....................... 407

- DateLastModified, файла....................... 403

- Default..................................................... 212

- DefaultCancel.......................................... 212



- Description, объекта

Error..................... 422

- Description, объекта

WshShortcut......... 436

- DisplayType.........................................92, 98

- Document................................................ 446

- Domain.................................................... 517

- Drive, папки

...........................................407

- Drive, файла............................................403

- EditAtDesignTime................................... 242

- Effect элементов

ActiveX....................... 198

- Effect элемента

FLEXLabel........... 184, 193

- EmailAddress........................................... 127

- Enabled элемента

ActiveX...................... 196

- EnterFocusColor...................... 243, 245, 248

- EntrylD.................................................... 128

- EOF .........................................256, 259-260

- EOFAction.......................................256, 272

- fgColor.............................................459, 462

- Fields................................................ 301, 303

- FirstName................................................ 127

- Font и шрифты

- для элементов

ActiveX....................... 195

- для

HTML...................................354-356

- для объекта

Ambient.......................... 213

- для элемента

DataReport................... 328

- для ячеек

Excel................................... 120

- размер..........................................355-356

- FullName

- для

Wscript.......................................... 430

- для

WshShortcut.................................. 436

- для контактов..................................... 136

-hash..........................................................479

- HasKeys................................................... 517

- HasRetum Value....................................... 423

- hDC......................................................... 196

- Height и высота

- Web-изображения ..............................359



- объекта

Extender................................. 210

- элемента WebBrowser и объекта Internet Explorer...................................... 446

- HomeAddress........................................... 127

- host, объекта

Link..................................479

- host, объекта

Location............................ 478

- hostname, объекта

Link.......................... 479

- hostname, объекта

Location................... 478

- Hotkey.....................................................437

-Hour.........................................................l53

- hRef, объекта Link       479

- hRef, объекта

Location 459, 478

- hWnd элементов

ActiveX       196

- IconLocation     438

- Index, объекта

Extender          210

- Index, объекта

UserControl     223

- Indexes  303

- InvisibleAtRuntime       231

- IsRootFolder     408

- Item, свойства

Procedures       422

- lastModified      467

- LastName          127

- LastUpdate       483

- LeaveFocusColor 244, 245

- Left, в элементе

UserObJect 223

- Left, для элемента

WebBrowser и

объекта Internet Explorer           447

- Length   466

- Line, объект Error        421

- Line, объект

TextStream          396

- Link       466

- linkColor           462

- ListField            296

- LocationName   447

- LocationURL    447

- LockType 338-340

- Mandatory 244—247

- MandatoryColor 244, 245

- Мах, в классе AXStat  166

- Min, класса AXStat     166

- Mouse Pointer   197

- MTSTransactionMode  162

- Name и имена

— элемента ActiveX     186

— индексов        268

— конфликты    142

— объекта Extender       210

— объекта File   403

— объекта Folder           407

— объекта QueryDef     304

— объекта Window       459

— объекта Wscnpt         430

— полей 267

— проектов        159

— свойства Procedures  423

— страницы свойств    215

- файлов  400

- NewWindow     450

- NoMatch           261, 263

- Number 422

- OLEDragMode 96-97

- OLEDragOver 197-198

- OLEDropAllowed        92-93

- OLEDropMode 197, 100



- OLEObjects      98

- OLETypeAllowed 78-79, 92

- Options 257-258

- OrdinalPosition объекта TableDef 304

- Parent, объекта

Extender         210

- ParentFolder, папки     407

- ParentFolder, файла     403

- Path, cookies     517

- Path, объекта Wscnpt   430

- pathname, объекта

Link           479

- pathname, объекта

Location 478

- Picture, ActiveX-элемента       198

- port, объекта Link        479

- port, объекта

Location 478

- Procedures         419

- Property Bag   225, 227

- PropertyName 480-481,485

- protocol, объекта

Link 479

- protocol, объекта

Location       478

-Range     110

- ReadOnly          256

- RecordCount   278, 340

- RecordSet         278, 290

- RecordsetType  256

- RecordSource 254-255, 290-291, 300

- Referrer 467

- RowSource        296

- Saved    109

- ScnptFullName 430

- ScriptName       431

- search    479

- SenderName      134

- SentOn  134

- ShortName, объекта

File          404

- ShortName, объекта

Folder     408

- ShortPath          408

- ShowGrabHandles        213

- ShowHatching  213

- Size

— объекта File  404

— объекта Folder           408

— поля таблицы            304

- SizeMode          75-76,  79 92

— значение AutoSize    77, 94

— значение Clip            77, 92

- Sort, набора записей   341

• Source   422

• SourceDoc        77, 80, 87, 93

• Sourceltem       77        87, 93

• SQL      304

• Stretch, в свойстве

SizeMode 77, 93

Tabindex  223

TabStop   223

Tag, объекта Extender    210

Tag объекта UserObject 223

Target      479

TargetPath           438

Text, объекта Error         422

Text ячеек Excel 120

TextAlignment

- элементов ActiveX 198-199, 201-202

- элемента FLEXLabel   184, 191, 193

Title, объекта Document            462

Title, приложения

Outlook 98   127

ToolboxBitmap    192,231

ToolTips   223

ToolTipText         223

Top, элемента

WebBrowser и

объекта Internet Explorer           447

• Type

— объекта Field 304

— объекта File   404

— элемента WebBrowser и объекта



Internet Explorer 447

• UserAgent         477

UserMode            212-213

Value и значения объекта Field            304

Value и значения, свойства

forASyneProperty           480-481, 485

Version    430

- Visible, элемента

Data 278

- vLinkColor        462

- Width и ширина

— HTML-таблицы        361

— Web-изображения     359

— объекта Extender       210

— пера    59

— элемента WebBrowser и объекта

Internet Explorer 446

- WindowStyle    438

- WorkingDirectory         438

Связанные объекты       72

Связанные с данными  295-299

Семейства элементов ActiveX 164—169

Семейство

- AllContacts       132

- Characters         106

- ClientCertificates          513

- Cookies 513

- Documents        107-109

— шаблоны        107

- Environment      432—433

- Field      341

- Fields     303

- Files       400

- Folders  407-408

- Form      510

- ObjectVerbs      98

- OLEObjects      98

- Paragraphs         106

- ProofReadingError        114

- QueryDefs         304

- QueryStrmg       507-511

- SelectedMessages         134-135

- ServerVanables 511-512

- SpecialFolders   432-434

- SpellmgSuggestions      114

- Subfolders         408

- TableDefs          302

- Words    106

-Worksheets         119

Сервер активный          143

Сервер пассивный        143

Серверная переменная

- CONTENT_LENGTH........................... 511

- CONTENT_TYPE.................................. 511

- QUERY_STRING.................................. 511

- REMOTE_ADDR................................... 511

- REMOTE_HOST.................................... 511

- REQUEST_METHOD........................... 511

- SCRIPTJMAME..................................... 511

- SERVER.................................................. 511

Серверы

- активные серверные страницы................................. 503, 512-513

- в

Web....................................................... 346

- модуль класса ........................................ 142

- серверные приложения.....................70—71



Сжатие JPEG-изображений..................... 357

Символы в HTML............................. 355-356

Система управления базами

данных Jet engine

- контроль типов...................................... 271

- поддержка ключей.................. ............. 264

Системные таблицы................................ 306

-MSys........................................................306

- USys......................................................... 306

- баз данных.............................................. 306

Системы управления базами данных...... 250

Сканирование папок.........................409-411

- папки Contacts............................. 136-140

Смещение чисел

- база данных BIBLI0..............250, 259, 265

- ввод данных ...................................274—277

- поиск записей................................ 280-283

- структура.........................................268-269

Событие .....................................................225

- Application_OnEnd................................. 515

- Application_OnStart................................ 515

- ASyncReadComplete............... 480, 484, 488

- BeforeNavigate2

приложения DemoPage .................457—458

- BeforeNavigate2 элемента WebBrowser

и объекта Internet Explorer.................... 449

- DIoadError............................................... 483

- DownloadBegin в приложении

SuperBrowser........................................... 453

- DownloadBegin для элемента

WebBrowser и объекта Internet Explorer...................................... 449

- DownloadComplete, в приложении

SuperBrowser........................................... 453

- DownloadComplete, для элемента

WebBrowser и объекта Internet Explorer..............................449-450

- DragDrop................................................... 44

-End...................................................515-516

- EnterFocus............................................... 229

- Error в базах данных..... 271-272, 276-277



- ExitFocus................................................229

- FrameBeforeNavigate ............... ..............451

- FrameNavigateComplete .........................451

- FrameNewWindow.................................. 451

- Initialize ...........................................225-226

- InitProperties .................. 225-226, 227-228

- Load формы

VBForm............................. 455

- LostFocus.........................................247-248

- Minute ..................................................... 153

- MouseMove............................................... 39

- NavigateComplete.................................... 450

- OLEDragDrop........................................... 98

- ProgressChange........................450, 453-454

- QryList_Click........................................... 306

- RatesRead................................................ 483

- ReadProperties.................................226-227

- Reposition............ ...........................281, 283

- Session_OnEnd........................................ 515

- Session_OnStart....................................... 516

- SetFocus................................................... 232

-Start..................................................515-516

- TimeOut................................................... 238

-Timer................................................239-240

- TitleChange.............................................. 450

- Validate...................................270-271, 277

- WriteProperties ................................226-227

- WriteProperty...................................202-204

- мыши, обнаружение..........................39—41

- элемента

ActiveX...........................204-205,

227-228, 238, 241

- объекта Internet Explorer....................... 449

- элемента

Alarm...............................238-241

- элемента

WebBrowser............................. 449

Создание отчетов.............. 308-309, 326-329

Сообщения e-mail



- в автоматизации Outlook 98 ......... 125-125

- приложение Messages.................. 131-135

- фильтрация............................ ....... 133-135

Сортировка наборов записей................. 341

Сохранение

- встроенных

объектов.........................80-81

- документов Word.................................. 110

- свойств элементов ActiveX ..........202-204

- файлов HTMLEditor   ... .... ....475

- ярлыков . . .   ........... . . . 438

Спецсимвол, структура. ........ .... 287

Списки

- в DHTML......... . .. ... ....................387-389

- динамические .. . ........ .................387—389

- полей................ ................................ 285

-таблиц............... .................. .........286, 306

- файлов ..... ..............................   ....433-434

Справочная система Microsoft

Developer Network (MSDN)....................... 19

Срок действия cookies.............465, 517-518

Ссылка на изображение ......................... 359

Ссылка, передача с помощью

значений аргументов..........................21—22

Стандартные значения полей .... . .......267

Стартовая форма

- мастера ActiveX Control Interface.     187

- мастера Property Page Wizard .   ... .215

Стиль символов в HTML ............. ... ...... 355

Стиль для DHTML... ....... 382-383, 385-386

Столбцы

- HTML-таблиц............ ..................362-363

- в таблицах.............................................. 251

- ячеек Excel.............................................. 120

Страница

- ALARM.HTM...... . ........................375-379

- ALLPRODS.ASP ............................523-527

- Calendar.htm...........................443, 470-472

- Cookie.............................. ..............463-466

- DATETIME.HTM.................................497

- Demo.htm.. ................. ..... ....................456

-FFRAMES.HTM .... ............................ 365

- FORM.HTM ....... .......... 371-372, 492-493

-GREET.ASP....................................498-499



-LABEL3D.HTM......................................381

- Navigate.htm....................................468-470

-NUMSTR.ASP........................................ 531

- PARAM.ASP ..................................509-510

-PRODCAT.ASP...............................523-527

- SBXDHTML.HTM .........................387-389

- SRVRFORM.HTM .........................507-510

- StandardColor..................................216-217

- StandardFont........................................... 216

- StandardPicture....................................... 216

- STYLES.HTM .................................383-384

- TIMESRVR.ASP .............................500-502

- UINPUT.HTM................................380-381

-VIEWERS.ASP................................528-529

- свойств CaptionProperties..............218—219

- свойств, переименование...................... 216

Страницы Web

- использование элементов ActiveX.... 375—381

- стартовые................................................ 358

- активные................................................. 366

- активные серверные .............................489

- включаемые файлы....................499—500

- использование cookies...............516—519

- используемые объекты..............502—503

- принцип действия......................495—496

- серверный сценарий..................500—502

- создание ......................................496—499

- базовые объекты................................. 504

- взаимодействие клиент-сервер..... 490-495

- встроенные объекты.................. 503—504

- использование элементов ActiveX......................529-531

- объект Database ..........................518-527

- объект Request............................506-513

- объект Response..........................504-507

- объект Server...............................512-513

- объекты Server и Application.............514

Страницы свойств

- использование мастера Property Page Wizard........215-228

- конструирование............................214—219



- редактирование ..............................219—222

Строка параметров ............................492—493

Структура POINTAPI ............................21-22

Структура базы данных

- объект Database           301-302

- объект QueryDef          304-306

- объект TableDef           303

Структуры данных Си  20

Структуры, используемые

в API-функциях 21-23

Суффикс API-функций            18

Существование файлов и папок 399

Сценарий

- ARGS1.VBS    429

- ARGS2.VBS    429

- DTOP.VBS       433

- MakeData          425

- POPUP VBS     435

- Process  425

-SPFOLDER.VBS          434

- SRVRPARAM.ASP     511-512

-WSCRIPT.VBS 431

- YEAR2000.VBS          426-427

T

Таблицы в базах данных          251

- объединение    287-289

- создание           267

Таблицы в HTML, теги 360-364

Текст в Web-изображении        359

Текстовые объекты в Word      110—110

Текстовые файлы объекта

FileSystemObject

- открытие          393-394

- создание           393

Тестирование элементов ActiveX 193

Тестирование HTML-тэгов      355

Тип данных

- Data

- использование в SQL-операторах 286

- в активных серверных

страницах 497, 500-502

- String, строковые типы в Си 20

- Integer, целочисленные типы в Си 20

- OLE_COLOR  206

- Variant, в языке VBScnpt        374

- полей    267

Тип курсора

- в ADO  338-340

- "ForwardOnly"  338

- Keyset   338

Тип поля

- AutoNumber     264-265

- Binary    267

- Memo    267

Типы блокировок объекта Recordset 338—340

Типы дисковых устройств       24

Типы проектов элементов ActiveX 158

Транзакция GET            448, 492

Транзакция POST          448, 492

Тэги в HTML     351-352

- заголовки         354

- изображения    358—359

- панели  363-365

- ссылки  356-357

- форматирование абзацев        – 355

- форматирование символов    355—356

У

Узел InfoSeek     490-491

Установка Help File Name        159

Утилита

- Package and Deployment Wizard 381

- Regedit  50

- REGSVR32      163, 531

- Visual Data Manager    265—266



- ввод данных    268

- установка индексов    265-267

- формирование запросов         292—294

- Web Publishing Wizard            485-486

- WINIPCFG      528

- просмотра API-функций        18—20

Ф

Файл

- DEFAULT.HTM          494

- GLOBAL.ASA 515-516, 527-528

- SYSTEM.DAT 51

-USER.DAT        51

-Winmm.dll         18

- атрибуты          28

- в формате Unicode      393, 405

- включаемый в ASP     499—500

- вывод списка (файлов)           433-434

- извлечение       400

- имена путей     28

- копирование    398 403

- объект FileSystemObject         398-400

- перемещение   399, 404

- размер  28

- сжатие  357

- существование            399

- типа ОСХ         381

- удаление           399—404

Фильтры е-mail  133—135

Флаги меню MF_          31-32

Флаги метода Navigate 448

Фокус элемента свойства        229

- цвет       244

Фоновые изображения 353

Форма

- frmOLE 90-91

- frmType 91

- VBForm           455

- WEBForm         455

Формат метода OpenAsTextStream 404-405

Формат объектов OLE  99

Форматирование абзаца в HTML 355

Формы

- в VBScript       367-372

- взаимодействие клиент сервер 490—491

- вспомогательные        177

Функция

- BitBlt()  16 56-57

- CreateCompatibleBitmap() 32 56 65—66

- CreateCompatibleDC() 32 56 65

- CreateObject() 102-103 105 152

- CreatePen()       59

- CreateSolidBrush()       59

- Date()    427 498

- DeleteDC()        66

- DeleteObject()   67

- DisplayBitmapMenu()   35

- Display TextMenu()      35

- Ellipse()58 61-62

- ExtFloodFill()   62-63

- FiinctionEvall() 416-417

- FunctionEval2()            416-417

- GenerateSQL()  263

- GetClassName()            39, 48

- GetCiirrentDirectory()  25

- GetDiskFreeSpace()      24-25

- GetDriveType() 23-24

- GetFileAttnbutes()        28

- GetFileSize()     28

- GetFullPathName()       28

- GetMenii()         31-32

- GetObject()       102-103

- GetParent()        48

- GetPixelV()       62-63, 67

- GetSubMenu()  31

- GetWindowsDirectory()           25



- GetWindowText()         48

- IntToHex()        414-415

- LineTo()            "58-62

- mciSendStrmg()            18

- ModifyMenu()  31-32, 35

- ReadSmgle()     174

- ReadTenths()     174

- RegCreateKey()            53

- RegSetValueEx()          53

- SelectObject()   60-61

- SetPixelV()        62-63, 67

- SetWindowPos()           44-48

- Shell()    406

- StretchBlt()       57

- Time()    498

- WindowFromPomt()     39, 48-49

X

Хранение MAPI-сообщений 125

Ц

Цвет, пера          59

Целостность ссылок      273—274

Ш

Шаблон SQL-запроса    287

Шлюзовый интерфейс  349—350

Шрифт, размеры в HTML         355-356

Э

Экземпляры, автоматизация OLE...102-103

Электронная почта

- в автоматизации Outlook 98 .........125-125

- приложение Messages.................... 131-135

- фильтрация..................................... 133-135

Элемент

- ActiveX .................................................. 196

- ADO ................................................330-335

- ADODC................................................... 308

-Alarm......................................232, 233-241

- взаимодействие с контейнером....209-214

- загрузка............................................... 381

- использование в Web-страницах........................... 375-381

- методы и свойства ..... 233-234, 236—239

- обновление дисплея ......... .. ...239-241

- перечислимые свойства...........206—208

- пользовательский интерфейс..... 232—233

- регистрация ..... .. ........ .. .... ...... .. 377

- свойства . .......... .. . .   ........ . ...... . .. 183

- события ...........................233, 238-241

- сохранение и извлечение.. .  202—204

- страницы свойств ......... . . ..214—222

- тестирование ....... . . ............. 234—235

- усовершенствование .... .........241—248

-BUTTON . ............   ..............   ..370

- CheckBox в VBScript............ ............. 369

- Command button, атрибут VALUE . ... 370

- CTextBox

- в Web-страницах.... . . ..............380-381



- доработка... ........................242—243

- спецификации. . . . ......  . .. 244-247

- Current Page Number .. .... ... .   . . 328

- Data...  ....... ................  ... .251-253

- методы навигации...... .........258-259

- методы поиска ............... .......260—262

- свойства ...................................254-257

- DataCombo......................................... 308

- DataGrid ........................................321-323

- DataList................................................... 308

- DataReport............................................ 328

-Filter.............. .................................375

- FLEXLabel ....................................178-182

- использование в проектах ... ....208—209

- конструирование........................  183

- основа......................................199-200

- перечислимые свойства............. 206—208

- свойство Font..................................... 184

- события .......................................204-205

- сохранение и извлечение свойств.........................................202-204

- спецификация ................................... 184

- страница свойств........................215—222

- установка и чтение свойств...... 201—202

- Grid, связанный с данными.........298—299

- Label, в DataReports.............................. 328

- Label, в элементе Alarm ....................... 235

- List, связанный с данными...........295-296

- ListView, координаты.....................41-44

- MHSFlexGrid.................................308, 314

- конструирование с DataEnvironment

ActiveX Designer............ ............323-325

- Multiple Selection

- атрибут SIZE ................................ .370

- атрибут VALUE............................ .. 370

- размер.. ..... ......................  .............. .370

- OLE Container....... ........ .74-75,81-82

- во время выполнения..... .... .84—91

- встроенные объекты...... .... . 75—78

- контекстное меню...... ........ ... . 82—84



- методы.................. ........... 94—96

- оперативное редактирование..   81—82

- размер ................ .   .   .......... .87-88

- свойства...     . .. ....        92-93

- связывание объектов . .... .. . . 79-80

- сохранение объектов .......... 80-81

- чтение объектов . ........... .... ..80—81

- Password ........................ .. ..........  367

- RadioButton ......................... ... ... .........369

- Rates .......................... .....................481

- исходный текст...... .... .... ...484-485

- компоненты-члены.. .. ........483-484

- применение ... .. .. ... .. ... ...483—484

- тестирование.......... ....   . . .485-488

- RichTextBox, OLE-операции

"перетянуть-и-опустить" ........... 98—101

- Script...............................................412-413

- ActiveX-компоненты..................418-420

- в приложениях........................ .423-426

- извлечение имен процедур........ . 423

- метод ExecuteStatement.............413-414

- методы AddCode и Run.. ..   .414-415

- обработка ошибок...... .     .421-422

- приложение Graph. ............... 416—417

- приложение Script Editor........ 417-419

- Sequencer         375

- Shape заливка фигур   62—63

- Structured Graphics      375

- TabStnp, страницы свойств    214-215

- Text       367-368

- атрибут SIZE   367

- атрибут VALUE         367

- размер   367

- TextArea           368

- TextBox,

- OLE-события

"перетянуть-и-опустить"          98-100

- доработка         242-243

- связанный с данными 256

- спецификации 244-247

- Timer

- Web страницы 376

- класс CTimer    145-150

- страница ALARM.HTM         375-379

- элемент Alarm  233, 235

- TreeView сканирование

папки Contacts   137-139

- WebBrowser     439-440

- индикация прогресса загрузки 453—454

- использование для

Web-броузеров   451 -454

- методы  447-449

- свойства           446-447

- события            449

- создание           440-443

- управления Multeple Selection 369-370



- управления размер      235

- взаимодействие с Internet 439, 479-481

- в изображениях           488

- связанные с данными 256, 295

- элемент ComboBox     297-298

- элемент Grid    298

- элемент List     295-304

Эллипс, рисование 58 61—62

Эффект 3-D для меток  179-180

Эффект Carved   184

Эффекты выпуклого изображения 184

Я

Язык

- JavaScript          366

- VBScript           125, 366

- ActiveX-элсменты       375-381

- Windows Scripting Host           426-431

- активные серверные страницы 496

- встраивание сценариев          373

- использование форм и

элементов управления  367—372

- объект File        401-404

- объект

FileSystemObject 392-400,405-406

- семейство Files            400

- семейство Folders        407-408

- семейство Subfolders  408

- элемент Script  412—426

- элемент Shell    437

- создания гипертекстов 346, 351-352

- URL      351-352

- атрибуты          353

- гиперссылки    356-357

- заголовки         354

- использование изображений 358—359

- панели  363-365

- структуры        351-352

- таблицы            360-364

- тестирование тэгов     355

- форматирование абзацев        355

- форматирование текста          355—356

- создания динамических

гипертекстов 346, 350-351, 382-383

- использование списков          387-389

- классы  382-383

- стили    382-386

- тэг <DIV>        383-384

- структурированных

запросов 252, 284-285

- использование в ADO            336—337

- объединения    287-289

- применение     290-291

- присоединение запросов к

базам данных     292-294

- структура операторов 284-285

Языки программирования

- процедурные   284-285

- бестиповые      374

- декларативные            284-285

- третье поколение        284

- четвертое поколение  284

Ярлык, создание            436

Продукция соответствует требованиям Министерства здравоохранения Российской Федерации. Гигиеническое заключение 77.ФЦ.8.953.П.197.3.99 от 12.03.1999.

Учебное пособие

Евангелос Петрусос

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

в двух томах Том 2

Ответственный исполнитель В. В. Легейда. Научный редактор Ю. М. Зорин.

Литературные редакторы В. М. Мацуй, Н. В. Мирошник.

Лицензия на издательскую деятельность № 071405

от 28 февраля 1997 г. 000 "Спаррк".

123364, Москва, ул. Свободы, д. 28, корп. 2.

Подписано в печать 20.12.99. Формат 70Х100 1/16.

Усл. печ. л. 35. Печать офсетная.

Тираж 4000 экз. Заказ № 1913.

Отпечатано с диапозитивов в ГПП «Печатный Двор» Министерства РФ по делам печати, телерадиовещания и средств массовых коммуникаций. 197110, Санкт-Петербург, Чкаловский пр., 15.


Пример организации связывания и встраивания


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

1. Запустите редактор WordPad с помощью меню Start (Пуск)/

2. Выберите команду Object (Объект) в меню Insert (Вставка), чтобы вызвать на экран диалоговое окно Insert Object (Вставка объекта), как показано на рис. 14.2.

3. Установите переключатель в положение Create from File (Создать из файла), а затем щелкните на кнопке Browse (Обзор).

4. В диалоговом окне Browse (Обзор) (идентичном диалоговому окну File Open (Открыть)) выберите растровое изображение и щелкните на кнопке ОК. Выбранное изображение будет встроено в документ WordPad.

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

Inseil Object

Рис. 14.2. Диалоговое окно Insert Object (Вставка объекта) позволяет выбрать существующий объект (или создать новый) и встроить его (или связать) с текущим документом

Если установить переключатель в положение Create New (в диалоговом окне Insert Object (Вставка объекта)), то на экране появится прокручивающийся список объектов, доступных системе. Каждое приложение, выполняющее функции приложения-сервера, регистрирует предоставляемые объекты в системе, чтобы приложения-контейнеры могли ими воспользоваться. Когда вы вставляете объект, приложение для работы с ним запускается автоматически при открытии каждого нового документа. Вернемся в диалоговое окно Insert Object (Вставка объекта), установим переключатель в положение Create New (Создать новый) и выберем из списка Object Types объект Bitmap Image (Растровое изображение). По умолчанию предполагается, что растровые изображения создаются в программе Paint. Если в системе не была заменена прикладная программа для создания и обработки растровых изображений, то WordPad установит связь с Paint и выведет на экран ее интерфейс пользователя Меню WordPad будет заменено на меню Paint, и на экране появится панель инструментов Paint (рис. 14.3). Теперь можно создать новое растровое изображение, пользуясь средствами Paint, но этот процесс будет происходить в WordPad. При этом не нужно запускать другое приложение, копи­ровать растровое изображение, а затем вставлять его в ваш документ.


Независимо от того, какое было вставлено растровое изображение — новое или уже существующее — для его редактирования достаточно выполнить двойной щелчок в области изображения. Операционная система обращается к Registry (Реестру), чтобы найти приложение, ассоциированное с растровым изображением. По умол­чанию — это программа Paint, которая поставляется вместе с Windows. Если эта установка не была изменена, то будет запушено приложение Paint и вместо меню и панели инструментов WordPad появится меню Paint (рис 14.3). (Если же эта установка была изменена, то будет запущено иное приложение). Теперь можно отредактировать растровое изображение, а затем возвратиться в основной доку­мент щелкнув за пределами растрового изображения. В нашем случае, приложение Paint является приложением-сервером, которое "знает", как обрабатывать растровые изображения.

Рис. 14.3. Меню и панели инструментов приложения-контейнера (WordPad) заменяются меню и панелями инструментов приложения-сервера (Paint)
Растровое изображение, помещенное в документ WordPad, и растровое изобра­жение, содержащееся на дисковом файле - это два отдельных объекта. Можно изменять этот файл на диске, заменять его другим, можно даже удалить его — на содержимое документа WordPad это не повлияет. В документе WordPad содержится копия растрового изображения.
Поскольку можно редактировать встроенный объект в том окне, в котором он находится, не нужно знать, с помощью какой программы был создан объект, и не нужно работать с этим объектом в отдельном окне. Одно из преимуществ такого подхода — упрощается выполнение операции масштабирования объекта по отно­шению к окружающему тексту.
Если в диалоговом окне Insert Object (Вставка объекта) установить флажок Link (Связать), то объект в документе WordPad будет связан с исходным объектом. При связывании объекта в системе будет только один объект (файл, содержащий рас­тровое изображение. При этом в документе WordPad будет содержаться ссылка на него, а не копия объекта. Тот же объект может быть связан с другим документом, возможно, с другим приложением. Независимо от количества документов, ссы­лающихся на данный объект, в системе будет находиться только один исходный объект. Если его изменить, то во всех документах, ссылающихся на него, появится уже измененная версия объекта (рис. 14.4).

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

Присоединение запросов к базе данных


Рассмотрим процесс определения запроса с помощью SQL-операторров и присоединения их к базе данных. Выполните следующие действия.

1. Запустите Visual Data Manadger и откройте базу данных BIBLIO.

2. В окне Database щелкните правой кнопкой мыши на запросе All Titles и из контекстного меню выберите команду Design.Visual Data Manadger отобразит другое окно с определением запроса (рис. 17.18).

Рис. 17.18. Кроме таблиц, база данных содержит запросы — SQL-операторы, входящие в проект базы данных

Примечание

Как видите, при открытии окна Database иконка запроса отличается от иконки таблицы.

Имя запроса появляется в свойстве RecordSource элемента управления Data, соединенного с базой данных BIBLIO. Позже мы используем этот запрос, чтобы модифицировать приложение ManyTbIs. Но сначала рассмотрим инструментальные средства Visual Data Manager для построения SQL-запросов.

Построение SQL-запросов

Если SQL кажется вам сложным для изучения, то знайте: Visual Data Manager позволяет создавать простые SQL-операторы с помощью мыши. Щелкните правой кнопкой мыши в окне Datadase и из контекстного меню выберите New Query (Новый запрос), чтобы открыть окно Query Builder (Конструктор запросов) (рис. 17.19).

Рис. 17.19. Query Builder: построение SQL-операторов с помощью мыши

Используем Visual Data Manager для построения простых SQL-операторов. Выполните следующие действия, чтобы создать запрос, выбирающий названия всех изданий и их издателей.

1. Выберите имена таблиц Publishers и Titles, щелкнув кнопкой мыши на их именах в списке Tables (Таблицы). Поля выбранных таблиц появятся в списке Field to Show (Показывать поля).

2. Щелкните на именах полей, которые необходимо включить в запрос (в RecordSet, который этот запрос возвратит). Щелкните на следующих именах полей Titles Title, Titles [Year Published] и Publishers Name.

Построим наиболее сложную часть SQL-оператора. Щелкните на кнопке Set Table Joins (Установить связи между таблицами) для задания объединения (чтобы определить, как таблицы будут объединены) Visual Data Manager не использует оператор JOIN. Он реализует объединения с помощью ключевого слова WHERE, а это означает, что на этот инструмент нельзя полагаться при создании усовершенствованных запросов.


3. В списке Select Table Pair (Выбрать пары таблиц) щелкните на именах таблиц Titles и Publishers. Поля обеих таблиц появятся в списках под заголовком Select Fields to Join On (Выбрать поля для объединения), как показано на рис. 17.20.



Рис. 17.20. Диалоговое окно Join Tables: позволяет определить внутренние объединения

4. Щелкните на поле PubID в обоих списках. Таблицы Titles и Publishers объеди­нятся по значению поля PubID.

5. Щелкните на кнопке Add Join to Query (Добавить объединение к запросу), чтобы добавить в запрос объединение.

6. Щелкните на кнопке Close, чтобы возвратиться в окно конструктора запросов Query Builder. Запрос определен.

7. Щелкните на кнопке Show, чтобы отобразить SQL-оператор, или на кнопке Run, чтобы выполнить его. После сообщения о том, является ли данный запрос SQLPassThrough-запросом, щелкните на кнопке No. Появится новая форма с элементом управления Data, позволяющим перемещаться по выбранным записям.

8. Для присоединения запроса к базе данных щелкните на кнопке Save. Visual Data Manager запросит имя запроса и присоединит его к базе данных. В следующий раз при подключении элемента управления Data к базе данных в списке доступных элементов RecordSource появится имя запроса.

Можно использовать конструктор запросов Query Builder, чтобы определить критерии выбора, реализуемые с помощью ключевого слова WHERE для груп­пирования и упорядочивания результатов запроса, а также ограничения размера RecordSet (если он слишком большой).

Чтобы добавить критерий выбора, выберите имя поля в списке Field Name, задайте операцию и определите значение в поле Value. Если вы не помните значение определенного поля, то щелкните на кнопке List Possible Values (Список возможных значений) и Visual Data Manager выведет все значения указанного списка.

SQL-операторы, сгенерированные конструктором запросов Query Builder, просты и пригодны для несложных запросов. Например, конструктор запросов Query Builder не создает множественные объединения. Но всегда можно отредактировать SQL-оператор (открывая запрос в режиме разработки) и добавить в него ключевые слова. Если необходимо создать SQL-оператор, а вы еще свободно не владеете SQL-языком, то используйте более совершенный инструмент, например, MS Access.



VB6 в действии: проект SQLTbIs (модификация ManyTbIs)

Приложение ManyTbIs объединяет все таблицы базы данных

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

1. Откройте приложение ManyTbIs, сохраните его как SQLTbIs (измените имя формы на SQLTbIs) и поместите его в новую папку.

2. Удалите все элементы управления Data формы и разместите на ней новый элемент управления Data. Назовите его TITLES и присвойте его свойству Caption значение

Titles-Authors-Publishers.


3. Соедините этот элемент управления с базой данных BIBLIO, указав в свойстве DatabaseName путь к базе данных.

4. Откройте список свойства RecordSource и выберите All Titles. Это имя SQL-запроса в базе данных, который возвращает необходимый RecordSet (названия изданий, их авторов и издателей).

5. Так как RecordSet создан с помощью SQL-оператора, то он является набором записей типа DynaSet, и для элемента управления Data необходимо установить свойство RecordSetType в 1-DynaSet.

6. Теперь откорректируйте свойства DataSource и DataFields элементов управления, размещенных на форме, чтобы они были связаны с соответствующими полями RecordSet через элемент управления Datal. Для этого необходимо установить их свойство DataSource в значение

Datal,
а свойство DataField - в Title, Company Name, Year Published и Author.

7. Последние два поля на основной форме приложения (Descriptions и Comments) не являются частью запроса All Titles, поэтому удалите их из формы. Можно изменить запрос или создать новый (который содержит эти поля), основанный на запросе All Titles.

8. Удалите весь код в приложении: он больше не нужен.

В действительности, SQL-оператор выполняет функции кода приложения, но этот подход компактнее и эффективнее.


Проектирование иерархии объектов


Command

Проект, называющийся DataRep, находится в папке этой главы на компакт-диске. В этом параграфе созданы несколько объектов Command, организованных в иерархическую структуру. Названия всех компаний содержатся в таблице Customers. Найдем для каждой компании выписанные ею счета и общее их количество. А для каждого счета - его подробное описание и итоги. Отобразим иерархию записей с помощью элемента управления Grid (элемент управления типа MSHFlexGrid). Элемент управления MSHFlexGrid похож на элемент управления MSFlexGrid, однако предназначен для использования с базами данных и с иерархией элементов управления Command.

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

Рис. 18.2. Иерархия объектов Command (заказчики-счета-сумма), отображаемые в элементе управления FlexGnd

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

1. Откройте новый Data-проект и создайте объект Connection для базы NWIND, как показано в последнем параграфе.

2. Добавьте новый объект Command (Commandl), откройте диалоговое окно его свойств (щелкните правой кнопкой на имени Commandl и выберите Properties).

3. В окне Properties объекта Commandl установите значение свойства Connection в Connection 1 и выберите Source of Data (Источник данных).

Имена компаний приведены в таблице Customers базы данных NWIND, поэтому выберите строку Table в списке Database Object и Customers - в списке Object Name. После выбора Table в первом раскрывающемся списке появятся имена всех таблиц.

Мы хотим получить счета каждого заказчика. Это означает, что необходимо создать новый объект Command, который будет принадлежать уже созданному объекту Commandl, те будет дочерним для объекта Commandl. Commandl содержит данные о заказчиках, а дочерний объект — счета заказчиков.


4. Щелкните правой кнопкой в окне DataEnvironment на объекте Commandl и выберите из контекстного меню команду Child.

Новый объект Command будет назван Command2. Так как Command2 — это дочерний объект Command1, то для него выполняется точно такое же подключение, как и для объекта Command1. Поэтому окно Connection недоступно. Дочерний объект Command не может иметь собственного подключения. В нашем случае дочерний объект Command возвращает счета из таблицы Orders.

5. Выберите строку Table в списке Database Object и укажите Orders — в списке Object Name.

Так как Command2 — это дочерний объект, то необходимо установить связь (relation) с его с родительским объектом.

6. Переключитесь на вкладку Relation диалогового окна Properties объекта Command2 и выберите Command 1 в качестве родительского объекта в пункте Parent Command (рис. 18.3).

Отношения между объектами определены. Таблицы Customers и Orders используют поле CustomerID в качестве связующего.

7. Выберите значение CustomerID в списках ParentFields и Child Fields/Parameters и щелкните на кнопке Add. В текстовом поле внизу будет показана связь поля CustomerID таблицы Customers с полем CustomerID таблицы Orders.

Добавьте следующий дочерний объект Command, принадлежащий Command2.



Рис. 18.3. Вкладка Relationship: определение отношении между дочерними и родительскими объектами Command

8. Щелкните правой кнопкой на объекте Command2 в окне DataEnvironmentI, выберите команду Child и откройте диалоговое окно Properties для нового объекта Command.

Новый объект Command будет возвращать сумму для каждого счета. Сумма не хранится в таблице базы данных NWIND. Она вычисляется с использованием SQL-оператора. Так как сумма счета часто пересчитывается, то в качестве источника данных следует выбрать View (Просмотр). Это эквивалентно тому, что значение OrderSubtotals будет вычисляться с помощью SQL-оператора всякий раз, когда это требуется. Результатом этого вычисления будет набор записей, как если бы источником данных была таблица. Разумеется, значения, представленные как View, не могут редактироваться.



9. Выберите View в списке Database Object, а в списке Object Name укажите Ок. Subtotals

Диалоговое окно свойств объекта Commands должно выглядеть так, как показано на рис. 18.4.

Следующая задача - добавление отношений между объектом

Commands и его родительским объектом Command2. Для этого выполните следующие действия.

1. На вкладке Relation определите Command2 в качестве родительского объекта и выберите поле OrederID в обоих списках области Relationship Definition (рис. 18.5).

2. Чтобы добавить отношение, щелкните на кнопке Add.

Мы создали иерархию объектов Command: суммы счетов были подключены к группам счетов, которые, в свою очередь, подключены к заказчикам. Зададим способ подведения итогов. Сумма (или итог) обычно задается вначале определения дочернего объекта. Выполните следующие действия.

1. В диалоговом окне Command2 выберите вкладку Aggregates (Итоги).

2. Создайте новый итог и назовите его Order Total (щелкните на кнопке Add и укажите Order Total в приглашении ввода имени нового итога).

3. Для вычисления суммы используется функция SUM, поэтому выберите Sum в списке Function Нам необходимо добавить сумму всех счетов к объекту Commands, который хранит все детали счетов.

4. Выберите объект Commands в списке Aggregate On и имя Subtotal в списке Field.



Рис. 18.4. Источник данных объекта Command3

OrderTotal — это имя итогового значения, вычисляемого для каждого счета. Это значение содержит суммы по всем счетам, выбранным с помощью элемента управления Command2 (рис. 18.6). По отношению к элементу Command2, OrderTotal – одно из полей его набора записей (RecordSet).



Рис. 18.5. Отношение объекта Commands к родительскому объекту



Рис. 18.6. Вкладка Aggregates объекта Command2

Задайте способ подведения итогов для объекта Command 1. Выполните следующие действия.

1. Откройте диалоговое окно свойств Command 1 и выберите вкладку Aggregates.

2. Добавьте новый итог и назовите его TotalOrders. Сумма TotalOrders — количество счетов на каждого заказчика.



3. Выберите Count в списке функций (необходимо посчитать количество счетов, а не их сумму), a Command2 в списке Aggregates и укажите OrderID в списке Field.

Итог TotalOrders вычисляет количество всех счетов в RecordSet объекта Comnnand2 для каждого заказчика. На рис. 18.7 показано задание способа вычисления первого итога объекта Command 1.



Рис. 18.7. Закладка Aggregates объекта Command 1

Вычислите полный итог по всем счетам для каждого заказчика. Выполните следующие действия.

1. Добавьте новый итог с именем CustomerTotal.

2. На этот раз необходимо добавить частичный итог для всех счетов. Для этого выберите функцию SUM, затем в списке Aggregate On - Command2, и в списке Field - OrderTotal.

OrderTotal — это еще один итог, определенный для объекта Command2. По отношению к объекту Objecti, OrderTotal является одним из его полей. После определения всех итогов окно DataEnvironmentI конструктора ActiveX выглядит так, как показано на рисунке 18.8. С помощью вертикальной полосы прокрутки можно увидеть итоги для каждого из объектов — они находятся под соответствую­щими объектами Command.



Рис. 18.8. Окно DataEnvironment после определения всех итогов

Мы построили объекты Command, которые возвращают нужные записи из базы данных, и определили отношения между ними. Теперь нужно вывести данные на форму. Способы вывода данных на форму описаны в следующих параграфах.


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


ActiveX DataEnvironment

Создадим простое приложение для работы с базами данных с использованием конструктора ActiveX DataEnvironment. Проект Denvl — это простая форма, которая позволяет перемещаться по записям таблицы Customers в базе данных NWIND. Для разработки формы, показанной на рис. 18.1, нужно выполнить подклю­чение к базе данных NWIND, затем получить данные из таблицы Customers и отобразить их в элементах управления, связанных с данными.

Для этого необходимо выполнить следующие действия.

1. Открыть новый проект и в окне типа проекта выбрать Data Project.

2. Выполнить двойной щелчок на объекте DataEnvironmentI в проводнике проекта, для того чтобы открыть окно DataEnvironment.

Рис. 18.1. Проект Denv1: основы использования конструктора элементов ActiveX DataEnvironment

Окно приложения DataEnvironment содержит объект

Connection и один или больше объектов Commandю Папка Commands пуста, но она будет заполнена позже при создании объектов Commandю

3. Щелкните правой кнопкой мыши на объекте Connection 1 и выберите Properties из контекстного меню, чтобы открыть окно Data Link Properties. Используйте вкладки в этом окне для задания базы данных, к которой нужно подключиться.

4. На вкладке Provider выберите драйвер связи между приложением и базой данных.

Большинство баз данных использует OLE DB-провайдер, являющийся для баз данных тем же, чем является OLE для других приложений. Выберите Microsoft OLE DB-Provider. Это простейший провайдер, который подключает приложение к базам данных Microsoft Access.

5. Выберите вкладку Connection.

6. Щелкните на кнопке с многоточием, чтобы указать путь к базе данных NWIND (в папке VB98).

7. Щелкните на кнопке Test Connection, чтобы убедиться в том, что подключение работает.

8. Если база данных требует указания имени пользователя и пароля, то будет выдано приглашение для их ввода. Введите ту же информацию в соответст вующие редактируемые поля вкладки Connection.

9. Выберите вкладку Advanced, чтобы выбрать способ открытия базы данных и опции доступа к ней для других пользователей.


6. Щелкните на кнопке ОК, чтобы перейти к окну DataEnvironmentI, в котором информация представлена в виде дерева.

7. Нажмите на знаке плюс перед объектом Command 1, чтобы отобразить имена полей таблицы Customers.

8. Выберите форму проекта (если вы не переименовывали ее, то это Form1).

9. Перетащите на форму объект Command 1 из окна DataEnvironmentI. Visual Basic создаст столько пар "метка-текстовое поле", сколько понадобится для отображения всех полей объекта Command 1. Если вы не хотите, чтобы были показаны все поля, перетащите только выделенные поля.

10. Выберите форму и разместите на ней элементы управления. В этой форме отсутствуют кнопки навигации. Разместите четыре кнопки на форме (см. рис. 18.1) и введите следующие команды для их событий Click.

Программа 18.1. Программирование кнопок навигации

Private Sub Commandl_Click ()

DataEnvironment1.rsCommand1.MoveFirst

End Sub

Private Sub Command2_Click()

If DataEnvironment1.rsCommand1.BOF Then

Beep

Else

DataEnvironment1.rsCommand1.MovePrevious

If DataEnvironment1.rsCommand1.BOF Then

DataEnvironment1.rsCommand1.MoveFirst

End If

End If

End Sub

Private Sub Command3_Click()

If DataEnvironment1.rsCommand1.EOF Then

Beep

Else

DataEnvironment1.rsCommand1.MoveNext

If DataEnvironment1.rsCommand1.EOF Then

                DataEnvironment1.rsCommand1.MoveLast

           End If

End  If

End Sub

Private    Sub Command4_Click ()

DataEnvironment1.rsCommand1.MoveLast

End Sub

Если вы прочитали предыдущую главу, то вам должен быть понятен этот код. Объект DataEnvironmentI предоставляет набор данных rsCommandl типа RecordSet, который содержит записи, извлеченные из таблицы Customers объектом Command 1. Имя набору данных назначается автоматически в соответствии с именем объекта Command (с префиксом "rs"). Объект DataEnvironmentI.rsCommandl — это набор данных, который поддерживает большую часть методов и свойств объекта DAO.

Для перемещения по записям используются методы Move (MoveFirst, MoveNext, MovePrevious и MoveLast). Чтобы предотвратить перемещение к несуществующей записи (перед первой или после последней), проверьте свойства BOF и EOF набора данных rsCommand 1.

Совет

Информация о свойствах EOF и BOF и об их использовании методами приведена в гл. 17.

Используя конструктор ActiveX DataEnvironment и несколько строк кода, можно разработать форму, способную перемещаться по набору записей. Этот пример не производит должного впечатления. Используя элемент управления Data это можно сделать гораздо быстрее. В следующем примере создается более сложный объект Command способом комбинирования трех таблиц из одной и той же базы данных (и все внутри конструктора ActiveX DataEnvironment) без единой строки кода.


Программирование


ADO

Как видно, бескодовое приложение для работы с базами данных, созданное с помощью элемента управления ADO, не такое гибкое и мощное, как приложение, разработанное с использованием элемента управления Data. Для полноценного использования ADO необходимо уметь управлять им с помощью программного кода. В этом параграфе обсуждается объектная модель ADO и показано, как программировать его основные объекты. Оставшаяся часть этой главы посвящена объектам Active Data, даны несколько примеров, демонстрирующих сходство между ADO и DAO.



Программирование операции перетаскивания для вставки объектов


OLE-операции Drag-and-Drop (Перетащить-и-опустить) удобнее задавать в тексте программы, а не определять автоматически. Проект OLEDDMAN (папка OLEDD на компакт-диске) имеет тот же интерфейс, что и проект OLEDDAUTO, но в нем установлено значение Manual свойства OLEDropMode. Значение своиства OLEDragMode элемента управления TextBox установлено в Automatic, поэтому для инициализации операции писать программу не требуется. То же относится и к элементам управления RichTextBox и PictureBox.

Каждый из элементов управления определяет, когда на него опущен объект, и реагирует соответствующим образом. Рассмотрим самый простой элемент управле­ния — TextBox. Когда на него опущен объект, происходит событие OLEDragDrop, эквивалентное событию DragDrop. Событие OLEDragDrop определяется следующим образом:

Private Sub Textl_OLEDragDrop^(Data As Data0b]ect, _

Effect As Long, Button As Integer, Shift As Integer, _

x As Single, у As Single)

Data - это переменная, описывающая объект, который был опущен. Эта пере­менная имеет несколько свойств для доступа к объекту (они рассматриваются вкратце). Effect — константа, которая определяет тип перемещения (операция Move или Copy). Параметр Button

описывает кнопку, щелчок на которой инициализирует операцию помещения объекта; параметр Shift

содержит информацию о состоянии клавиш управления Shift, Alt и Ctrl. Последние два параметра - координаты точки, в которую помещается скопированный или перемещенный объект.

Методы, применяемые при работе с объектами типа Data подобны методам, используемым при работе с буфером обмена Clipboard. Метод GetFormat позволяет определить формат данных. При этом он не возвращает тип данных. При его вызове необходимо указывать предполагаемый тип данных, и если он соответствует указанному, то возвращается значение True, в противном случае — False. Чтобы выяснить, содержит ли объект Data текст, следует воспользоваться следующим оператором If:

If Data.GetFormat(vbCFText) Then

{обработка текста}

End If

(Константы, описывающие различные типы данных, точно такие же, как и ис­пользуемые при работе с буфером обмена.)


Чтобы получить сами данные, следует использовать метод GetData. Этот метод возвращает объект, который должен быть присвоен соответствующей переменой. Если данные являются текстом, можно присвоить значение, возвращенное методом GetData, свойству Text элемента управления TextBox. Если данные — растровое изображение, то можно присвоить их свойству Picture того элемента управления, который может выводить изображение.

Синтаксис метода GetData имеет вид:

Data.GetData(format)

где

formal — константа, которая определяет желаемый формат данных. Один и тот же объект может иметь различные форматы. Выделив абзац из документа Word, можно поместить его в окно элемента управления TextBox как текст, а в окно элемента управления RichTextBox - как сформатированный текст. Данные как таковые могут быть восстановлены во множественных форматах, в зависимо­сти от возможностей элемента-получателя. Метод EditCopy элемента управления Graph работает точно так же (рассматривается в Приложении В "The MSChart Control" ("Элемент управления MSChart")). Он копирует текущее изображение из окна элемента управления Graph. Эти данные могут быть вставлены либо как растровое изображение в рабочее окно графического редактора, или как текст — в окно текстового редактора.

Если пользователь поместил один или несколько файлов на элемент управления (значение выражения GetFotmat(vbCFFiles)

равно True), можно воспользоваться семейством Files объекта Data, чтобы получить названия этих файлов:

If Data.GetFormat(vbCFFiles) Then

For i = 1 To Data.Files.Count

{обработка файла Data.Files(i)) }

Next

End If

Ниже приводится текст обработчика OLE — операции перетащить-и-опустить для окна элемента управления TextBox:

Private Sub Textl_OLEDragDrop(Data As Data0b]ect, _

Effect As Long, Button As Integer, Shift As Integer, _

x As Single, у As Single)

Dim pie As Picture

If Data GetFormat(vbCFFlles) Then

Text1.Text   "You dropped the following files " & vbCrLf

' (Вы поместили следующие файлы)



For i =  1 To Data Files Count

Textl.Text = Textl Text & Data.Files(i) & vbCrLf

Next

End If

If Data.GetFormat(vbCFRTF) Then

Text1.Text = Data.GetData(vbCFText)

End If

If Data GetFormat(vbCFBitmap) Then

imgWidth = Round(ScaleX(Data GetData _

(vbCFBitmap).Width, vbHimetric, vbPixels))

imgHeight - Round(ScaleY(Data GetData _

(vbCFBitmap) Height, vbHimetric, vbPixels))

Textl.Text = " You dropped an image with the folowing _

specifications:" & vbCrLf

' (Вы поместили изображение со следующими параметрами:)

Text1.Text = Textl.Text & "WIDTH " & imgWidth & vbCrLf

Text1.Text = Textl.Text & "HEIGHT " & imgHeight

End If

Если поместить один или несколько файлов в окно элемента управления TextBox, то будут перечислены их имена. Если вы перетащили текст из элемента управления RichTextBox, то этот же самый текст появится в окне элемента TextBox не отформатированным. И, наконец, если поместить в TextBox изображение из элемента управления PictureBox, то будут выведены характеристики изображения. Следует обратить внимание на то, как программа передает размеры изображения. Объект, полученный в результате применения метода GetData, является объектом типа Picture, следовательно, можно обратиться к его свойствам Width и Height, чтобы получить значения размеров объекта.

Текст обработчика события OLEDragDrop элемента управления RichTextBox напоминает фрагмент, приведенный выше. Однако элемент управления RichTextBox воспринимает большее количество типов данных и реагирует на них по-разному Можно открыть соответствующий проект в Visual Basic и исследовать текст программы. Если попытаться поместить изображение в окно элемента управления RichTextBox, то в результате будет получено сообщение об ошибке. Следующий фрагмента программы должен бы выполнить вставку растрового изображения в RichTextBox, но этого не происходит. Во время выполнения программы вместо перемещения изображения выдается сообщение об ошибке.

If Data.GetFormat(vbCFBitmap) Or Data.GetFormat(vbCFDIB) Then



RichTextBox1.OLEObjects.Add, , Data.GetData(vbCFDIB)

GoTo PasteDone

End If

Единственный выход из данной ситуации который можно предложить - на мгновение переключить свойство OLEDropMode элемента управления RichTextBox в состояние Automatic, а затем вернуть его в состояние Manual. Первое действие должно происходить в обработчике события OLEStartDrag элемента управления PictureBox.

Private Sub Picture1_OLEStartDrag(Data As Data0bject, _

AllowedEffects As Long)

RichTextBox1.OLEDropMode = rtfOLEDropAutomatic

End Sub

После того как операция переноса завершена можно установить исходное значение свойства OLEDropMode элемента управления. Это действие должно выполняться в обработчике события OLECompleteDrag элемента управления TextBox, которое сигнализирует об окончании OLE-операции перетащить-и-опустить:

Private Sub Picture1.OLECopmpleteDrag(Effect As Long)

RichTextBox1.OLEDropMode =  rtfOLEDropManual

End Sub

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


Простое редактирование и обновление записей


Основное отличие между объектами ADO RecordSet и DAO RecordSet или RDO ResultSets - это отсутствие метода Edit. He надо готовить запись к редактированию. Вместо этого полю присваивается новое значение. Не нужно вызывать метод Update для записи изменений. При перемещении к другой записи изменения автоматически записываются в базу данных.

Другая интересная особенность объекта ADO RecordSet — он позволяет создавать массивы имен полей и значений и использовать их для добавления новых записей. Для добавления новой записи используйте метод AddNew. Пример добавления новой записи к текущему объекту RecordSet (RecSet) с использованием массива и приведен ниже.

RecSet.AddNew Array ("ProductName", "CategoryID", "UnitPrice"),

Array ("Ma's Marmelade", 34, 3.45)

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

RecSet. Update новая запись записывается в базу данных.

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

RecSet. Fields ("ProductName") = "Ma's Marmelade"

Для обновления нескольких полей в записи также используйте массивов:

RecSet.Update Array ("ProductName", "CategoryID", "UnitPrice"),

Array ("Ma's Marmelade", 34, 3.45)

Методы AddNew и Update принимают в качестве аргументов два массива. Первый содержит имена полей, а второй — их значения.

В последнем параграфе этой главы рассмотрены два примера программирования объектов ADO.

VB6 в действии: проекты AD01 и AD02

На компакт-диске находятся два простых проекта, демонстрирующих неко­торые методы и свойства ADO компонентов. Откройте проекты AD01 и AD02 в среде разработки Visual Basic и просмотрите их код. Проект AD01 демонстрирует операции получения и манипулирования записями. Главная форма содержит два списка имен категорий (табл. Categories в базе данных NWIND) и имен товаров в выбранной категории. Когда пользователь выбирает категорию в первом списке, второй список заполняется наименованиями ее товаров.


В первом параграфе главы описываются протоколы, используемые в Web и Internet, рассказывается о тегах HTML и показано, как использовать HTML для создания простых документов с гиперссылками (статические Web-страницы). Далее показано, как активизировать Web-страницы, используя сценарии (scripting) VBScript и элементы управления ActiveX, как преобразовать статическую Web-страницу в интерактивное приложение (это позволит запустить ее через Internet в окне броузера). В конце главы рассмотрено создание Web-страниц, в которых используются стандартные элементы управления ActiveX.

В главе также даны основы построения динамических HTML-страниц (DHTML). DHTML - последняя тенденция в оформлении Web-страниц, переводящая HTML на новый уровень — позволяет Web-разработчикам создавать приложения HTML, аналогичные приложениям рабочего стола, обогащенным эффектами мультимедиа. Это слишком обширная тема для глубокого и подробного изучения, поэтому мы рассмотрим лишь принципы создания DHTML. Относительно Web, основное внимание уделено нескольким темам, посвященным работе Web и разработке Web-страницы как приложения. Описана роль VBScript в программировании Web-страниц. В следующих главах приведена специфическая информация о соче­тании авторских технологий VB и Web в Web- и VB-приложениях. Мы научимся отображать страницы HTML на формы Visual Basic и использовать модели Web с гиперссылками в VB-приложениях.

Intranet является органичной частью Web

Материал этой главы полезен не только при выпуске документов в Internet, но и при построении Intranet-приложений.

Широкое распространение Web — доказательство того, что он действительно прост в использовании. Средства работы с ним становятся составной частью опера­ционных систем, и рабочий стол Windows 98 напоминает Web-броузер.

Если Web-технология позволяет упростить такую хаотичную структуру как Internet, то почему бы не использовать ее в локальных сетях? Многие локальные сети спроектированы как миниатюрные Internet. Intranet или корпоративная Internet — это локальная сеть, использующая технологию Internet. Для упрощения операций в Intranet можно использовать Web-модель, не запуская конкретную Web-страницу, и без ограничений в виде платы за модемную связь.

Intranet, как и

Internet, работает с протоколом TCP/IP, но не является глобальной сетью. Пользователи Intranet сети - работники корпорации, университета или другой организации. Эта сеть не доступна пользователям извне. В отличие от World Wide Web, Intranet-сеть имеет один сервер. Он поддерживает все документы, запраши­ваемые клиентами.

Во многих корпорациях

Intranet используется для предоставления информации служащим, а Web-узел — внешним пользователям. Использование технологии, которая сделала Web столь популярным, позволяет создавать локальные корпора­тивные сети. Но основная особенность корпоративной Intranet заключается не столько в использовании протокола связи TCP/IP, сколько в использовании протокола HTTP (HyperText Transfer Protocol — протокол передачи гипертекста).


Проверка корректности данных


Из первого примера главы видно, что элемент управления Data может использо­ваться для редактирования записей. Однако приложения баз данных должны проверять правильность (validating) данных пользователем перед их сохранением в базе. Элемент управления Data предоставляет несколько событий и методов для проверки правильности вводимых данных перед их сохранением в базе.



Проверка орфографии документов


Одна из наиболее полезных функции Word — способность к орфографической проверке документов. Эту же возможность Word предоставляет объектам VBA, и ее можно использовать в приложениях, созданных в Visual Basic. Сделать это очень просто. Чтобы обратиться к подпрограмме проверки орфографии Word, необходимо определить два объекта семейство ProofReadingErrors и семейство SpellingSiiggestions.

Семейство ProofReadingErrors — это свойство объекта Range Оно содержит слова с орфографической ошибкой в объекте Range. Чтобы вызвать Word для орфогра­фической проверки фрагмента текста и расширить семейство ProofReadingErrors, следует вызвать метод SpellmgErrors объекта Range. Этот метод возвращает результат, который должен быть сохранен в объектной переменной типа ProofreadingErrors:

Dim SpellCollection As ProofreadingErrors

Set SpellCollection = DRange SpellingErrors

DRange — это объект типа Range (абзац или весь документ). Вторая строка заполняет переменную SpellCollection словами с орфографическими ошибками. После этого можно организовать цикл типа For Each Next, чтобы прочитать слова из указанного семейства.

Помимо отыскания и выделения орфографических ошибок,

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

объекта Application, передавая ему слово с орфографической ошибкой в качестве параметра. Обратите внимание, что это метод объекта Application, а не проверяемого объекта Range. Результаты, возвращенные методом GetSpellmgSuggestions, должны быть сохранены в аналогичной объектной переменной, которая была объявлена как переменная типа SpellingSuggestions:

Dim CorrectionsCollection As SpellingSuggestions

Set CorrectionsCollection = _

AppWord.GetSpellmgSuggestions ("antroid")

Оператор, находящийся во второй строке, организует доступ к списку предла­гаемых вариантов для слова antroid.


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

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

SpellDoc — это приложение, в котором используются методы Word для орфо­графической проверки документа. Приложение SpellDoc можно найти в папке, посвященной этой главе на компакт-диске. Главная форма приложения, показанная на рис. 14.15, содержит окно элемента управления TextBox, в которое пользователь может вводить некоторый текст (или вставлять текст из другого приложения) и выполнять его орфографическую проверку, щелкая на кнопке Spell Check Document.



Рис. 14.15. Главная форма приложения SpellDoc

Приложение обратится к Word и запросит список слов с орфографическими ошибками Этот список будет отображаться в окне другой формы (рис. 14.16). В окне элемента управления ListBox, расположенном слева, приводится список всех слов с орфографическими ошибками, которые Word обнаружил в тексте. Но Word не только составляет список слов, содержащих орфографические ошибки, но и предлагает возможные варианты их замены. Чтобы просмотреть список альтер­нативных вариантов написания определенного слова, следует с помощью мыши выбрать слово в левом списке



Рис. 14.16. Эта форма приложения SpellDoc отображает слова с орфографической ошибкой и возможные варианты замены

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

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

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

Public AppWord As Application

Public CorrectionsCollection As SpellingSuggestions

Public SpellCollection As ProofreadingErrors

Переменная



SpellCollection

описывает семейство, содержащее все слова с орфо­графическими ошибками, а переменная CorrectionsCollection - семейство, содержащее предложенные программой проверки орфографии варианты замены для опреде­ленного слова. Значение переменной CorrectionsCollection присваивается каждый раз, когда пользователь выбирает другое слово с орфографической ошибкой в окне Spelling Suggestions (см. рис. 14.16).

После выполнения щелчка на кнопке Spell Check Document программа обра­щается к приложению Word. Сначала с помощью функции Get0bject() программа пытается соединиться с запущенным экземпляром Word. Если в настоящее время нет ни одного запущенного экземпляра Word, запускается новый экземпляр. Это выполняет следующий фрагмент программы.

Программа 14.12. Обращение к Word

Set AppWord = Get0bject ("Word Application")

If AppWord Is Nothing Then

Set AppWord = CreateObject ("Word.Application")

If AppWord Is Nothing Then

MsgBox "Could not start Word Application will end"

' (Невозможно открыть Word Работа приложения

' будет прекращена)

End

End If

End If

После того как связь с Word установлена, программа создает новый документ и с помощью метода InsertAfter объекта Range копирует содержимое окна элемента управления TextBox в новый документ. Это выполняется следующим образом:

AppWard.Documents.Add

DRange.InsertAfter Textl.Text

Теперь VB-программа вызывает метод SpellingErrors объекта Range, который возвращает семейство объектов Word. Результат метода SpellingErrors присваивается объектной переменной SpellCollection:

Set SpellCollection = DRange.SpellingErrors

Приведенный ниже фрагмент программы добавляет слова, содержащиеся в переменной SpellCollection, к левому списку второй формы и отображает эту форму.

Программа 14.13. Кнопка Check Document

Private Sub Command1_C1ick()

Dim DRange As Range

Me.Caption = "starting word   "

' (начальное слово)

On Error Resume Next

Set AppWord = Get0bject ("Word.Application")



If AppWord Is Nothing Then

Set AppWord = CreateObject ("Word.Application")

If AppWord Is Nothing Then

MsgBox " Could not start Word. Application will end"

'(Запустить Word невозможно. Приложение будет закрыто) End

End If

End If

On Error GoTo ErrorHandler

AppWord.Documents.Add

Me Caption = "checking words... "

'(проверка слов... )

Set DRange = AppWord.ActiveDocument.Range

DRange.InsertAfter Text1.Text

Set SpellColiection = DRange.SpellingErrors

If SpellColiection.Count > 0 Then

SuggestionsForm.List1.Clear

SuggestionsForm.List2.Clear

For iWord = 1 To SpellColiection.Count

 SuggestionsForm!List1.Addltem _

SpellColiection.Item(iWord)

Next

End If

Me.Caption = "Word VBA Example"

SuggestionsForm.Show

Exit Sub

ErrorHandler:

MsgBox "The following error occured during the document's _

spelling"& vbCrLf & Err.Description

' (Во время проверки обнаружена следующая ошибка ...)

End Sub

Во второй форме приложения основное внимание сконцентрировано в Word на обработке события Click в окне Words in Question. Каждый раз, когда выполня­ется щелчок на элементе списка в левом окне ListBox, программа вызывает метод GetSpellingSuggestions

объекта AppWord, передавая выбранное слово в качестве параметра. Обратите внимание, что к значению свойства Listlndex объекта List прибавляется 1, чтобы отобразить тот факт, что индексация элементов семейства начинается с 1, в то время как индексация элементов окна списка ListBox начина­ется с 0. Метод GetSpellingSuggestions возвращает другое семейство, содержащее предложенные слова, которые помещены во второе (правое) окно элемента управления ListBox, помещенное на форме с помощью следующего фрагмента.

Программа 14.14. Обработчик события

Click в окне списка

Private Sub Listl_Click()

Screen.MousePointer = vbHourglass

Set CorrectionsCollection = _

AppWord.GetSpellingSuggestions(SpellColiection.Item _

(List1.ListIndex + 1))

List2.Clear

For iSuggWord = 1 To CorrectionsCollection.Count



List2.AddltemCorrectionsCollection.Item(iSuggWord)

Next

Screen MousePointer = vbDefault

End Sub

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

Теперь вполне очевидно, что внести изменения в Office-приложения совсем несложно. Познакомившись с объектами этих приложений, можно установить с ними связь, управляя некоторыми свойствами и вызывая методы этих объектов.


Работа с


ADO

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

1. Откройте меню Project

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

3. Отметьте опцию Microsoft ActiveX Data Object 2.0 Library

После того как библиотека ADO добавлена в проект, просмотрите состав библиотеки с помощью Object Browser. Если вы знакомы с Remote Data Objects (RDO) из Visual Basic 5, то заметите, что основные объекты, предлагаемые моделью объектов ADO, похожи на RDO, включая процесс доступа к базе данных. Необходимо произвести подключение, а затем выполнить SQL-выражение или сохраненную процедуру базы данных и обработать результаты запроса, возвращаемые объектом RecordSet. В следующем параграфе этот процесс рассмотрен подробно.



Работа с графическими объектами


Графические объекты являются важной частью любого приложения. Графи­ческим объектом может быть и простой значок, и сложное растровое изображение. В параграфе рассмотрены некоторые методы вывода графических изображений с помощью API-функций. Рассмотрены функции BitBlt() и StretchBlt(), в определенном смысле эквивалентные методу PaintPicture в Visual Basic. Основное различие между ними заключается в том, что метод PaintPicture можно применять только к опреде­ленному объекту (элементу управления PictureBox или форме), а с помощью функций BitBltQ и StretchBltQ можно выполнять копирование пикселей изображения в пределах рабочего стола. Их можно использовать для создания разнообразных приложений, например программ копирования экрана, чего не позволяет метод PaintPicture.



Работа с объектом


RecordSet

Если создан объект RecordSet, то можно получить доступ к записям и их полям с помощью нескольких методов и свойств, идентичных методам и свойствам объекта RecordSet DAO. Количество возвращенных записей хранится в свойстве RecordCount, принимающем правильное значение только при перемещении на последнюю запись. Для RecordSet типа Forward-Only нельзя просто получить коли­чество записей. Необходимо просканировать и обработать их все. При иных типах RecordSet можно переместиться с помощью метода MoveLast на последнюю запись, а затем вернуться к первой записи, используя метод MoveFirst. После этого для получения количества строк в объекте RecordSet можно использовать свойство RecordCount. Конечно, этот метод не будет работать с RecordSet типа Forward-Only.

Доступ к индивидуальным значениям полей в строке получают с помощью семейства Fields. Количество колонок в объекте RecordSet находится в свойстве Fields Count. К каждому из полей в текущей строке можно адресоваться с помощью индекса (это порядковый номер поля в SQL-выражении) или по его имени. Например, если используется SQL-выражение,

SELECT ProductName, ProductID FROM Products

то можно получить доступ к именам товаров в текущей записи с помощью выражений двух видов:

RecSet.Fields(0).Value

или

RecSet.Fields ("ProductName") .Value

(Можно опустить Value, как свойство, установленное по умолчанию для семейства Fields.)

Для сканирования объекта RecordSet используйте методы Move (MoveFirst, MoveLast, MovePrevious и MoveNext). В дополнение к методам навигации, объект RecordSet содержит метод AbsolutePosition,

который указывает на позицию текущей записи в объекте RecordSet.

Для сканирования RecordSet можно использовать цикл:

For Each rec In RecSet

{обработка текущей записи}

Next

или следующий фрагмент с циклом For...Next

RecSet.MoveLast

AllRecs = RecSet.RecordCount

RecSet.Move First

For i = 1 To AllRecs

{обработка текущей записи}

RecSet.MoveNext

Next

Похожий цикл используется для сканирования колонок


RecordSet. Имена полей получают с помощью свойства Fields(i).Name. Следующий цикл предназначен для печати имен колонок в наборе записей RecSet.

For Each fld In RecSet.Fields

Debug.Print fld.Name

Next

Можно отсортировать RecordSet в соответствии со значениями полей или отфильтровать их, чтобы отобрать записи, отвечающие определенному критерию. Извлекать рекомендуется только нужные записи в желаемом порядке. Когда это невозможно (или когда создан клиентский RecordSet и необходимо применять разные методы обработки разных записей), то используются свойства Sort и Filter объекта RecordSet.

Свойство Sort принимает в качестве аргумента имя поля, в соответствии с которым необходимо отсортировать RecordSet. Предположим, создан объект RecordSet с именами заказчиков из базы данных NWIND, и необходимо отсортировать их в соответствии с полем Country. Установите свойство Sort.

RSCustomers.Sort = "Country ASCENDING"

Для фильтрации выбранных записей в RecordSet используйте следующее выражение.

RSCustomers.Filter = "Country = 'Germany' "

RSCustomers. Filter — не метод, и он не возвращает RecordSet. А метод Move будет игнорировать записи, у которых значение поля Country не Germany.


Размещение одного окна поверх других


Часто приходится сталкиваться с приложениями, которые размещают свое окно поверх окон других приложений независимо от того. какое именно из них является активным. Примером такого окна может служить окно Find (Найти) редактора Microsoft Word. Чтобы предусмотреть такую возможность, воспользуйтесь API-функцией SetWindowPos().

Private Declare Function SetWindowPos Lib "user32" _

     (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _

ByVal x As Long, ByVal у As Long, _

ByVal ex As Long, ByVal cy As Long, _

ByVal wFlags As Long) As Long

Параметр

hWnd — дескриптор окна, х и у — координаты левого верхнего угла окна, сх и су — ширина и высота окна соответственно. Параметр h WndInsertAfter — дескриптор окна, после которого окно hWnd

находится в списке окон. Параметр hWnd

может принимать одно из значений, указанных в табл. 13.5.

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

Значение

Расположение окна

HWND_BOTTOM HWND_TOP HWND_TOPMOST

HWND_NOTOPMOST

Внизу списка окон

Поверх всех окон

Наверху списка окон

Наверху списка окон, под самым верхним окном

Параметр wFlags является целочисленной константой, содержащей один или несколько флагов, приведенных в табл. 13.6.

Таблица 13.6. Флаги, составляющие параметр wFlags

Флаг

Действие

SWP_DRAWFRAME

Рисует рамку окна

SWP_HIDEWINDOW

Скрывает окно

SWP_NOACTIVATE

Делает окно неактивным

SWP_JMOMOVE

Сохраняет координаты текущего положения окна (параметры х и у игнорируются)

SWP_NOREDRAW

Запрещает автоматическую перерисовку содержимого

окна

SWP_NOSIZE

Сохраняет данные о текущем размере окна

SWP_NOZORDER

Сохраняет текущее положение окна в списке других

окон

SWP_SHOWWINDOW

Отображает окно

Совет

Можно скопировать значения констант из окна API Viewer непосредственно в ваше приложение. Избегайте задания числовых констант в вашем коде.

Текст программы типичного приложения WinTop, демонстрирующего использо­вание функции SetWindowPos(), приведен ниже.


Программа 13.9. Приложение WinTop

Option Explicit

Private Declare Function SetWindowPos Lib "user32" _

(ByVal hwnd As Long, ByVal hWndInsertAfter As Long,_

ByVal x As Long, ByVal у As Long,

ByVal ex As Long, ByVal cy As Long,

ByVal wFlags As Long) As Long

Const HWND_TOPMOST = -1

Const SWP_SHOWWINDOW = &H40

Private Sub Form_Load()

Dim retValue As Long

retValue = SetWindowPos(Me.hwnd, HWND_TOPMOST,_

Me.CurrentX, Me.CurrentY, 300, 300, SWP_SHOWWINDOW)

End Sub      

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

Search & Replace (Поиск и замена) в проекте RTFPad (см. гл.9). При этом данное окно будет оставаться расположенным поверх других окон и видимым при переходе в окно формы редактора (рис. 13.7). Для этого вставьте объявление функции SetWmdowPos() и пару констант в модуль

Public Declare Function SetWindowPos Lib "user32" _

(ByVal HWND As Long, ByVal hWndInsertAfter As Long,_

ByVal x As Long, ByVal у As Long, ByVal ex As Long, _

ByVal cy As Long, ByVal wFlags As Long) As Long

Public Const HWND_TOPMOST = -1

Public Const SWP SHOWWINDOW = &H40



Рис. 13.7. Диалоговое окно Search & Replace (Поиск и замена) видимо даже в том случае, когда активным становится другое окно

Кроме того, потребуется изменить программу обработчика события команды меню Find (Найти). Строку

SearchForm Show

замените следующим оператором:

SetWindowPos SearchForm.hwnd, HWND_TOPMOST, _

Me.CurrentX, Me.CurrentY, 470, 155, SWP_SHOWWINDOW

Значения 470 и 155, указанные в программе, являются размерами окна Search & Replace в пикселях. Значение свойства BorderStyle формы Search должно быть установлено в Fixed, тогда пользователь не сможет изменить размер окна.


Реализация семейства


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

• Метод Add. Добавляет новый элемент в семейство.

•  Метод Remove. Удаляет элемент из семейства.

•  Метод Clear. Удаляет все элементы из семейства.

•  Свойство Count. Возвращает количество элементов в семействе.

•  Свойство Item. Возвращает заданный элемент семейства.

Чтобы сделать это, вставьте следующее объявление семейства в окне Code модуля класса.

Dim DataCollection As New Collection

Data Collection —

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

Программа 15.7. Свойство Count переменной DataCollection

Public Property Get Count() As Long

Count = DataCollection.Count

End Property

Метод Add — это общедоступная функция, которая возвращает значение True, если ее аргументы успешно добавлены в семейство Если при выполнении возни кают ошибки, то метод возвращает False.

Программа 15.8. Метод Add переменной DataCollection

Public Function Add(dValue As Double) As Boolean

On Error GoTo AddError

DataCollection.Add dValue

Add = True

Exit Function

AddError:

Add = False

End Function

Метод Remove — также функция, возвращающая результат типа Boolean. Функция возвращает True, если указанный элемент успешно удален из списка. Кроме того, она генерирует прерывание ошибок выполнения, которое главное приложение может обработать с помощью оператора On Error. Заметьте, что оператор Err.Raise в программном коде 15.9 инициирует ошибку выполнения с номером и ее описанием (обязательно надо добавить константу vbObjectError, чтобы избежать конфликтов со стандартным сообщением об ошибке). Поскольку прило­жение использует класс — он будет получать стандартную ошибку Visual Basic. Заметьте, что Visual Basic может инициировать свою собственную ошибку 1. Но ошибка 1 существует только для нашего класса, вот почему была добавлена константа vbObjectError.


Программа 15.9. Метод Remove переменной DataCollection

Public Function Remove(index As Long) As Boolean

If index < 0 Or index > DataCollection.Count Then

DataCollection.Remove index

Remove = True

Else

Err Raise vbObiectError + 2, "ClassName", _

"Couldn't remove item"

(... элемент удалить нельзя)

Remove = False

End If

End Function

Синтаксис метода Raise для объекта Err:

Err.Raise number, source, description

где source — имя компонента, в котором появляется ошибка (возможно, что несколь­ко компонентов инициируют одинаковую ошибку). Основное приложение должно знать одновременно номер и источник ошибки, а затем предпринять соответст­вующие действия (т.е. устранить причину, которая инициировала ошибку или повторить операцию).

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

Программа 15.10. Метод Item переменной DataCollection

Public Function Itemfindex As Long) As Double

If index < 0 Or index > DataCollection.Count Then

Err.Raise vbObjectError + 1, "ClassName", _

"Index out of bounds"

'(Индекс вышел за пределы границ массива)

Else

Item = DataCollection(index)

End If

End Function

Последний метод (Clear) удаляет все элементы из семейства. Поскольку семейство не имеет собственного метода Clear, необходимо удалить все элементы из семей ства с помощью его метода Remove. Заметьте, что обход семейства осуществляет из конца в начало. Прямой обход может вызвать ошибку исполнения, поскольку сразу после удаления первого элемента свойство DataCollection Count становится меньше на единицу, но это изменение не влияет на число итераций.

Программа 15.11. Метод Clear переменной DataCollection

Public Function Clear() As Boolean

On Error GoTo ClearError

For i = DataCollection.Count To 1 Step -1

DataCollection Remove i

Next

Clear = True

Exit Function

]

ClearError:

Clear = False



End Function

VB6 в действии: класс AXStat

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

•  Свойство Average. Возвращает среднее значение из набора данных, который хранится в элементе управления.

• Свойство Min. Возвращает минимальное значение из набора данных.

• Свойство Мах. Возвращает максимальное значение из набора данных.

Специальные свойства достаточно просты и их реализация показана ниже.

Программа 15.12. Специальные члены класса AXStat

Public Property Get Average() As Double

Dim dSum As Double

Dim itm As Long

For itm = 1 To DataCollection.Count

dSum = dSum + DataCollection(itm)

Next

Average =

dSuiti / DataCollection.Count

End Property

Public Property Get Min () As Double

Dim itm As Long

Min = 1E+202

For itm = 1 To DataCollection.Count

If DataCollection(itm) < Min Then _

Min = DataCollection(itm)

Next

End Property

Public Property Get Max() As Double

Dim itm As Long

Max =

-1E+202

For itm =

1 To DataCollection.Count

If DataCollection(itm) > Max Then _

Max = DataCollection(itm)

Next

End Property

Этот код считывает значения данных, которые хранятся в семействе DataCollection, и вычисляет их базовую статистику. Можно использовать процедуру Property Get, чтобы получить более полную статистику, чем показана здесь. Заметьте, что свойства предназначены только для чтения (не имеет смысла уста­навливать их значения) и не определены дуальные процедуры Property Let.

Код, который реализует стандартные методы семейства, подобен коду, приве­денному ранее в разделе "Реализация семейства". Достаточно просто изменить имя класса в строке, которая инициирует ошибки исполнения.

Тестирование класса AXStat. Тестовый проект для класса AXStat показан на рис. 15.7. Кнопка Create Data Set (Создать набор данных) добавляет 100 случайных чисел к семейству класса. Кнопка Display Data (Отобразить данные) берет данные из класса и показывает их в окне списка. И, наконец, кнопка Show Statistics (Показать статистику) вызывает методы класса для вычисления основных статистических ха­рактеристик набора данных и их отображения. Кнопки справа демонстрируют спо­соб обработки ошибок, инициируемых в классе (но к ним вернемся позже).



Для использования класса AXStat в проекте необходимо сначала добавить в проекте ссылку на класс, а затем создать объектную переменную, соответствую­щую классу. Следующее объявление должно появиться в самом начале окна кода тестовой формы:

Dim STATS As New Statistics

Ключевое слово New

говорит Visual Basic, что необходимо создать новый экземпляр модуля класса Statistics. Первая командная кнопка использует метод Add переменной STATS для создания набора данных из 100 значений.

Программа 15.13. Заполнение объекта STATS случайными данными

Private Sub Command1_C1ick()

List1.Clear

STATS.Clear

For i = 1 То 100

STATS.Add Rnd() * 1000

Next

Command2.Enabled = True

Command3.Enabled = True

End Sub



Рис. 15.7. Тестовая форма класса AXStat

Кнопка Display Data извлекает данные из переменной STATS с помощью метода Item. Значения данных формируются в цикле, который работает в диапазоне от 1 до STATS.Count.

Программа 15.14. Чтение данных из объекта STATS

Private Sub Command2_Click()

Dim i As Long

List1.Clear

For i = 1 To STATS.Count

List1.AddItem Format(STATS.Item(i), "000.000000")

Next

End Sub

Кнопка Show Statistics вызывает методы Average, Min и Мах переменной для вычисления основных статистических характеристик набора данных. Код, соответ­ствующий кнопке Show Statistics, приведен ниже.

Программа 15.15. Использование класса AXStat для вычисления статистических характеристик

Private Sub Command3_Click()

StatsMsg = "There are " & STATS.Count & _

           " points in the data set" & vbCrLf  

' (В наборе присутствуют ... элементов данных)

StatsMsg = StatsMsg & "Their average is" & _   

STATS.Average & vbCrLf    

' (Их среднее значение. .)

StatsMsg = StatsMsg & "The smallest value" & STATS.Mm & vbCrLf

                           '(Минимальное значение...)

StatsMsg = StatsMsg & "The largest value"& STATS.Max

'(Максимальное значение...)

MsgBox StatsMsg

End Sub


Реализация семейства свойств


Некоторые компоненты ActiveX предоставляют массив или семейство свойств. Например, элемент ListBox предлагает свойство List, которое является массивом. Пункты элемента ListBox сохраняются в массиве List, который является свойством этого компонента и к ним можно обратиться, указав индекс от 0 до ListCount-1. Реализовывать свойство - массив из кода компонента не очень сложно, но должны быть объявлены массив и методы для добавления выбора и удаления элементов массива. Вообще массивы - не самые лучшие структуры для хранения нескольких элементов, потому что неудобно быстро удалить элемент из массива. Чтобы удалить элемент из массива, необходимо переместить все элементы следующие за удаляемым, на одну позицию. Структура которая лучше подходит для этого - объект Collection.



Редактирование страницы свойств


Запустите тестовый проект и проверьте работоспособность страниц свойств, сгенерированных мастером. Теперь наступил момент, когда можно добавить еще несколько элементов управления на страницу Text Property, которая позволит разработчикам изменять другие заказные свойства. Законченная страница должна иметь вид, подобный представленному на рис. 16.12.

Рис. 16.12. Страница свойств со свойствами элемента управления FLEXLabel

Откройте страницу свойств в режиме конструирования и добавьте два элемента управления ComboBox и две соответствующие метки над ними. Установите нужный размер и шрифт для всех элементов.

Теперь все готово к изменению кода. Оба элемента управления ComboBox должны быть заполнены допустимыми установками для соответствующих свойств. Наилучшее место для вставки кода инициализации — событие Initialize.

Программа 16.11. Инициализация страницы CaptionProperties

Private Sub PropertyPage_Initialize()

Combo1.AddItem "Top Left"

Combo1.AddItem "Top Middle"

Combo1.AddItem "Top Right"

Combo1.AddItem "Center Left"

Combo1.AddItem "Center Middle"

Combo1.Addltem "Center Right"

Combo1.AddItem "Bottom Left"

Combo1.AddItem "Bottom Middle"

Combo1.AddItem "Bottom Right"

Combo2.Addltem "None"

Combo2.Addltem "Carved Light"

Combo2.Addltem "Carved"

Combo2.Addltem "Carved Heavy"

Combo2.Addltem "Raised Light"

Combo2.Addltem "Raised"

Combo2.Addltem "Raised Heavy"

End Sub

Теперь необходимо исправить обработчик события

SelectionChanged().   Добавим операторы, инициализирующие два элемента управления ComboBox,        которые соответствуют двум новым свойствам. Введите следующий код в обработчик события SelectionChanged страницы свойств.

Программа 16.12. Инициализация элементов ComboBox

Private Sub PropertyPage SelectionChanged()

txtCaption.Text = SelectedControls(0).Caption

Combol.Listlndex = SelectedControls(0).TextAlignment


Combo2.Listlndex = SelectedControls(0).Effect

End Sub

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

Private Sub Combol_Click()

Changed =

True

End Sub

Private Sub Combo2_Click ()

Changed = True

End Sub

На последнем шаге исправим обработчик события

ApplyChanges() так, чтобы он приводил в действие изменения в элементах ComboBox. Ниже приведен код, реализующий обработку щелчка на кнопке Apply.

Программа 16.13. Применение изменений

Private Sub PropertyPage_ApplyChanges()

SelectedControls(0).Caption = txtCaption.Text

SelectedControls(0).TextAlignment = Combol.Listlndex

SelectedControls(0).Effect = Combo2.Listlndex

End Sub

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

1. Устанавливайте свойство Changed в значение True каждый раз, когда свойства меняют свое значение для разрешения использования кнопки Apply.

2. Модифицируйте свойства элементов управления, используя выражение Selec­tedControls (0) propertyName, где propertyName — фактическое имя свойства.

3. Инициализируйте свойства в событии PropertyPage_SelectionChanged() каждый раз, когда пользователь переключается на новую страницу свойств.

Если открыть окно свойств для объекта UserControl, то можно увидеть, что свойство PropertyPages имеет значение 4. Это указывает на то, что элемент управления имеет четыре страницы свойств. Для того чтобы исключить ненужные страницы свойств, вызовите диалоговое окно Connect Property Page, показанное на рис. 16.13 и очистите флажок перед соответствующим именем страницы свойств.





Рис. 16.13. В диалоговом окне вместе со стандартными страницами свойств Visual Basic показана заказная страница свойств элемента FLEXLabel

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


Регистрация компонентов


ActiveX

Классы регистрируются автоматически в системе, где они разработаны. Созда­ваемые DLL или ЕХЕ-файлы, реализующие классы, также автоматически регист­рируются Visual Basic. Но если нужно создать класс, который должен быть доступен разработчикам в других системах? Если компонент создан как ЕХЕ-сервер, то его можно распространить в виде ЕХЕ-файла. При запуске на компьютере, где компо­нент будет использоваться, класс зарегистрируется автоматически. Никаких сооб­щений или форм при этом не выдается. Все, что нужно сделать, так это запустить ЕХЕ-сервер, который сам себя зарегистрирует.

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

Для регистрации ActiveX DLL создайте файл, используя команду Make ClassName.dll из меню File (ClassName является именем класса). Затем скопируйте этот файл в папку Windows System или любую другую. Для регистрации DLL от­кройте окно Command Prompt (окно командной строки DOS), перейдите в пап­ку, где находится DLL, и выполните следующую команду:

С:\WINDOWS\SYSTEM\REGSVR32 ClassName.dll

ClassName.dll -

это имя файла, в котором реализован сервер. Есть несколько опций, которые можно использовать с утилитой REGSVR32. Опция /и удаляет ранее зарегистрированный DLL.

Чтобы удалить файл ClassName.dll, используйте команду:

REGSVR32 /u ClassName.dll

Когда новый компонент DLL зарегистрирован, утилита REGSRV сообщает о результатах операции в диалоговом окне. Для подавления вывода этого окна можно использовать опцию /s (silent - молчаливый) REGSRV32 - это наиболее простой механизм для распространения DLL-серверов. Все, что при этом нужно сделать, это написать маленькую программу, которая копирует файл DLL в папку и затем запускает утилиту REGSRV32 для регистрации скопированного DLL. Если дистри­бутивные файлы были созданы с помощью мастера Package & Deployment, то все компоненты, которые должны быть установлены вместе с приложением, будут устанавливаться программой инсталляции.



Рекурсивное сканирование папки


Рекурсивное сканирование папки (сканирование файлов папки и ее подпапок на произвольную глубину) - это стандартная операция при программировании файловой системы. В гл. 11 было показано, как рекурсивно сканировать папку, используя элементы управления File System (элементы управления DriveListBox, DirectoryListBox и FileListBox). В гл. 8 было создано приложение, которое заполня­ет элемент управления TreeView содержимым устройства или папки. Древовидная структура идеальна для представления папки, потому что папка является древо­видной структурой. В проекте Explorer при использовании объекта FileSystemObject мы обещали вернуться к пояснению работы проекта.

В этом параграфе рассмотрено приложение FSystem, которое заполняет элемент управления TreeView папками диска С. Для отображения содержимого другого устройства или папки внесите в код соответствующие изменения. Форма приложения FSystem показана на рисунке 20.3. Запустите приложение и щелкните на кнопке Populate Tree, чтобы увидеть структуру папок диска С: в окне элемента управления TreeView. Время реакции приложения зависит от количества папок в корневом каталоге устройства. Будьте терпеливы или измените код для просмотра меньшего количества папок.

Рис. 20.3. Приложение FSystem: некоторые методы объекта FileSystemObject

Начнем с простой версии приложения, которая выводит имена папок в окно проверки. Затем заменим оператор Debug. Print соответствующими операторами для добавления имен папок в элемент Tree View.

Программа 20.4. Сканирование диска с помощью объекта FileSystemObject

Dim FSys As New Scripting.FileSystemObject

Private Sub Command1_Click()

Dim folderSpec As String

Set FSys = CreateObject ("Scripting.FileSystemObject")

' В следующей строке укажите папку, которую необходимо видеть

folderSpec = "с:\"

ScanFolder(folderSpec)

Debug.Print "*** Конец списка объектов каталога ***"

End Sub

Sub ScanFolder(folderSpec As String)

Dim thisFolder As Folder


Dim sFolders As Folders

Dim fileItem As File, folderItem As Folder

Dim AllFiles As Files

Set thisFolder = FSys.GetFolder(folderSpec)

Set sFolders = thisFolder.SubFolders

Set AllFiles = thisFolder.Files

For Each folderItem In sFolders

Debug.Print

Debug.Print "*** ПАПКА " & folderltem.Path & "***"

ScanFolder (folderItem.Path)

Next

For Each fileItem In AllFiles

Debug.Print fileItem.Path

Next

End Sub

Обработчик события Click кнопки Command 1 вызывает подпрограмму ScanFolder(), чтобы просканировать папку, имя которой передается в качестве аргумента. ScanFolder() создает объектную переменную thisFolder, которая задает текущую папку. Затем программа создает семейство подпапок из сканируемой папки. Это семейство - sFolder -

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

В версии программы FSystem на компакт-диске операторы, выполняющие вывод в окно проверки, закомментированы и добавлены операторы, помещающие имена папок и файлов в элемент управления TreeView.

Программа 20.5. Заполнение элемента TreeView

Dim FSys As New Scripting.FileSystemObject

Private Sub Coininandl_Click ()

Dim folderSpec As String

Set FSys = CreateObject("Scripting.FileSystemObject")

' В следующей строке укажите папку, которую хотите увидеть

folderSpec = "c:\wind"

folderSpec = UCase(folderSpec)

TreeView1.Nodes.Add, ,folderSpec, folderSpec

Screen.MousePointer = vbHourglass

ScanFolder (folderSpec)

Screen.MousePointer = vbDefauit

TreeView1.Nodes(1).Expanded = True

MsgBox "File List created"

' (Список файлов создан)

End Sub

Sub ScanFolder(folderSpec As String)

Dim thisFolder As Folder

Dim sFolders As Folders



Dim fileItem As File, folderItem As Folder

Dim AllFiles As Files

Set thisFolder = FSys.GetFolder(folderSpec)

Set sFolders = thisFolder.SubFolders

Set AllFiles = thisFolder.Files

For Each folderItem In sFolders

TreeView1.Nodes.Add folderItem.ParentFolder.Path, _

tvwChild, folderItem.Path, folderItem.Name

ScanFolder (folderItem.Path)

Next

For Each fileItem In AllFiles

TreeView1.Nodes.Add fileItem.ParentFolder.Path, _

tvwChild, fileItem.Path, fileItem.Name

Next

End Sub

Заметьте, как метод Add элемента управления TreeView добавляет папку и имена файлов в надлежащее место в дереве. Узел каждой папки является потомком узла родительской папки. Выражение folderltem.ParentFolder.Path является именем текущего пути и используется как ключ узла. Ключ каждого элемента -это имя полного пути к нему, поэтому ключи файлов с одинаковыми именами из различных папках будут помещены в требуемую позицию в дереве.

Код проекта FSystem легко модифицировать, чтобы заполнить элемент TreeView не всеми именами файлов, а только именами выделенных файлов. Критерием для выделения могут быть атрибуты файлов, например, его размер, тип и т.д. Можно выбрать файлы с изображениями, размер которых превышает 100 Кб. Или текстовые файлы, которые не использовались в течение месяца, и т.д.


Рекурсивный просмотр папки


Contacts

В проекте Contacts из предыдущего параграфа подразумевалось, что все контакты хранятся в папке Contacts (точно также и в других проектах подразумевается, что все сообщения постоянно находятся в одной папке) Это приемлемо для пользователей с небольшим числом контактов (или полностью неорганизованных пользователей), но в общем случае это не так. Большинство пользователей организует контакты в подпапки для упрощения поиска. Но организовать просмотр папки Contacts вместе с подпапками не так-то просто. Для реализации такой возможности требуется использовать методы рекурсивного программирования. Если во время чтения гл. 11 " Использование рекурсивных методов" могло показаться, что рассматриваемые методы больше нигде не понадобятся, то в данном случае есть возможность убедиться в обратном. Пусть это не покажется вам навязчивой пропагандой в пользу применения рекурсии, но есть задачи, которые невозможно решить другими способами. Сколь трудным и непривычным не казался бы рекурсивный подход к программированию, но без него невозможно организовать циклический просмотр папки Contacts, при условии, что в ней содержатся подпапки (точно так же, как выполнить обход дерева Tree View).

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

Одноименное приложение, демонстрирующее рекурсивную процедуру просмотра папки Contacts, может быть найдено в папке ALLCONTS, находящейся на компакт-диске в папке, посвященной этой главе. Если после загрузки формы приложения щелкнуть на кнопке Populate Tree, то окно элемента управления TreeView будет заполнено названиями всех подпапок папки Contacts (рис. 14.22). После этого можно открывать различные папки в окне элемента управления TreeView и просматривать список всех контактов в окне элемента управления ListBox (справа).

Рис. 14.22. В проекте AIIContacts в окне элемента управления TreeView (слева) выводится список (дерево) всех подпапок папки Contacts приложения Outlook

Исходный текст приложения

Программа, как всегда, начинается с описания переменных. Сначала объявля­ются следующие объектные переменные, используемые большинством процедур:


Public OutlookApp As outlook.Application

Public OlObjects As outlook.NameSpace

Public OlContacts.As outlook.MAPIFolder

Затем в событии Load формы введите следующие операторы для создания нового экземпляра Outlook и объектных переменных, необходимых для обращения к его папкам.

Программа 14.24. Создание объектной переменной Outlook

Private Sub Form Load()

Set OutlookApp = CreateObject ("Outlook.Application.8")

If Err Then

MsgBox "Could not create Outlook Application object!"

'(He удалось создать объект Outlook Application!)

End

End If

Set OlObjects = OutlookApp.GetNamespace("MAPI")

Set OlContacts = OlObjects.GetDefaultFolder(olFolderContacts)

If Err Then

MsgBox "Could not get MAPI NameSpace" , YbCritical

' (He удалось получить место расположения MAPI...)

End If

End Sub

Переменная

OutlookApp

представляет приложение. Переменная OlObjects - все папки, предоставленные Outlook, и переменная OlContacts -

папку Contacts. Эти переменные объявлены следующим образом:

Public OlObjects As outlook.NameSpace

Public OlContacts As outlook.MAPIFolder

Ядром приложения является обработчик события Click команды Populate Tree, который заполняет окно элемента управления TreeView с помощью рекурсивной процедуры.

Программа 14.25. Заполнение окна элемента управления TreeView

Private Sub Command1_Click ()

Dim allFolders As outlook.Folders

Dim Folder As outlook.MAPIFolder

Dim Folders As outlook.Folders

Dim thisPolder As outlook.MAPIFolder

Dim newNode As Node

' Добавление корневого узла

Set newNode = TreeViewl.Nodes.Add(, , OlContacts.EntryID, "Contacts")

newNode.Expanded =

True

' Получение списка подпапок в папке Contacts

Set allFolders = OlContacts.Folders

' Обработка отдельных подпапок в папке Contacts

For Each Folder In allFolders

Set newNode = TreeViewl.Nodes.Add(OlContacts.EntryID, _

tvwChild, Folder.Name, Folder.Name)

Set Folders = Folder.Folders

For Each thisFolder In Folders

Set newNode = TreeViewl.Nodes.Add(Folder.Name, _



tvwChild, thisFolder.EntryID,

thisFolder.Name)

newNode.Expanded = True

' теперь просматривается содержимое подпапок текущей папки

ScanSubFolders thisFolder

Next

Next

End Sub

Чтобы заполнить окно элемента управления TreeView, сначала добавляется корневой узел, который, в данном случае, является папкой Contacts. Этот узел не имеет родительского узла, а ключом для него является значение свойства Entry ID папки Contacts:

Set newNode = TreeViewl.Nodes.Add(, , OlContacts.EntryID, _

"Contacts")

newNode.Expanded = True

Как только узел добавлен, он дополняется таким образом, чтобы пользователь видел имена подпапок под ним и знак "плюс" перед их именами. Затем необхо­димо создать семейство allFolders,

которое содержит все подпапки папки Contacts:

Set allFolders = OlContacts.Folders

Цикл, приведенный в программе 14.26, просматривает каждый элемент этого семейства и добавляет имя текущей папки к содержимому окна элемента управления TreeView. Новый узел становится дочерним узлом узла Contacts, а его ключом является значение свойства EntryID родительского узла.

Затем следует создать другое семейство - Folders, содержащее подпапки текущей папки. Элементы этого семейства добавляются к содержимому окна элемента управления TreeView, после чего вызывается подпрограмма ScanSubFolders(), позво­ляющая просмотреть подпапки каждого элемента семейства. Код подпрограммы ScanSubFoldersO приведен ниже.

Программа 14.26.

Подпрограмма ScanSubFolders()

Sub ScanSubFolders(thisFolder As Object)

Dim subFolders As outlook.Folders

Dim subFolder As outlook.MAPIFolder

Set subFolders = thisFolder.Folders

If subFolders.Count <> 0 Then

strFolderKey = thisFolder.EntryID

For Each subFolder In subFolders

TreeViewl.Nodes.Add thisFolder.EntryID, _

tvwChild, subFolder.EntryID, subFolder.Name

ScanSubFolders subFolder

Next

End If

End Sub

Это очень простая программа (для рекурсивной процедуры, разумеется). Она позволяет создать семейство subFolders

подпапок текущей папки. Затем программа просматривает каждый элемент семейства, добавляет его имя к содержимому окна элемента управления TreeView и, при этом, выполняет этот просмотр рекурсивно. Это означает, что она вызывает сама себя, передавая в качестве параметра имя текущей папки.



Просмотр контактов папки

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

Это событие возвращает узел, на котором был выполнен щелчок, после чего можно получить ключ узла, который является ID выбранной папки. Как только стал известен ID выбранной папки, можно создать ссылку на эту папку (переменная thisFolder)

и использовать ее для просмотра содержащихся в ней элементов (т. е. контактов). Ниже приводится текст обработ­чика события NodeClick в окне элемента управления TreeView.

Программа 14.27. Получение списка содержимого выбранной папки

Private Sub TreeViewl NodeClick(ByVal Node As ComctlLib.Node)

Dim thisFolder As outlook.MAPIFolder

Dim contacts As outlook.Items

Dim Contact As outlook.Contactltem

On Error Resume Next

List1.Clear

Labell.Caption = "Selected Folder: " & Node.Text

' (Выбранная папка:...)

Set thisFolder = OlObjects.GetFolderFromID(Node.Key)

If Err Then

Exit Sub

Else

Set contacts = thisFolder.Items

For Each Contact In contacts

List1.AddItem Contact.LastName & ", " & _

   Contact.FirstName

Next

End If

End Sub

Программа позволяет отобразить только значения свойств

LastName и FirstName контакта. Пользователь может изменить программу, чтобы можно было отображать содержимое любых полей. Например, можно получать адрес электронной почты контакта и автоматически разослать по этим адресам сообщения (как это было сделано в предыдущем примере). Если эти примеры представляются вам интерес­ными, можете вставить фрагмент программы AlIContacts в проект Contacts.

Этим примером заканчивается введение в автоматизацию

OLE. Если добавить ссылки на различные Office-приложениям в пользовательских проектах, а затем открыть Object Browser, то можно обнаружить, что теперь они предоставляют много объектов, которые, в свою очередь, предоставляют многочисленные свойства и методы. Автоматизация Office-приложений с помощью VBA вполне по силам среднему программисту, и, кроме того. она предоставляет возможность ознако­миться с объектами, предоставляемыми Office-приложениями (или любыми другими приложениями, которые поддерживают VBA). После чтения этой главы читатель получит знания об основах программирования в VBA и понимание того обстоя­тельства, что программирование в VBA не многим отличается от программирования BVB6.



Глава 15 Конструирование компонентов ActiveX

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

• Конструирование модулей классов

• Реализация свойств и методов

• Инициирование событий из кода класса

• Создание и использование объектных переменных

• Регистрация компонентов ActiveX

• Обработка ошибок в классах

В предыдущей главе было показано, как установить связь с приложением-сервером и как управлять его работой с помощью объектов, которые оно предос­тавляет. В этой главе объясняется, как создавать свои собственные приложения-серверы или так называемые компоненты ActiveX. Компонент ActiveX — это общий термин, который относится к трем (в будущем, возможно, и более) типам проектов: ActiveX DLL, ActiveX EXE и элементам управления ActiveX. В этой главе мы познакомимся с конструированием программных компонентов

(ActiveX DLL и ActiveX EXE), которые являются приложениями-серверами, интерфейс которых состоит из свойств, методов и событий.

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

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

Другой категорией компонентов ActiveX являются документы ActiveX — это приложения, которые могут располагаться в таких контейнерах, как Internet Explorer и Office Binder. В этой книге мы не будем рассматривать документы ActiveX, которые, на самом деле, очень похожи на программные компоненты ActiveX и элементы управления ActiveX.


Реляционные связи


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

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

Примечание

Модель реляционной базы данных создана в 1970 году Коддом (E.F. Codd) из корпорации IBM, который разработал также язык запросов, впоследствии названный SQL.

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



Рисование на объекте


UserControl

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

Код вывода на экран видимого интерфейса элемента управления обычно помещается в событие Paint. Visual Basic инициирует это событие каждый раз, когда элемент управления должен быть перерисован. Таким образом, нужно добавить код, перерисовывающий элемент управления. Сейчас давайте скопируем процедуру DrawCaption(), разработанную ранее в этой главе, в элемент управления. Откройте окно объекта UserControl, в котором находится код элемента управления, и вставьте туда процедуру DrawCaption(). В обработчике события Paint объекта UserControl вставьте следующую строку, которая вызывает процедуру DrawCaptionQ:

DrawSubroutine

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

Процедура DrawCaption() рисует на объекте Form. Объект UserControl фактически идентичен объекту Form, поэтому может использовать те же самые методы рисования. Откройте окно кода объекта UserControl, вставьте код подпрограммы DrawCaption() и замените все вхождения "Me" на "UserControl", чтобы процедура рисовала на объекте UserControl.

Подпрограмма DrawCaption() должна также вызываться для перерисовки надпи­си всякий раз, когда изменяется какое-либо из специальных свойств элемента управления. Свойствами, которые влияют на вид выводимого текста наряду со стан­дартными свойствами Picture и BackColor, являются Caption, TextAlignment и Effect. Вставьте в коды этих свойств элемента управления процедуру Property Let со строкой, вызывающей событие UserControl_Paint. Доработанная процедура Property Let для свойства Effect показана ниже (подчеркнута вставленная строка).


Public Property Let Effect (ByVal New_Effect As Effects)

m_Effect = New_Effect

PropertyChanged "Effect"

UserControl Paint

End Property

Рисование на объекте UserControl идентично рисованию на объекте Form. Элементы управления, которые подобно элементу управления FLEXLabel рисуют свой видимый интерфейс и не полагаются на стандартные элементы управления, называются user-drawn

(нарисованные пользователем). Позже в главе будет показано, как строить специальные элементы управления на основе конституэнтных.

Попробуйте изменить свойство, определяющее цвет элемента управления FLEXLabel. Появится знакомое диалоговое окно, в котором можно выбрать или задать новый цвет. Заметьте, мы не предпринимали никаких мер для реализации этого свойства. Если посмотреть код элемента управления, можно заметить, что мастер объявил тип свойств Backcolor и ForeColor как OLE_COLOR. Когда Visual Basic видит тип OLE_COLOR, он знает, как обрабатывать соответствующие свойства в окне свойств.

Примечание

OLE_COLOR не является общим типом данных, который можно использовать в объявлениях обычных переменных Visual Basic, но он имеет определенный смысл. Он выводит диалоговое окно Color Selection (Выбор цвета) всякий раз, когда пользователь пробует устанавливать новое значение для свойства, определяющего цвет. Если определить тип свойств Backcolor или Forecolor как Long, то пользователь элемента управления для задания цвета должен будет вводить в окне свойств целое значение (например, HOOFFOO для зеленого цвета).


Сценарии для объектов


ActiveX

Наиболее мощное свойство элемента управления Script, позволяющее использовать его для написания сценариев приложения — это его способность манипулировать элементами управления ActiveX. Из примера, приведенного в предыдущем параграфе, видно, как создавать объектные переменные для доступа к OLE-серверу. Если приложение использует классы, то можно получить к ним доступ посредством элемента управления VBScript. Необходимо только создать экземпляр класса (или нескольких классов) и сохранить его в элементе управления Script. После этого свойства и методы будут доступны с помощью объектной переменной, как обычные команды VBScript.

С помощью метода AddObject

можно добавить объект к элементу управления Script.

ScriptControll.AddObject Name, Object, members

Первый аргумент — Name —

это имя для доступа к классу в сценарии. Это переменная типа String. Второй аргумент - Object - действительное имя класса. Допустим, приложение предоставляет класс DisplayClass. Для добавления этого класса к элементу управления Script надо создать объектную переменную

Private Display As New DisplayClass

и воспользоваться следующим оператором

ScriptControll.AddObject "Output", Display

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

Output.Show "some message"

' (некоторое сообщение)

(Метод Show выводит сообщение в нижний элемент управления TextBox формы.) Последний (необязательный) аргумент - members — это логическое значение, определяющее, будут ли доступны члены класса через объектную переменную. Если установить значение этого аргумента в True, то члены класса будут доступны по имени, как функции VBScnpt. Если добавить класс DisplayClass в элемент управления Script оператором

ScriptControll.AddOb]ect "Output", Display, True

то к методу Show можно обратиться из сценария без указания переменной имени объекта


Show "some message"

(некоторое сообщение)

VB6 в действии: класс Display

Одно из ограничений VBScnpt — он не поддерживает функций ввода/вывода. Так как VBScnpt — язык написания сценариев, то он по определению не поддер­живает пользовательский интерфейс. Если необходимо разработать приложение с визуальным интерфейсом, то используйте Visual Basic. Но во время проектирования, особенно на этапах отладки и тестирования, необходим способ отображения промежуточных результатов.

Форма проекта SEditor имеет окно, в котором сценарий помещает свой вывод (подобно временному окну). Эта особенность реализуется с помощью класса DisplayClass, имеющего два метода.

•  Show - для печати строки в нижнем элементе управления TextBox;

• Clear — для удаления содержимого нижнего элемента управления TextBox.

Реализация модуля класса DisplayClass требует всего нескольких строк кода.

Программа 20.9. Класс Display

Public Sub Show(message)

ScriptForm.Text2.Text = ScriptForm.Text2.Text _

& vbCrLf & message

End Sub

Public Sub Clear()

ScriptForm.Text2.Text = ""

End Sub

Для использования членов класса DisplayClass внутри сценария без регистрации Display DLL и создания объектной переменной с помощью функции CreateObject(), объект Display добавляется в элемент управления Script. Для этого необходимо добавить следующий оператор в событие Load формы.

Private Sub Form Load()

ScriptControll.AddObject "Output", Display, True

End Sub

Заметьте последний аргумент установлен в True, то есть Show и Clear доступны по имени.

Проект SEditor — простое приложение, позволяющее экспериментировать с VBScript. При разработке действительно сложных приложений, не требующих интенсивного ввода/вывода (не считая функции MsgBox() и метода Show), можно использовать и простой редактор. Однако на него нельзя рассчитывать, когда понадобится отобразить члены объектной переменной или проверить синтаксис.


Семейство


Documents u объект Document

Первым в иерархии объектов приложения Word является объект Document, представляющий любой документ, который можно открыть в Word, или иной документ, который можно отобразить в окне Word. Все открытые документы принадлежат семейству Documents (Документы), которое состоит из объектов Document. Подобно всем другим семействам, это семейство поддерживает свойство Count (Число открытых документов), метод Add (Добавить), с помощью которого можно добавить новый документ, и метод Remove (Удалить), который позволяет закрыть существующий документ. Чтобы обратиться к уже открытому документу, можно воспользоваться методом Item (Элемент) из семейства Documents (Документы), определив индекс документа следующим образом:

Application.Documents.Item(1)

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

Application.Documents.Item ("MasteringVB.doc")

Поскольку Item — это заданное по умолчанию свойство, то можно полностью опустить его имя:

Application.Documents(I)

Чтобы открыть существующий документ, можно воспользоваться методом Open (Открыть) семейства Documents (Документы):

Documents.Open(fileName)

Параметр

fileName — это путь и имя файла документа.

Для создания нового документа, следует воспользоваться методом Add семей­ства Documents (Документы), который принимает два необязательных параметра:

Documents.Add(template, newTemplate)

Параметр

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

является значением типа Boolean. Если он имеет значение True, Word создаст новый файл шаблона.

Большинство выполняемых операций воздействуют на активный документ (документ в активном окне Word), который представляется объектом ActiveDocument, являющийся свойством объекта Application. Чтобы обращаться к выделенному тексту в активном документе, следует воспользоваться следующим выражением:

Application ActiveDocument.Selection

Можно сделать активным любой документ, вызвав метод Activate (Активизи­ровать) объекта Document. Чтобы сделать документ My Notes doc активным, можно воспользоваться следующим оператором:

Documents ("MyNotes doc"). Activate

После выполнения этого оператора документ MyNotes doc становится активным, и программа может обращаться к нему по имени Application ActiveDocument


Worksheets и объект Worksheet

Каждая рабочая книга в Excel может содержать один или несколько рабочих листов. Коллекция Worksheets, подобная коллекции Documents в Word, содержит объект Worksheet

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

Application.Worksheets.Add(before, after, count, type)

Параметры

before и after позволяют определить расположение нового рабочего листа в рабочей книге. Можно определить только один из двух параметров. Если опустить оба параметра, то новый рабочий лист будет вставлен перед активным рабочим листом (и станет активным). Параметр type определяет тип нового рабочего листа и может иметь одно из следующих значений.

•   xlWorksheet. Значение, установленное по умолчанию.

•   xIExcel4MacroSheet. Рабочий лист, содержащий макросы Excel 4.

•   xlExcel4lntlMacroSheet. Рабочий лист, содержащий международные макросы Excel 4. Чтобы обратиться к рабочему листу, следует воспользоваться методом Item коллекции Worksheets, передавая в качестве параметра индекс или имя рабочего листа. Если второй рабочий лист называется SalesData.xIs, то следующие выражения эквивалентны:

Application.Worksheets.Item(2)

и

Application.Worksheets.Item ("Sales Data.xls")

Поскольку Item — это установленное по умолчанию свойство коллекции, имя его можно полностью опустить:

Application.Worksheets (2)

Объекты, предоставляющие доступ к ячейкам

Excel - это приложение, которое предназначено для обработки информации хранящейся в ячейках. Но основным объектом, используемым для организации доступа к содержимому рабочего листа, является объект Range, являющийся свой­ством объекта Worksheet. Имеются несколько способов идентификации объекта Range, но ниже приведено каноническое его описание:

Worksheet.Range(celll:се112)

Где cell1 и сеll2

—адреса двух ячеек, которые определяют прямоугольную область на рабочем листе. Это адреса левой верхней и правой нижней ячеек блока. В этом параграфе будет использована стандартная нотация Excel, в которой число опреде­ляет строку, а буква - столбец, например, СЗ или А103. Чтобы выбрать блок ячеек размером 10 х 10, занимающий левый верхний угол активного рабочего листа, следует воспользоваться выражением:




Files

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

Set ThisFolder = FSys.GetFolder(folderName)

Set AllFiles = ThisFolder.Files

For Each file in AllFiles

{обработка текущего файла}

Next

Внутри тела цикла предоставляется доступ к свойствам текущего файла. Его имя - это file. Name, дата создания - file.DateCreated и т.д. В следующих параграфах перечислены свойства и методы объекта File.




Folders

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

Set FSys = CrateObject ("Scripting. FileSystemObject")

Set ThisFolder =

FSys.GetFolder(folderName)

Set AllFolders = ThisFolder.SubFolders

For Each folder in AllFolders

{обработка текущей папки}

Next

В теле цикла доступны свойства текущей папки. Ее имя – folder.Name, дата создания — folder. DateCreated и т.д.

Свойства объекта Folder описаны ниже. Рассмотрим метод AddFolder - един­ственный метод объекта Folder.

AddFolder. Этот метод добавляет новый объект Folder в семейство. Его синтаксис имеет вид:

FolderObject.AddFolders folderName

где

folderName - это имя новой добавляемой папки.

Объект Folder

Этот объект представляет папку на диске. Он позволяет манипулировать реальными папками на диске с помощью своих методов и свойств. Чтобы создать объект Folder, сначала создается объектная переменная типа FileSystem Object, а затем — вызывается ее метод GetFolder, которому в качестве аргумента передается путь к папке.

Set FSys = CreateObject ("Scripting.FileSystemObject")

Set thisFolder = FSys.GetFolder("c: \windows\desktop")

Теперь переменная thisFolder

задает папку c:\windows\desktop, и вы можете работать с ней, используя свойства и объекты переменной. Кратко опишем свойства объекта Folder.

Attributes.

Возвращает или устанавливает атрибуты файлов или папок. Подробно описано в параграфе свойств объекта File.

DateCreated.

Возвращает дату и время создания указанного файла или папки ("только для чтения").

DateLastAccessed, DateLastModified.

Возвращают дату и время последнего доступа/модификации файла или папки ("только для чтения").

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

ParentFolder.

Возвращает родительскую папку объекта Folder. Используется в примере свойства IsRootFolder.




Subfolders

Свойство Subfolders возвращает семейство Subfolders, содержащее все подпапки данной папки. Чтобы получить семейство Subfolders папки "C:\WINDOWS", создайте переменную FileSystem Object, воспользуйтесь методом GetFolder для получения ссылки на указанную папку, а затем создайте семейство ее подпапок, используя свойство SubFolders.

Set FSys =

CreateObject ("Scripting.FileSystemObject")

Set thisFolder = FSys.GetFolder ("c:\windows")

Set allFolders = aFolder.SubFolders

For Each subFolder in allFolders

{обработка папки subFolder}

Next

Чтобы отсканировать подпапки указанной папки, используйте оператор For Each...Next, как показано выше. Имя текущей папки в теле цикла - subFolder.Name.

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




Environment

Свойство Environment возвращает семейство переменных среды. Для обработки этих переменных создается объект Shell и обрабатывается семейство Environment.

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

Set AllVars = WShell.Environment

For Each evar In AllVars

txt = txt & evar & vbCrLf

Next

MsgBox txt

Переменная

evar задает переменные среды в этой форме.

Variable =

setting

Результат работы ENWARS.VBS показан на рис. 20.11. Для доступа к опреде­ленным переменным среды используется объект Environment, описанный ниже.

Рис. 20.11. Сценарий ENWARS.VBS отображает имена и значения переменных среды

Переменные, возвращаемые методом Environment, по умолчанию — переменные среды PROCESS. Это встроенные переменные, такие как WinDir или WinBootDir, и переменные, созданные командой SET (команда DOS, встречающаяся несколько раз в файле AUTOEXEC.BAT). Эти переменные перечислены в табл. 20.6 (некоторые из них могут отсутствовать в системе). Можно передать аргумент методу Environment, который укажет, какой набор переменных возвращать. Windows NT поддерживает несколько наборов переменных среды. Windows 98 — только наборы PROCESS и VOLATILE. Сценарий может использовать набор VOLATILE для обмена с другими сценариями или динамически создавать и удалять эти переменные.

Семейство SpecialFolders

Свойство SpecialFolders предоставляет доступ к специальным папкам системы. Специальные папки включают папку Desktop (Рабочий стол), папку Start-меню и папку с персональными документами.

Примечание

Свойство SpecialFolders возвращает путь к папке Desktop (Рабочий стол), а не объект Folder. Для доступа к файлам и подпапкам этой папки необходимо создать экземпляр объекта Folder с помощью метода GetFolder объекта FileSystemObject, как показано в следующем примере.

Семейство SpecialFolders используется для создания новых ярлыков на Рабочем столе или помещения новых приложений в меню Пуск. Следующий пример выводит список всех файлов, имеющихся в папке DeskTop, и их типы. Для просмотра файлов этот сценарий (DTOP.VBS на компакт-диске) использует объект FileSystemObject.



Скелет элемента управления ActiveX


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

Программа 16.2. ActiveX Control

Private m_Caption As String

Private m_Effect As Integer

Private m TextAlignment As Integer

' Значения свойств по умолчанию:

Const m_def_Caption = "3D Label"

Const m_def_Effect = 2

Const m_def_TextAlignment = 4

' Переменные свойств:

' Объявления событий:

Event DblClick()

Event Click()

Event KeyUp(KeyCode As Integer, Shift As Integer)

Event KeyPress(KeyAscii As Integer)

Event KeyDown(KeyCode As Integer, Shift As Integer)

Event MouseUp(Button As Integer, Shift As Integer, X As Single, _

Y As Single)

Event MouseMove(Button As Integer, Shift As Integer, X As Single, _

     Y As Single)

Event OLEStartDrag(Data As DataObject, AllowedEffects As Long)

Event OLESetData(Data As DataObject, DataFormat As Integer)

Event OLEGiveFeedback(Effect As Long, DefaultCursors As    Boolean)

Event OLEDragOver(Data As DataObject, Effect As Long, _

     Button As Integer, Shift As Integer, X As Single, _

     Y As Single, State As Integer)

Event OLEDragDrop(Data As DataObject, Effect As Long, _

Button As Integer, Shift As Integer, X As Single, _

Y As Single)

Event Resize ()

Public Property Get Font() As Font

Set Font = UserControl.Font

End Property

Public Property Set Font(ByVal New_Font As Font)

Set UserControl.Font = New_Font

PropertyChanged "Font"

End Property

Public Property Get BorderStyle() As Integer

BorderStyle = UserControl.BorderStyle

End Property

Public Property Let BorderStyle(ByVal New_BorderStyle As Integer)

UserControl.BorderStyle() = New_BorderStyle

PropertyChanged "BorderStyle"

End Property

Public Property Get BackStyle() As BackgroundStyle


BackStyle = UserControl.BackStyle

End Property

Public Property Let BackStyle(ByVal New_BackStyle As _

BackgroundStyle)

UserControl.BackStyle() = New_BackStyle

PropertyChanged "BackStyle"

End Property

Public Property Get Appearance () As Integer

Appearance = UserControl.Appearance

End Property

Private Sub UserControl_DblClick()

RaiseEvent DblClick

End Sub

Private Sub UserControl_Click()

RaiseEvent Click

End Sub

Public Property Get Enabled() As Boolean

Enabled = UserControl.Enabled

End Property

Public Property Let Enabled(ByVal New_Enabled As Boolean)

UserControl.Enabled() = New_Enabled

PropertyChanged "Enabled"

End Property

Public Property Get ForeColor() As OLE_COLOR

ForeColor = UserControl.ForeColor

End Property

Public Property Let ForeColor(ByVal New_ForeColor As OLE_COLOR)

UserControl.ForeColor() = New ForeColor

PropertyChanged "ForeColor"

End Property

Public Property Get hDC() As Long

hDC = UserControl.hDC

End Property

Public Property Get hWnd() As Long

hWnd = UserControl.hWnd

End Property

Private Sub UserControl_KeyUp( KeyCode As Integer, Shift As Integer)

RaiseEvent KeyUp(KeyCode, Shift)

End Sub

Private Sub UserControl_Keypress(KeyAscii As Integer)

RaiseEvent Keypress(KeyAscii)

End Sub

Private Sub UserControl_KeyDown(KeyCode As Integer, Shift As Integer)

RaiseEvent KeyDown(KeyCode, Shift)

End Sub

Private Sub UserControl_MouseUp(Button As Integer, Shift As Integer, _

X As Single, Y As Single)

RaiseEvent MouseUp(Button, Shift, X, Y)

End Sub

Public Property Get MousePointer() As Integer

MousePointer = UserControl.MousePointer

End Property

Public Property Let MousePointer(ByVal New_MousePointer As Integer)

UserControl.MousePointer() = New_MousePointer

PropertyChanged "MousePointer"

End Property

Private Sub UserControl_MouseMove(Button As Integer, Shift As Integer,     _



X As Single, Y As Single)

RaiseEvent MouseMove(Button, Shift, X, Y)

End Sub

Private Sub UserControl_OLEStartDrag(Data As Data0bject, _

AllowedEffects As Long)

RaiseEvent OLEStartDrag(Data, AllowedEffects)

End Sub

Private Sub UserControl_OLESetData(Data As DataObject, _

DataFormat As Integer)

RaiseEvent OLESetData(Data, DataFormat)

End Sub

Private Sub UserControl_OLEGiveFeedback(Effect As Long, _

DefaultCursors As Boolean)

RaiseEvent OLEGiveFeedback(Effect, DefaultCursors)

End Sub

Public Property Get OLEDropMode() As Integer

OLEDropMode = UserControl.OLEDropMode

End Property

Public Property Let OLEDropMode(ByVal New_OLEDropMode As Integer)

UserControl.OLEDropMode() = New_OLEDropMode

PropertyChanged "OLEDropMode"

End Property

Private Sub UserControl_OLEDragOver(Data As DataObject, _

Effect As Long, Button As Integer, Shift As Integer, _

X As Single, Y As Single, State As Integer)

RaiseEvent OLEDragOver(Data, Effect, Button, Shift, X, Y, State)

End Sub

Private Sub UserControl_OLEDragDrop(Data As Data0b]ect, Effect As    Long, _

Button As Integer, Shift As Integer, X As Single, _

Y As Single)

RaiseEvent OLEDragDrop(Data, Effect, Button, Shift, X, Y)

End Sub

Public Sub OLEDrag()

UserControl.OLEDrag

End Sub

Public Property Get Picture() As Picture

Set Picture = UserControl.Picture

End Property

Public Property Set Picture(ByVal New Picture As     Picture)

Set UserControl.Picture = New_Picture

PropertyChanged "Picture"

End Property

Private Sub UserControl_Resize ()

RaiseEvent Resize

End Sub

Public Property Get Caption() As String

Caption = m_Caption

End Property

Public Property Let Caption(ByVal New_Caption As     String)

m_Caption = New Caption

PropertyChanged "Caption"

End Property

Public Property Get Effect() As Integer

Effect = m_Effect

End Property

Public Property Let Effect(ByVal New_Effect As Integer)



m_Effect = New_Effect

PropertyChanged "Effect"

End Property

Public Property Get TextAlignment() As Integer

TextAlignment = m_TextAlignment

End Property

Public Property Let TextAlignment(ByVal New_TextAlignment As Integer)

m_TextAlignment = New_TextAlignment

PropertyChanged "TextAlignment"

End Property

' Инициализация свойств

Private Sub UserControl_InitProperties()

Set Font = Ambient.Font

m­_Caption = m_def_Caption

m_Effect = m_def_Effect

m_TextAlignment = m_def_TextAlignment

UserControl.BorderStyle = 1

UserControl.BackStyle = 1

End Sub

' Загрузка значений свойств

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)

Set Font = PropBag.ReadProperty("Font",Ambient.Font)

UserControl.BorderStyle = PropBag.ReadProperty ("BorderStyle", 0)

UserControl.BackStyle = PropBag.ReadProperty ("BackStyle", 1)

UserControl.Enabled = PropBag.ReadProperty ("Enabled", True)

UserControl.ForeColor = PropBag.ReadProperty ("ForeColor", _

   &H80000012)

UserControl.MousePointer = PropBag.ReadProperty ("MousePointer", 0)

UserControl.OLEDropMode = PropBag.ReadProperty ("OLEDropMode", 0)

Set Picture = PropBag.ReadProperty ("Picture", Nothing)

m_Caption = PropBag.ReadProperty ("Caption", m_def_Caption)

m_Effect = PropBag.ReadProperty ("Effect", m_def_Effect)

m_TextAlignment = PropBag.ReadProperty ("TextAlignment", _

  m_def_TextAlignment)

UserControl.BackColor = PropBag.ReadProperty ("BackColor", _

  SH8000000F)

End Sub

' Сохранение значений свойств

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)

Call PropBag.WriteProperty("Font", Font, Ambient.Font)

Call PropBag. WriteProperty("BorderStyle",

UserControl.BorderStyle,0)

Call PropBag.WriteProperty("BackStyle", UserControl.BackStyle, 1)

Call PropBag.WriteProperty("Enabled", UserControl.Enabled, True) Call PropBag.WriteProperty ("ForeColor", UserControl.ForeColor, _



&H80000012)

Call PropBag. WriteProperty ("MousePointer", _

UserControl.MousePointer, 0)

Call PropBag. WriteProperty ("OLEDropMode", _

UserControl.OLEDropMode, 0)

Call PropBag.WriteProperty("Picture", Picture, Nothing)

Call PropBag. WriteProperty ("Caption", m_Caption, _

m_def_Caption)

Call PropBag.WriteProperty("Effect", m_Effect,

m_def_Effect)

Call PropBag. WriteProperty ("TextAlignment", _

m_TextAlignment, m_def_TextAlignment)

Call PropBag.WriteProperty ("BackColor", _

UserControl.BackColor, &H8000000F)

End Sub

' ВНИМАНИЕ! НЕ УДАЛЯЙТЕ И НЕ ИЗМЕНЯЙТЕ

' СЛЕДУЮЩУЮ ЗАКОММЕНТИРОВАННУЮ СТРОКУ

' MappingInfo=UserControl,UserControl,-1,BackColor

Public Property Get BackColor() As OLE_COLOR

BackColor = UserControl.BackColor

End Property

Public Property Let BackColor(ByVal New_BackColor As OLE_COLOR)

UserControl.BackColor() = New_BackColor

PropertyChanged "BackColor"

End Property

Программа довольно длинная, но не так сложна, как выглядит. Рассмотрим каждый раздел кода подробно, начиная с раздела объявлений.

Option Explicit

' Значения свойств по умолчанию

Private m_Caption As String

Private m_Effect As Integer

Private m_TextAlignment As Integer

Эти переменные содержат значения специальных свойств элемента управ­ления. Свойства элемента управления отображены на закрытые переменные кода элемента управления. Как и в случае с компонентом ActiveX, чьи свойства доступны извне, эти свойства являются, фактически, простыми переменными. Позже будет видно, как элемент управления получает значение, введенное пользователем в окне свойств (или код во время выполнения), и связывает их с закрытыми переменными. (Вспомните манипулирование свойствами OLE-сервера с помощью процедур Property Let и Property Get, рассмотренное в предыдущей главе. Тот же самый подход работает и с элементами управления ActiveX, но об этом позже.).

Дальше следуют определения нескольких констант, которые соответствуют значениям определенным в окне Set Attributes мастера. Эти константы будут исполь­зоваться дальше в коде как начальные значения для различных свойств. Учтите, что нет необходимости запускать мастер для того, чтобы просто поменять эти значения. Можно отредактировать код элемента управления. Обратите также внимание имена констант основаны на именах свойств, и код можно легко редактировать.



' Значения свойств по умолчанию:

Const m_def_Caption = "3D Label"

Const m_def_Effect = 2

Const m_def_TextAlignment =  4

Дальше следуют объявления событий. Это события, которые были определены в первых двух окнах мастера и отображены на объект UserControl. Щелчок на элементе управления генерирует событие Click, которое передается приложению, как будто оно было сгенерировано самим элементом управления ActiveX. В списке определено несколько больше событий, но нет нужды повторяться.

' Объявления событий:

Event DblCllck()

Event Click()

Event KeyUp(KeyCode As Integer, Shift As Integer)

Event Keypress(KeyAscii As Integer)

Event KeyDown(KeyCode As Integer, Shift As Integer)

Event MouseUp(Button As Integer, Shift As Integer,

X As Single, Y As Single)

Event MouseMove(Button As Integer, Shift As Integer, _

X As Single, Y As Single)

Примечание

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

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

Установка и чтение значений свойств

Теперь рассмотрим несколько подпрограмм: по две для каждого свойства.

Программа 16.3. Процедуры свойства Caption

Public Property Get Caption() As String

Caption =

m_Caption

End Property

Public Property Let Caption(ByVal New Caption As String)

m_Caption = New Caption

PropertyChanged "Caption"

End Property

Каждое свойство определено двумя Public-процедурами:

•   Property Let,

•   Property Get.

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



Процедура Property Get вызывается всякий раз, когда программа обращается к значению свойства. Эта процедура читает значение закрытой переменной m_Caption и присваивает его свойству Caption. Для каждого свойства должны быть определены процедуры Property Get и Property Let, включающие приведенные строки. Они составляют минимальный механизм для установки или чтения значений свойств.

Конечно, в эти процедуры можно добавлять и код проверки допустимости значений. Значение свойства TextAlignmen должно быть в диапазоне от 0 до 9. На данный момент элемент управления позволяет пользователю ввести любое значение этого свойства в окне свойств. Добавим проверку допустимости значения в проце­дуру Property Let для свойства TextAlignment. Сам код прост: он отвергает любые значения меньше 0 и больше 8.

Программа 16.4. Код проверки допустимости свойства TextAlignment в процедуре Property Let

Public Property Let TextAlignment(ByVal New_TextAlignment As _

Integer)

If m_TextAlignment >=0 And m_TextAlignitient<=8 Then

   m_TextAlignment = New_TextAlignment

PropertyChanged "TextAlignment"

Else

MsgBox "Invalid value for this property"

  ' (Недопустимое значение для этого свойства)

End If

End Property

Оператор If проверяет допустимость введенного значения, и, если новое значение находится вне допустимого диапазона, попытка изменить свойство отклоняется. Измените процедуру Property Let согласно приведенной схеме и затем переключитесь на тестовую форму проекта. Выберите элемент управления FLEXLabel на форме, откройте окно свойств и установите свойство TextAlignment в заведомо недопустимое значение (13 или 1000, например). При попытке изменить свойство, установив его в недопустимое значение, элемент управления выдаст предупреждение и отклонит изменения. Пока не совсем понятно, как добиться, чтобы допустимые значения свойства отображались в раскрывающемся списке, как в других элементах управления VB? Это требует написания еще небольшого ко­личества кода, о чем чуть позже.



После процедур Property Let и Property Get

для всех свойств идет код инициа­лизации некоторых переменных.

Программа 16.5. Код инициализации

' Инициализация свойств элемента управления

Private Sub UserControl_InitProperties ()

Set Font = Ambient.Font

m_Caption = m_def_Caption

m_Effect = m_def_Effect

m_TextAlignment = m_def_TextAlignment

UserControl.BorderStyle = 1

UserControl.BackStyle = 1

End Sub

Операторы подпрограммы InitProperties() присваивают начальные значения закрытым переменным, которые представляют свойства элемента управления. Константы m_def_Caption, m_def_TextAlignment и m_def_Effect были определены ранее в программе. При помещении этого элемента управления на форму Visual Basic читает значения переменных m_Caption, m_TextAlignment и m_Effect и выво­дит их в соответствующих строках окна свойств элемента.

Сохранение и чтение значений свойств

Далее в тексте идут две интересные подпрограммы:

•  ReadProperties;

•   WriteProperties.

При изменении каких-либо свойств через окно свойств новые значения должны быть где-то сохранены. Зачем?

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

Visual Basic предусматривает специальный объект для сохранения всех значений свойств - PropertyBag. Этот объект предусматривает два метода: один - для сохранения значения свойства, другой - для его чтения. Разработчику элемента управления необязательно знать все подробности сохранения значений. Visual Basic сохраняет значения свойств и при запросе предоставляет их.

Первый метод имеет следующий синтаксис:

WriteProperty propertyName, value, defaultValue

где

propertyName - имя свойства (например, Effect), value

может иметь буквальное значение(1 или "some sizzling effect"), но почти всегда - это имя закрытой пере­менной, которая содержит значение свойства, defaultValue - значение свойства по умолчанию.



Примечание

Зачем нужно указывать одновременно и собственно значение и значение по умолчанию при вызове метода? Дело в том, что VB сравнивает эти два параметра, и, если значения совпадают, то VB не выполняет сохранение (для ускорения процесса сохранения и восстановления значений свойства). При последующем запросе значения свойства с помощью метода ReadProperty Visual Basic просто возвращает значение по умолчанию.

Метод ReadProperty имеет следующий синтаксис:

ReadProperty propertyName, defaultValue

где propertyName — имя свойства, defaultValue — значение этого свойства, сохраненное ранее в объекте PropertyBag. В коде события Write Properties объекта UserControl необходимо вызвать метод WriteProperty для каждого из свойств. Аналогично, в коде процедуры ReadProperties для каждого свойства необходимо вызвать метод ReadProperty. Ниже приведен код процедур Write Properties и ReadProperties сгене­рированный мастером для элемента управления FLEXLabel.

Программа 16.6. Процедура ReadProperties элемента управления

' Загрузка значений свойств

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)

Set Font == PropBag.ReadProperty("Font", Ambient.Font)

UserControl.BorderStyle = PropBag.ReadProperty ("BorderStyle", 0)

UserControl.BackStyle = PropBag.ReadProperty ("BackStyle", 1)

UserControl.Enabled = PropBag.ReadProperty("Enabled", True)

UserControl.ForeColor = PropBag.ReadProperty ("ForeColor", _

&H80000012)

UserControl.MousePointer = PropBag.ReadProperty ("MousePointer", 0)

UserControl.OLEDropMode = PropBag.ReadProperty ("OLEDropMode", 0)

Set Picture = PropBag.ReadProperty ("Picture", Nothing)

m_Caption = PropBag.ReadProperty("Caption", m_def_Caption)

m_Effect = PropBag.ReadProperty("Effect", m_def_Effect)

m_TextAlignment = PropBag.ReadProperty ("TextAlignment", _

m_def_TextAlignment)

UserControl.BackColor = PropBag.ReadProperty ("BackColor", _



&H8000000F)

End Sub

Программа 16.7. Процедура WriteProperties элемента управления

' Сохранение значений свойств

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)

   Call PropBag.WriteProperty("Font", Font, Ambient.Font)

   Call PropBag.WriteProperty ("BorderStyle", UserControl.BorderStyle, 0)

   Call PropBag.WriteProperty("BackStyle", UserControl.BackStyle, 1)

   Call PropBag.WriteProperty("Enabled", UserControl.Enabled, True)

   Call PropBag.WriteProperty("ForeCoior", UserControl.ForeColor, _

&H80000012)

   Call PropBag.WriteProperty ("MousePointer", _

UserControl.MousePointer, 0)

   Call PropBag.WriteProperty ("OLEDropMode", _

UserControl.OLEDropMode, 0)

   Call PropBag.WriteProperty ("Picture", Picture, Nothing)

   Call PropBag.WriteProperty("Caption", m_Caption, m_def_Caption)

   Call PropBag.WriteProperty("Effect", m_Effect, m_def_Effect)

   Call PropBag. WriteProperty ("TextAlignment", _

m_TextAlignment, m_def_TextAlignment)

   Call PropBag.WriteProperty ("BackColor", _

UserControl.BackColor, &H8000000F)

End Sub

Передача событий

Последний раздел кода отображает различные события элемента управления на эквивалентные события объекта UserControl. Когда пользователь щелкает мышью на элементе управления ActiveX, Windows отправляет событие Click объекту UserControl. Разработчик элемента управления может обработать это событие в самом элементе управления (в этом случае приложение, которое использует элемент, не видит события Click), или передать событие приложению-контейнеру (в этом случае разработчик приложения, использующего элемент управления, сможет обработать сообщение), или сделать и то, и другое (сначала обработать событие в элементе управления, а затем передать его контейнеру).

Передать событие приложению можно с помощью метода

RaiseEvent. Событие Click объекта UserControl определено таким образом.

Private Sub UserControl_Click()

RaiseEvent Click

End Sub

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

Все, что сделал мастер — это вставил достаточно простой код. За исключением методов ReadProperty и WriteProperty, все остальное должно быть более или менее знакомо большинству программистов на Visual Basic. ActiveX — элемент управления, следовательно, не намного сложнее по сравнению со стандартным проектом. Осталось добавить еще несколько строк кода. В конце концов, необходимо указать элементу управления, как выравнивать надпись и обрисовывать ее с трехмерным эффектом.


Смешанные серверные и клиентские сценарии


ASP-файл может содержать текст как серверного, так и клиентского сценария. Если вы хотите включить раздел сценария в Web-страницу, то поместите команды сценария между тегами <SCRIPT>. На рис. 22.4 показан вывод другого ASP-файла, являющегося вариантом сценария для вывода даты и времени сервера на экране клиента. Страница TIMESRVR.ASP выводит время клиента с помощью клиентского сценария и время сервера с помощью серверного сценария. Если сервер и клиент находятся в разных часовых поясах, то разница между временем сервера и клиента составит целое число часов и несколько секунд, необходимых для передачи HTML-кода клиенту.

Рассмотрим листинг файла TIMESRVR.ASP. Обратите внимание: клиентский сценарий размещен между тегами <SCRIPT>, как на обычной HTML-странице. Серверный сценарий, вообще говоря, не является сценарием — это просто вызов функции Time(). Однако в пару тегов <% и %> можно поместить столько операторов, сколько необходимо.

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

Рис. 22.4. Страница TIMESRVR.ASP: серверный и клиентский сценарии — время сервера и время клиента.

Программа 22.3. Страница TIMESRVR.ASP

<HTML>

<BODY>

<% theTime = Time %>

<% theDate = Date %>

<FONT FACE-VERDANA SIZE=3>

<Hl>Server's Local Time</Hl>

<BR><BR>

The time at the server's location is <% = theTime %>

<BR>

and the date is <% = theDate %>

<P>

<HR>

<Hl>Clitent's Local Time</Hl>

SCRIPT LANGUAGE = VBScript>

Document.write "The local time is " & Time

Document.write "<BR>"

Document.write "and the date time is " & Date

Document.write "<HR>"

Document.write "The time difference is " & DateDiff ("s", "<% - theTime

%>", Time) & " second(s)"

Document.close

</SCRIPT>

</BODY>

</HTML>

Также рассмотрим разработку серверных сценариев: чтение данных, поступающих от клиента, их обработку на сервере (в большинстве случаев для этого используются элементы управления ActiveX, расположенные на сервере) и построение Web-страниц в реальном времени для передачи их обратно клиенту. Независимо от типа сервера этот процесс требует использования Си-подобного программирования. Однако при использовании ASP и встроенных объектов задачи, которые обычно требуют применения Peri или C++, разрешимы средствами VBScript.

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

Database (База данных)), позволяющие сценарию получить доступ к базам данных на сервере.



Проверку правильности вводимых данных выполняет


Validate
Проверку правильности вводимых данных выполняет событие
Validate элемента управления Data. Объявим это событие.
Private Sub object_Validate (action As Integer, save As Integer)
Параметр
action (действие) — это целое число, задающее операцию, выполнение которой вызывает данное событие. Его значения приведены в табл. 17.7.
Таблица 17.7. Значения параметра action (действие) события Validate

Константа
Значение
Описание
vbDataActionCancel
0
Отмена операции при выходе из процедуры
vbDataAction Move First
1
Метод MoveFirst (Перейти к первой записи)
vbDataActionMovePrevious
2
Метод MovePrevious (Перейти к предыдущей записи)
vbDataActionMoveNext
3
Метод MoveNext (Перейти к следующей записи)
vbDataActionMoveLast
4
Метод Move Last (Перейти к последней записи)
vbDataActionAddNew
5
Метод AddNew (Добавить новую запись)
vbDataAction Update
6
Операция обновления (не LfpdateRecord)
vb DataAction Delete
7
Метод Delete (Удалить)
vb DataAction Find
8
Метод Find (Найти)
vbDataAction Bookmark
9
Установлено свойство
Bookmark (Закладка)
vb DataActionClose
10
Метод Close (Закрыть)
vbDataActionUnload
11
Выгрузка формы из памяти

Чтобы отменить операцию,  вызвавшую событие Validate,  значение vbDataActionCancel может устанавливаться с помощью кода. Например, если поль­зователь изменяет данные в элементе управления, а затем щелкает на кнопке MoveNext, то можно отменить изменения и операцию MoveNext.
Параметр
save (сохранить) — это выражение типа Boolean, указывающее, изменялись ли данные. Можно установить его значение в False, чтобы отменить изменения.


Error
Другим полезным событием при проверке правильности данных является событие Error (Ошибка). Когда модифицируется запись в базе данных, механизм JET гарантирует, что введенные данные не противоречат правилам, определенным при проектировании базы данных. Например, если требуется, чтобы указанное поле было уникальным, то запись не будет модифицирована, если введенное зна­чение уже использовалось. Если поле превышает максимальную длину, изменения будут также отклонены. Другими словами, механизм JET производит проверку данных самостоятельно. Он также выполняет проверку данных в соответствии с правилами, определенными в поле Validation Rule.
Если данные не удовлетворяют правилам, определенным в проекте базы данных, то генерируется ошибка выполнения программы. Перед сообщением об ошибке генерируется событие Error. Можно выявить причину ошибки, вызвав ее обработчик.
Объявим событие Error.
Sub Error (dataerr As Integer, response As Integer)
Параметр
dataerr (данные об ошибке) — номер ошибки, a response
(отклик) — целое число, которое устанавливается при появлении события, чтобы затем в обработчике ошибки выполнить соответствующие действия. Значения параметра response
перечислены в табл. 17.8. Ошибку необходимо обработать внутри процедуры Error и затем установить параметр response в 0, чтобы предотвратить генерирование ошибки выполнения программы.
Таблица 17.8. Значения параметра Response события Error

Константа
Значение
Описание
vbDataErrContinue vbDataErrDisplay
0
1
Продолжать выполнение
Отображение сообщения об ошибке (установлена по умолчанию)

и Application поддерживают события Start


Start и End
Объекты Session и Application поддерживают события Start (Начать) и End (Завершить), которые сигнализируют о начале и завершении сеанса и приложения соответственно. Эти события имеют следующий вид:
•  Scssion_OnStart
•  Application_OnStart
•  Session_OnEnd
• Application_OnEnd
Обработчики этих событий содержат код, который выполняется, когда приложение или сеанс стартуют и завершаются. Если приложение запускается одновременно с началом сеанса, то первым происходит событие Application_OnStart. Оба эти события важны при разработки ASP-приложсний. К сожалению, они недоступны из кода сценария. Их обработчики следует поместить в файл GLOBAL.ASA, который находится в корневой папке приложения (в ней находится первый ASP-файл, запрошенный клиентом). Обычно файл GLOBAL.ASA содержит обработчики событий Start и End объектов Session и Application, а также объявления переменных.
Например, если нужна переменная для хранения количества пользователей, подключенных к вашему узлу, то ее нужно инициализировать в обработчике события Application_OnStart. Для этого введите в файл GLOBAL.ASA следующие строки.
<SCRIPT LANGUAGE=VBScript RUNAT=Server>
Sub Application_OnStart
Application ("Visitors") = 0
End Sub
</SCRIPT>
Это событие происходит каждый раз, когда запускается программное обеспечение сервера. Поскольку разумнее не инициализировать переменную при каждом рестарте сервера, сохраните значение переменой Visitors в текстовом файле на диске сервера, как показано в гл. 20. Теперь можно в обработчике события Application_0n Start читать значение этой переменной и увеличивать его на 1 в обработчике события Session_OnStart.
<SCRIPT LANGUAGE=VBScript RUNAT=Server> Sub Session_OnStart
Application.Lock
Application ("Visitors") = Application ("Visitors") + 1
Application.Unlock
End Sub
</SCRIPT>
Эту процедуру также следует поместить в файл
GLOBAL.ASA. При таком подходе значение счетчика не увеличивается, когда пользователь обращается к начальной странице в течение одного сеанса, поскольку событие Session_OnStart происходит только при первом обращении к начальной странице.


Отображение счетчика в какой- либо оригинальной форме является отдельной задачей. Пока можно просто выводить его значение шрифтом большого размера или генерировать GIF-файл и отображать его на стартовой странице. Элемент управления Structured Graphics, поставляемый с Internet Explorer 4.0, позволяет создавать достаточно сложные изображения несколькими строками кода. Исполь­зование этого элемента — простейший способ красочного отображения счетчика пользователей.
Если ваши Web-страницы во время сеанса часто обращаются к некоторому компоненту, то можно объявить объектную переменную в событии
Session_OnStart. Эта переменная будет доступна всем страницам в течение текущего сеанса. Приведем пример, в котором создается объектная переменная, ссылающаяся на компонент MyObject.
<CRIPT LANGUAGE=VBScript RUNAT=Server>
Sub Session_OnStart
Set Session ("MyObj") "Server.CreateObject ("MyObject")
End Sub
</SCRIPT>
Во время текущего сеанса любая страница может обращаться к пергменной MyObj, и одноименные переменные, принадлежащие разным сеансам, являются абсолютно независимыми.

События элемента


WebBrowser и объекта InternetExplorer

События элемента управления WebBrowser и объекта InternetExplorer вызываются тогда, когда пользователь перемещается к другому URL с помощью кнопок нави­гации Internet Explorer или методов передвижения элемента управления WebBrowser. Они контролируют процесс каждой загрузки и позволяют приложе­нию узнать, когда загрузка страницы завершена.

BeforeNavigate2 (Перед перемещением).

Генерируется, когда WebBrowser соби­рается переместиться к другому LJRL. Это может быть вызвано внешней (вызов метода Navigate) или внутренней автоматизацией из сценария или когда пользователь щелкает на гиперссылке в текущем документе. Можно отменить передвижение в приложении, установив значение параметра Cancel метода в True.

Совет

Событие BeforeNavigate2 не срабатывает, если гиперссылка недопустима. Элемент управления, прежде всего, устанавливает контакт с Web-сервером, а затем перемещается к документу.

Метод BeforeNavigate2 имеет следующее объявление.

Private Sub WebBrowserI BeforeNavigate2(ByVal pDisp As Object, _

URL As Variant, Flags As Variant,

TargetFrameName As Variant, PostData As Variant, _

Headers As Variant, Cancel As Boolean)

Первый параметр — pDisp — представляет объект, на котором документ воспро­изводится. Обычно этот объект - WebBrowser. Этот параметр можно использовать, чтобы обратиться к свойствам элементам управления. Его имя — PDisp.Name, pDisp Width и pDisp. Height — размеры элемента управления и т.д.

Параметр URL — это адресат URL (определенный методом Navigate или гипер-ссылкой), Flags - зарезервированный параметр. Параметр TargetFrameName — имя фрейма, в котором воспроизводится документ или значение NULL, если документ не должен отобразиться ни в каком фрейме. Параметры PostData и Header подобны соответствующим параметрам метода Navigate.

Приложение может устанавливать параметр Cancel (обратите внимание: он передается по ссылке) для отмены перемещения. Если установить этот параметр в True, то перемещение не будет даже начато. Для остановки уже начатого переме­щения используется метод Stop.


NavigateComplete (Перемещение завершено). Генерируется после того, как элемент управления успешно переместился к новому положению. Некоторые ресурсы документа все еще могут загружаться (загрузка большого изображения продолжительна), но часть документа загружена с сервера и выполнение началось. Для прерывания этого процесса вызывается метод Stop.
Событие NavigateComplete объявляется следующим образом.
Sub WebBrowserl_NavigateComplete(ByVal URL As String)
Параметр
URL — это URL загружаемого документа.
DownloadBegin (Начало загрузки). Генерируется, когда стартует операция передвижения. Это событие инициируется после того, как сгенерировано событие BeforeNavigate (если передвижение не было отменено), которое сообщает прилйжению, что необходимо отобразить сообщение о занятости программы или изменить форму указателя мыши.
Событие DownloadBegin объявляется следующим образом.
Sub WebBrowserl_DownloadBegin()
DownloadComplete (Загрузка закончена). Генерируется, когда операция пере­движения закончена, остановлена или завершена неудачно. В отличие от события NavigateComplete, которое не инициируется в случае неудачи, это событие всегда инициируется после начала передвижения. Любая индикация о занятости при­ложения управляется из обработчика этого события. Событие DownloadComplete объявляется следующим образом.
Sub WebBrowserl_DownloadComplete()
ProgressChange (Состояние процесса загрузки). WebBrowser прослеживает развитие операции загрузки и периодически выдает событие ProgressChange, чтобы сообщить приложению о степени загрузки. Событие ProgressChange объявляется следующим образом.
Sub WebBrowserl_ProgressChange(ByVal Progress As Long, _
ByVal ProgressMax As Long)
Оба параметра являются длинными целыми числами. Параметр Progress — количество уже загруженных данных, a ProgressMax — общее количество данных, которые будут загружены.
Совет
Процент загруженных данных — это отношение Progress ProgressMax.
Необходимо всегда проверять значение ProgressMax, потому что его значение может быть нулевым (если элемент управления не знает общего объема данных, которые будут загружены). Более того, событие ProgressChange вызывается для каждого из ресурсов документа, и не существует способа узнать заранее полный размер элементов управления, которые загружаются. Отметим: InternetExplorer воспроизводит прогресс загрузки каждого элемента управления, а не всего документа.


TitleChange (Изменение заголовка). Генерируется, когда заголовок текущего документа изменяется. Заголовок HTML-документа может изменяться: когда документ загружается, его заголовком является URL. После того, как реальный заголовок (если он определен с помощью метки TITLE) проанализирован, вызывается событие TitleChange. Его можно использовать для модификации свойства Caption на форме Visual Basic. Событие TitleChange объявляется следующим образом.
Sub WebBrowserl_TitleChange(ByVal Text As String)
Параметр
Text - это строка, которая появляется в строке заголовка InternetExplorer.
NewWindow (Новое окно).
Хотя результат большинства гиперссылок воспроиз­водится в том же окне, что и содержащий их документ, некоторые гиперссылки требуют открытия нового окна для отображения документа. Событие NewWindow вызывается непосредственно перед созданием нового окна.
Это событие можно вызвать, если удерживать нажатой клавишу SHIFT и щелкнуть кнопкой мыши на гиперссылке или выбрать команду Open в меню New Window контекстного меню. Событие NewWindow позволяет приложению отменить создание нового окна. Когда это событие используется с InternetExplorer, то новое окно является еще одним экземпляром InternetExplorer.
Когда событие NewWindow используется при работе с элементом управления WebBrowser, то приложение должно создать новый элемент управления WebBrowser и показать в нем документ или потребовать, чтобы новый документ отображался в том же окне. Если приложение создает новый элемент управления WebBrowser, то необходимо передать все параметры из события NewWindow непо­средственно методу Navigate последнего созданного элемента управления WebBrowser. При отображении нового документа на том же элементе управления необходимо опять-таки передать параметры этого события в метод Navigate существующего окна.
Событие NewWindow объявляется следующим образом.
Sub WebBrowser_NewWindow (ByVal uri As String, _
ByVal Flags As Long, ByVal TargetFrameName As String, _
PostData As Variant, ByVal Headers As String, _
Processed As Boolean)
Параметры события NewWindow идентичны параметрам метода Navigate, кроме последнего, принимающего значения True или False и указывающего, создаст прило­жение новое окно (True) или нет (False).
FrameBeforeNavigate, FrameNavigateComplete, FrameNewWindow. Эти события идентичны событиям BeforeNavigate, NavigateComplete и NewWindow, но вызываются из фреймов.

Составные документы


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

Парни из Microsoft учли потребность среднего пользователя в средстве, позво­ляющем объединять любимые прикладные программы. Они также поняли, что создать универсальное приложение невозможно и придумали OLE, позволяющее приложениям обмениваться данными и функциями. Поскольку OLE-приложения могут быть связаны друг с другом, пользователи могут использовать их отдельные компоненты для создания собственных приложений. Красота OLE состоит в том, что для использования в вашем приложении возможностей другого приложения нет необходимости знать детали его реализации. Аналогично, тому, кто програм­мирует на Visual Basic, нет нужды знать подробности выполнения операций элементом управления RichTextBox или функционирования элемента MSFlexGrid.



Создание


Internet-совместимых элементов управления

С приходом эры Интернет и объединения рабочего стола с Web, что демонст­рируют Active Desktop и последняя версия Internet Explorer, средства управления ActiveX должны обладать возможностью подсоединения к Интернет и загрузки информации с HTTP-серверов. Независимо от того, как много информации можно получить с помощью имеющихся средств, на сервере всегда остается новейшая информация. Интересная, и во многих случаях необходимая, возможность, которую можно добавить к элементам управления - соединение с HTTP и загрузка информации по запросу.

Элементы ActiveX, разрабатываемые с помощью Visual Basic, поддерживают асинхронную загрузку значений свойств. Это значит, что значением свойства может быть файл на Web-сервере, а элементы управления пользователя могут обращаться к серверу и загружать с него информацию. Для загрузки файла из URL используют метод AsyncRead со следующим синтаксисом.

UserControl_AsyncRead Target, AsyncType [, PropertyName]

Строка

Target определяет адрес, по которому находятся данные. Это URL удаленного HTTP-сервера или путь к файлу на локальном или сетевом диске. Например, URL - http://www.servername.corn/Updates/Latest.txt, путь к локальному файлу - file://m:\Software\Updates\Latest.txt.

Тип файла для загрузки определяется аргументом AsyncType, значения которого перечислены в табл 21.5.

Таблица 21.5. Возможные значения аргумента AsyncType метода AsyncRead

Константа

Описание

vbAsyncTypeFile

vbAsyncTypeByteArray

vbAsyncTypePicture

Данные находятся в файле, который можно будет открыть с помощью Visual Basic

Данные в виде массива байтов. Приложение должно обрабатывать элементы массива

Данные — объект

Picture (изображение)

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




и другими свойствами, подгружаемыми параллельно. Параметр PropertyName — произвольное имя. Его единственная функция — служить идентификатором загружаемых данных.

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

Sub UserControl_AsyncReadComplete(PropertyValue As AsyncProperty)

Аргумент

PropertyValue является объектом, свойства которого описаны в табл. 21.6.

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

Константа

Описание

Value

PropertyName

AsyncType

Переменная, содержащая результат асинхронной загрузки.

Имя свойства, определяемое последним аргументом метода AsyncRead.

Целочисленное значение, определяющее тип данных, в свойстве Value. Принимает такие же значения, как и аргумент AsyncType метода AsyncRead.

Событие AsyncReadComplete происходит даже в случае, если во время передачи возникает ошибка. Если загрузка не завершилась успешно, то при обращении к свойству Value объекта AsyncProperty происходит ошибка исполнения. Необходимо включать оператор On Error в код обработчика события AsyncReadComplete, что­бы перехватить ошибки при загрузке.

Свойство Value является фактическим значением загружаемого свойства. Если тип запрошенных данных — VbAsyncTypeFile, то свойство Value — имя временного файла, который Visual Basic создает на диске в папке Temp. Для работы с таким файлом используются стандартные функции ввода/вывода. Если тип запрошенных данных - VbAsyncType Picture, то свойство Value является объектом Picture, содер­жащим битовое представление. Можно присвоить свойство Value свойству Picture элемента управления (или объекту UserControl) или преобразовать битовое представление с помощью метода PaintPicture. Если тип запрошенных данных — VbAsyncTypeByteArray, то свойство Value



является массивом байтов.

Прекратить асинхронную загрузку данных можно с помощью метода CancelAsyncRead. Метод CancelAsyncRead имеет следующий синтаксис.

UserControl.CancelAsyncRead PropertyName

PropertyName — это имя загружаемого свойства (последний аргумент метода AsyncRead). Если PropertyName не был передан при последнем вызове метода AsyncRead, то его выполнение отменяется.

VB6 в действии: разработка элемента управления

Rates


Асинхронная разгрузка значений свойства из Интернет демонстрируется в проекте Rates (Курсы обмена валюты) (рис. 21.12). Rates Control Demo имеет гра­фический интерфейс, содержащий элемент управления ListBox, в котором отобра­жаются последние курсы валюты Rates Control Demo обеспечивает методы поиска курсов различных валют, чтобы элемент управления мог остаться скрытым.



Рис. 21.12. Rates Control Demo: загрузка и вывод данных из Интернет с HTTP-сервера


Создание активных серверных страниц


Простейшим способом создания ASP является изменение расширения файла, содержащего HTML-документ, с НТМ на ASP. Перенесите этот файл в новую папку корневой папки Web-сервера. Во всех примерах этой главы предполагается, что ASP-страницы находятся в папке ASPages, а сами примеры - на прилагаемом компакт-диске в папке с тем же именем.

ASP-файлы и права исполнения

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

С помощью административной утилиты Web-сервера создайте виртуальную папку, назовите ее ActivePages и отобразите ее на ASPages в корневом каталоге Web. Назначьте этой папке право Scripts. Назначать право Execution (Выполнение) необязательно, поскольку ASP-файлы не являются исполняемыми.

Начнем с тривиального примера (см. гл. 20). Это простой HTML-файл, который отображает время на экране клиента (рис. 22.3).

Рис. 22.3. Страница DATETIME.HTM

Программа 22.1. Файл DATETIME.HTM

<HTML>

<HEAD>

<TITLE>Simple ASP Demo<\TITLE>

<SCRIPT LANGUAGE=VBScript>

Document.Write "<FONT SIZE=3 FACE='Verdana'>"

Document.Write "<H1>Welcome to the Active Server     Pages<\H1>"

Document. Write "The date is <B>" & Date () & "</B>  and  the  time is

<B>" & Time()S "</B>"

Document.Write "<P>"

</SCRIPT>

</HEAD>

<BODY>

<B>Active Server Pages</B> contain text, HTML code and scripts that

are executed on the client, ]ust like ordinary HTML documents. The

DateTime.asp file contains a client-side script, which prints   the

date and the time on the client and then displays the document's

body.

</BODY>

</HTML>

Это клиентский сценарий, который вызывает функции

Date() и Time(). Он выполняется на компьютере клиента и, как следствие, отображает дату и время, считанные с его системных часов.


Изменим эту страницу так, чтобы она отображала дату и время сервера. Для этого необходимо добавить операторы, которые будут исполняться на сервере. Скопируйте файл DATETIME.HTM в файл SRVRTIME.ASP и замените сценарий следующим.

<CRIPT LANGUAGE = VBScript RUNAT = Server>

Response. Write "<FONT SIZE=3 FACE='Verdana'>"

Response.Write "<Hl>Welcome to the Active Server Pages</Hl>"

Response. Write "The date is <B>" & Date() & "</B> and the time is <B>"

& Timef) & "</B>"

Response.Write "<P>"

</SCRIPT>

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

Серверные сценарии можно заключать в пару тегов <% и %>. Между тегами помещаются все операторы, выполняющиеся на сервере. Эти операторы рассмат­риваются как серверный сценарий, поэтому на компьютере клиента они замещаются выполняемым выводом, и увидеть их на экране клиента нельзя.

Примечание

При выполнении двойного щелчка на имени ASP-файла на экран выводится HTML-код, но операторы серверного сценария не исполняются. Броузер пропускает теги серверного сценария <% и %>, поскольку не знает, как их отображать.

Приведем пример более полезной ASP-страницы (GREET.ASP), которая отображает различные приветствия в зависимости от времени суток.

Программа 22.2. Страница GREET.ASP

<HTML>



<BODY>

<%

If Time() >=#12:00:00 AM# And Time() < #12:00:00 PM# Then

greeting = "Good Morning!"

Else

greeting = "Good Afternoon!"

End If

%>

<H1> <% =greeting %> </H1>

<BR>

<H2> and welcome to the Active Server Pages.</H2>

<BR>

{Другие строки HTML-кода}

</BODY>

</HTML>

Операторы между первой парой тегов <% и %> не выполняют вывод на экран клиента. Они присваивают требуемое значение переменной greetings (приветствие). Значение этой переменной пересылается клиенту строкой <% =greeting %>. Выражение вида "=переменная" (разумеется, без кавычек) при выполнении сценария на сервере заменяется значением переменной. Остальное — обычный HTML-код, который отображается на экране клиента.

HTML-код и операторы серверного сценария могут сосуществовать в одной строке. Альтернативным вариантом последнего примера является следующий.

<HTML>

<BODY>

<% If Time() > = #12:00:00 АМ# And Time() < #12:00:00 PM# Then %

<Hl>Good Morning!</H1>

<» Else %>

<Hl>Good Afternoon!</H1>

<% End If %>

<BR>

<H2>and welcome to the Active Server Pages.</H2>

<BR>

{Другие строки HTML-кода}

</BODY>

</HTML>

Наряду со встроенными (например, Date() и Time()), серверный сценарий может вызывать процедуры, написанные вами. Предположим, вы написали функцию, которая получает в качестве параметра число и возвращает его строковое представление (для числа 96 она вернет строку "девяносто шесть"). Чтобы вызвать эту функцию из вашего сценария, заключите ее имя в пару тегов.

<% =NumToString(96) %>

При этом определение функции должно располагаться в этом же файле. Поскольку она выполняется на сервере и не содержит HTML-код, который нужно переслать клиенту, поместите ее в пару тегов <SCRIPT>, добавив модификатор RUNAT.

<SCRIPT RUNAT=SERVER LANGUAGE=VBScript>

function NumToString(Number)

{

операторы функции

}

</SCRIPT>

Строка, возвращаемая функцией, может использоваться в сценарии.


Создание базового прототипа элемента управления


Начнем с создания прототипа элемента управления.

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

1. Выберите команду New Project меню File, чтобы открыть окно нового проекта.

2. Щелкните на пиктограмме ActiveX Control. Visual Basic создаст новый проект, который содержит UserControl, с названием UserControll. Он представляет собой форму, на которой будет построен видимый интерфейс.

3. Выберите команду Add Project меню File, чтобы добавить Standard ЕХЕ-проект. Visual Basic создаст новый проект с одной формой Formi, которую будем использовать в качестве тестовой (Formi часто называют тест-формой, а проект, которому она принадлежит - тест-проект). Перед вами базовый прототип элемент управления.

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

5. Закройте окно конструирования элемента управления для активизации его пиктограммы на панели элементов управления.

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

7. Выберите элемент управления и откройте окно Properties.

По умолчанию, объект UserControl имеет следующие свойства:

Draglcon

Left

Top Left

DragMode

Tablndex

Visible

Height

TabStop

WhatIsThisHelpID

HelpContextID

Tag

Width

Index

ToolTipText

Эти свойства, фактически, поддерживаются контейнером. Свойство Left определено контейнером и имеет значение только в контексте контейнера. Аналогично, Tablndex и TabStop не управляются элементом непосредственно, потому что элемент управления не знает, какие еще элементы управления существуют на форме. Только форма знает это и, следовательно, должна поддерживать эти свойства для элементов управления.

Испытайте несколько свойств. Присвойте значение "My generic control" свойству ToolTipText. Запустите приложение, а затем наведите указатель мыши на элемент управления. Введенная строка появится над элементом управления. Подобным способом можно проверить свойство Tag, присваивая ему строку или свойство Index, создавая экземпляры одного элемента управления на форме с одинаковым именем и различным значением Index. При этом не нужно добавлять ни строчки кода для реализации этих свойств.



Создание элементов меню, содержащих растровые изображения


Элементы меню, создаваемые средствами Menu Editor (Редактор меню) Visual Basic, не всегда содержат только текст. В некоторых прикладных программах может потребоваться, чтобы элемент меню содержал растровое изображение. Добавить растровые изображения к элементам меню можно с помощью нескольких API-функции. Разработка таких элементов меню занимает немало времени, но результат того стоит Приложение MenuBMP (рис 13.4) позволяет создавать элементы меню с растровыми изображениями.

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

В этом приложении используются такие API-функции:

• GetMenu()

• GetSubMenu()

• ModifyMenu()

• CreateCompatibleDC()

• CreateCompatibleBitmap()

• Select0bject()

Рис. 13.4. Приложение MenuBMP

Чтобы манипулировать элементами меню с помощью API-функций, необхо­димо получить дескриптор элемента меню. Элементы меню являются объектами, и поэтому им поставлены в соответствие дескрипторы, которые идентифицируют их с точки зрения операционной системы (точно так идентифицируются формы и растровые изображения). Более того, можно манипулировать элементами меню других приложений, запущенных в настоящий момент, если получить дескриптор этого элемента меню.

Для получения дескриптора элемента меню используется функция GetMenu(). Объявим ее:

Private Declare Function GetMenu Lib "user32" (ByVal hWnd _

As Long) As Long

Параметр

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

MenuHandle = GetMenu(Me.hWnd)

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

GetSubMenu().

Private Declare Function GetSubMenu Lib "user32" _

(ByVal hMenu As Long, ByVal nPos As Long) As Long

Параметр

hMenu - это дескриптор меню, возвращаемый функцией GetMenu(), а параметр nPos — номер текущей позиции подменю. Если значение параметра nPos равно 0, то функция GetSubMenu() возвращает дескриптор первого подменю (им часто оказывается меню File (Файл)).


После того как дескриптор подменю получен, его можно модифицировать с помощью функции

ModifyMenu().

Private Declare Function ModifyMenu Lib "user32" Alias _

"ModifyMenuA" (ByVal hMenu As Long, ByVal nPosition _

As Long, ByVal wFlags As Long, ByVal wIDNewItem As _

Long, ByVal IpString As Any) As Long

Эта функция позволяет изменить элемент меню. Поясним это. Параметр hMenu — это дескриптор подменю, полученный с помощью функции GetSubMenu() Параметр nPosition

идентифицирует элемент меню, который требуется изменить. Если в параметре wFlags установлен флаг MF_BYCOMMAND, то этот параметр относится к ID (Идентификатору) команды меню, которая будет изменена. Если же установлен флаг MF_BYPOSITION, то параметр определяет номер позиции элемента подменю. Параметр wFlags является комбинацией флагов, описанных в табл. 13.4.

Таблица 13.4. Флаги меню

Значение

Описание

MF_BITMAP

Указывает, что элемент меню содержит растровое

изображение. Растровое изображение остается в

памяти, пока используется указанный элемент меню

MF_BYCOMMAND

Определяет элемент меню командой ID меню

MF_BYPOSITION

Определяет элемент меню его позицией в подменю:

номер позиции первого объекта равен нулю

MF_CHECKED

Отображает метку выбора, устанавливая ее слева от

элемента меню

MF_DISABLED

Делает элемент меню недоступным

MF_ENABLED

Делает элемент меню доступным

MF_G RAYED,

Делает элемент меню недоступным и выводит его,

заливая изображение серым цветом (вместо того, чтобы

сделать его невидимым)

M F_MENUBARBREAK

Помещает элемент меню в новый столбец, отделяя его

вертикальной линией

MF_MENUBREAK

Помещает элемент меню в новый столбец

MF_POPUP

Подключает дополнительное раскрывающееся меню к

элементу меню

MF_SEPARATOR

Помещает горизонтальную линию разделителя под

элементом меню

MF_STRING

Помещает строку в элемент меню

MF_JJNCHECKED

Снимает метку выбора слева от элемента меню (если

элемент был выделен)

<


Чтобы связать растровое изображение с пунктом меню, необходимо установить флаг MF_BITMAP в параметре wFlags

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

Набор данных, состав­ляющих растровое изображение (обычно это BMP-файл), загружается в скрытый элемент управления PictureBox. Из него растровое изображение копируется в контекст устройства с помощью функции CreateCompatibleBitmap(). После того как растровое изображение помещено в контекст устройства, его можно связать с элементом меню, как строку текста Фрагмент программы 13.5 содержит код, реализующий добавление растрового изображения к элементу меню приложения MenuBMP.

Обратите внимание размеры растрового изображения должны быть переданы как параметры функции CreateCompatibleBitmap(). Создавая растровое изображение с помощью графического редактора, необходимо задавать изображению такие размеры, чтобы они соответствовали размерам элемента меню. Не следует делать его слишком высоким или слишком узким Растровые изображения в рассматри­ваемых примерах были созданы в программе PaintShopPro. Для создания растровых изображений можно использовать любой графический редактор, включая ImageEdit (папка Tools прилагаемого компакт-диска).

Меню Bitmaps приложения MenuBMP содержит три команды, соответствующие трем различным шрифтам (см. рис. 13.4). Три растровых изображения хранятся в файлах Verdana.bmp, Serif.bmp и Comic.bmp в той же папке, что и приложение. После разработки растровых изображений можно начинать работать с программой. Полный текст программы MenuBMP приведен ниже.

Программа 13.5. Приложение MenuBMP

Option Explicit

Private Declare Function GetMenu Lib "user32" _

(ByVal hwnd As Long) As Long

Private Declare Function GetSubMenu Lib "user32"



( ByVal hMenu As Long, ByVal nPos As Long) As Long

Private Declare Function GetMenuItemID Lib "user32"

(ByVal hMenu As Long, ByVal nPos As Long) As Long

Private Declare Function ModifyMenu Lib "user32"

Alias "ModifyMenuA" (ByVal hMenu As Long, _

ByVal nPosition As Long, ByVal wFlags As Long, _

ByVal wIDNewItem As Long, ByVal IpString As Any) As Long

Private Declare Function CreateCompatibleDC Lib "gdi32" _

(ByVal hdc As Long) As Long

Private Declare Function CreateCompatibleBitmap Lib "gdi32" _

(ByVal hdc As Long, ByVal nWidth As Long,

_

ByVal nHeight As Long) As Long

Private Declare Function SelectObject Lib "gdi32" _

(ByVal hdc As Long, ByVal hObject As Long) As Long

Private Declare Function BitBIt Lib "gdi32" _

(ByVal hDestDC As Long, ByVal x As Long, ByVal у As Long, _

ByVal nWidth As Long, ByVal nHeight As Long, _

ByVal hSrcDC As Long, ByVal xSrc As Long, _

ByVal ySrc As Long, ByVal dwRop As Long) As Long

Private Declare Function DeleteDC Lib "gdi32" _

(ByVal hdc As Long) As Long

Const SRCCOPY   &HCC0020

Const MF_BYPOSITION - &H400&

Const MF_BITMAP   &H4&

Private Sub Form_Load()

Dim Width As Integer, Height As Integer

Dim hTmpDC As Long, hMenuID As Long

Dim hBitmap As Long, retValue As Long

Dim tmpID As Long

Dim fileName As String

Dim menuPos As Integer, menuID As Long

‘ Установка позиции меню и имени файла

menuPos = 0

fileName = App.Path & "\verdana.bmp"

Picturel.Picture = LoadPicture(fileName)

Width = 64

Height = 16

‘ Получение дескриптора меню

hMenuID = GetSubMenu(GetMenu(Me.hwnd), menuPos)

‘ Создание контекста устройства для хранения растрового

‘изображения

hTmpDC = CreateCompatibleDC(Picturel.hdc)

‘ Создание растрового изображения

hBitmap = CreateCompatibleBitmap(Picturel.hdc, Width, Height)

‘ Выбор растрового изображения во временный контекст

tmpID = SelectObject(hTmpDC, hBitmap)

‘ Копирование содержимого из элемента управления в   контекст



‘ устройства

retValue = BitBIt(hTmpDC, 0, 0, Width, Height, _

Picturel.hdc, 0, 0, SRCCOPY)

‘ Отмена выбора

tmpID = SelectObject(hTmpDC, tmpID)

‘ Модификация меню

menuID = GetMenuItemID(hMenuID, menuPos)

retValue = ModifyMenu(hMenuID, menuPos, _

MF_BYPOSITION Or MF_BITMAP, menuID, hBitmap)

‘ Второй пункт меню

menuPos = 1

fileName = App.Path & "\serif.bmp"

Picture1.Picture = LoadPicture(fileName)

‘ Создание растрового изображения для элемента меню

hBitmap = CreateCompatibleBitmap(Picturel.hdc. Width, Height)

‘ Выбор растрового изображения во временный контекст

‘ устройства

tmpID = SelectObject(hTmpDC, hBitmap)

retValue = BitBIt(hTmpDC, 0, 0, Width, Height, _

Picture1.hdc. О, О, SRCCOPY)

tmpID = SelectObject(hTmpDC, tmpID)

menuID = GetMenuItemID(hMenuID, menuPos)

retValue = ModifyMenu(hMenuID, menuPos,

MF_BYPOSITION Or MF_BITMAP, menuID, hBitmap)

‘Третий пункт меню menu

Pos = 2

fileName = App.Path & "\comic.bmp"

Picture1.Picture = LoadPicture(fileName)

‘ Создание растрового изображения для элемента меню

hBitmap = CreateCompatibleBitmap(Picturel.hdc, Width, Height)

‘ Выбор растрового изображения во временный контекст устройства

tmpID = SelectObject(hTmpDC, hBitmap)

retValue = BitBIt(hTmpDC, 0, 0, Width, Height, _

Picturel.hdc. О, О, SRCCOPY)

tmpID = SelectObject(hTmpDC, tmpID)

menuID = GetMenuItemID(hMenuID, menuPos)

retValue = ModifyMenu(hMenuID, menuPos, _

MF_BYPOSITION Or MF_BITMAP, menuID, hBitmap)

‘ Очистка

retValue = DeleteDC(hTmpDC)

End Sub

Private Sub MyMenu Click(Index As Integer)

Dim fName(3) As String

fName(0) = "Verdana"

fName(l) = "Serif"

fName(2) = "Comic Sans MS"

Me.CIs

Me.CurrentX = (Me.ScaleWidth - TextWidth(fName(Index)))/2

Me.CurrentY = (Me.ScaleHeight - TextHeight(fName(Index)))/2

Me.Font.Name = fName(Index)

Me.Print fName(Index)

End Sub


Создание набора записей


Если связь с базой данных установлена, то можно использовать SQL-операторы для манипулирования записями. Чтобы выполнить SQL-оператор, используйте метод Execute объекта Connection, передав ему этот оператор в качестве аргумента.

DBConnection.Execute SQLStatement

Аргумент

SQLStatement - это строка, содержащая SQL-оператор или имя сохраненной процедуры. Если SQL-оператор возвращает набор записей (Recordset), как оператор SELECT, то его следует вызывать следующим образом.

Set SelRecords = DBConnection.Execute(SQLStatement)

Метод Execute принимает два необязательных аргумента:

•  количество записей, на которые воздействует данная операция (значение этого параметра устанавливается драйвером);

•  признак, указывающий, является аргумент SQLStatement SQL-оператором или именем сохраненной процедуры.

Полный синтаксис метода имеет следующий вид.

DBConnection.Execute SQLStatement, numRecords, SQLText

Аргумент

SQLText принимает значения adCmdText (для SQL-оператора) и adCmdStoredProc (для сохраненной процедуры).

Другим способом выполнения SQL-оператора является создание объекта Command с помощью оператора:

Set SQLCornmand = Server. CreateObject ("ADODB. Command")

и выполнение SQL-оператора с помощью метода

Execute объекта SQLCommand. Объект Command предоставляет несколько свойств, позволяющих уточнить, какой оператор и каким образом будет выполняться.

Например, можно указать объект Connection, к которому будет применяться объект Command (в случае нескольких открытых соединений), задать значения параметров для сохраненных процедур и т.п.

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

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

Set SQLCommand = Server. CreateObject ("ADODB. Command")

Set Paramltetri = Server. CreateObject ("ADODB. Parameter")

SQLCommand.ActiveConnection = DBConnection

SQLCommand.CommandText = "ProductsByCategory"

SQLCommand.CommandType = adCmdStoredProc

ParamItem.Name = "@ProductCategory"


ParamItem.Value = 31

SQLCommand.Parameters.Append ParamItem

SQLCommand.Execute

Здесь

ProductCategory — имя параметра, который одновременно является именем сохраненной процедуры. Во время выполнения этой переменной присваивается значение (в предыдущем примере - 31). Приведенные операторы используют объект Command для выполнения сохраненной процедуры с параметрами. Этот код можно упростить с помощью оператора With.

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

Set SQLCommand = Server. CreateObject ("ADODB. Command")

Set Paramltem = Server.CreateObject ("ADODB. Parameter")

With SQLCommand

.ActiveConnection = DBConnection

.CommandText = "ProductsByCategory"

.CommandType = adCmdStoredProc

With Paramltem

     .Name = "@ProductCategory"

.ParamItem.Value =31

.Parameters.Append ParamItem

EndWith

.Execute

End With


Создание объектных переменных


В предыдущей главе было показано, как получать доступ к объектам посредством объектной переменной. Также были изучены два метода объявления объектной переменной:

1. Объявление объектной переменной с ключевым словом New.

Private objectVar As New objectType

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

Private objectVar As objectType

Set objectVar = New objectType

Оба метода требуют, чтобы Visual Basic знал тип объекта.

Можно ожидать, что Visual Basic знает о формах, элементах управления и других типах встроенных объектов, но что можно сказать об объектах, созданных разработчиком? Так как Visual Basic ничего не знает об вновь созданном объекте, необходимо обеспечить доступ проекта к объекту посредством добавления в него ссылки на этот объект. Например, если нужно добавить к проекту класс CTimer, откройте меню Project и выберите References. В появившемся диалоговом окне References найдите объект, на который нужно сослаться в коде, и нажмите ОК.

Если после добавления в проект новой ссылки открыть окно Object Browser, можно увидеть список Type Library (Библиотеку типов) с только что добавленным объектом. Выберите его в списке Type Library для просмотра классов, которые он предоставляет. Проект CTimer предоставляет один класс - CTimer. Щелкните на его имени для просмотра его членов.

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

Private TMR As Object

Set TMR = CreateObject ("TimerProject.CTimer")

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



Создание проекта


Data

Чтобы увидеть новый визуальный инструмент в действии, создайте новый проект и в диалоговом окне типа проекта выберите Data Project. Проект Data — это не специальный тип проекта, а стандартный ЕХЕ-проект, но Visual Basic при этом загружает, на панель элементов управления все инструменты для работы с базами данных.

В окне проводника проекта отобразится, как обычно, новая форма и два конструктора ActiveX. Конструктор ActiveX - это специальная надстройка (add-in), предназначенная для упрощения разработки двух типов компонентов:

•  DataEnvironment,

•  DataReport.

Компонент

Data Environment

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

Панель элементов управления проекта Data содержит большое количество элементов управления ActiveX. Перечислим некоторые из них.

• ADODC (ADO Data Control — элемент управления данными ADO) — эк­вивалентен элементу управления Data.

•  DataList и DataCombo — усовершенствованные версии элементов управления ListBox и ComboBox, предназначенные для работы с базами данных (data-bound -связанные с данными). Работают с элементами управления ADO, но не с эле­ментами управления DAO.

•  MSHFlexGrid - иерархический элемент управления Grid (Сетка), который работает с элементами управления DAO. Элемент MSHFlexGrid похож на элемент управления MSFlexGrid (см. гл. 9), но заполняется автоматически с помощью конструктора DataEnvironment.

В следующем параграфе будут рассмотрены конструкторы ActiveX — DataEnvironment и DataReport. Чтобы понять, что такое конструктор ActiveX и как он облегчает разработку проекта Data, рассмотрим основные требования к при­ложению, работающему с базами данных.


Для доступа к базе данных с помощью ADO (или другого инструмента) необ­ходимы объекты двух типов:

•  один или более объектов Connection и

• один или более объектов Command.

Объект Connection соединяет приложение с базой данных, a Command —

извлекает записи из базы данных. Он может использоваться и для изменения содержимого базы данных, но мы не будем это рассматривать подробно. Объект Command принимает, а затем выполняет SQL-оператор. Если это — SQL-запрос, то командный объект возвращает набор записей (RecordSet), соответствующих запросу. Если это — SQL-операция, то командный объект выполняет ее, и одна или больше записей обновляются (командный объект может возвращать записи, измененные операцией).

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

DataReport позволяет создавать структуры отчетов, используя операции типа "укажи и нажми". При этом сначала нужно определить данные, которые будут включены в отчет с по­мощью объекта DataEnvironment, работающего в связке с конструктором ActiveX элемента DataReport. Он позволяет без программирования реализовать дополни­тельные операции для работы с базами данных (запросы и отчеты).


Создание строки параметров


Можете воспользоваться одним из двух способов построения URL для запроса приложения на сервере и передачи ему параметров.

•  Поместите требуемые параметры в тег <FROM> и предоставьте броузеру право соединения с сервером и передачи параметров, заданных значениями элементов управления на форме.

•  Создайте строку параметров с использованием команд VBScript и передайте ее на сервер, вызвав метод Navigate объекта Window.

Рассмотрим первый и наиболее простой способ. Для этого вернемся к странице FORM.HTM (см. гл. 19). Раздел Form на странице (рис. 22.2) создан с помощью следующего тега.

<FROM ACTION="ASPages/Register.asp" METHOD="GET">

Атрибут ACTION указывает URL приложения, которое нужно запустить. В данном случае — это ASP-приложение в виртуальной папке ASPages на Web-узле, на который передается страница. Атрибут METHOD определяет один из двух методов передачи данных от клиента на сервер. В примерах этой главы используется метод GET. Альтернативным является метод POST, который имеет ограничения на длину строки, передаваемой на сервер.

Раздел Form страницы FORM.HTM (рис. 22.2) содержит элементы управления и значения, перечисленные в табл. 22.1.

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

http://127.0.0.I/Register.asp?LName=Brannon&FName=Andrea&Mail= ABrannon@USA.net&hardware=PC&browser=IE&Sports=ONSStock=ON& Bargains=ON&mail=YESsRegister=Register+Now%21

Рис. 22.2. Страница FORM.HTM запускает приложение на сервере и передает значения элементов управления в виде параметров

Таблица 22.1. Элементы управления и их значения из раздела Form

Элемент управления

Значение

Lname

Brannon

Fname

Andrea

Email

Abrannon@USA.net

Hardware

PC

Browser

IE

Sports

ON

News

OFF

Stock

ON

Weather

OFF

Bargains

ON

Mail

YES

Другой способ передачи параметров на сервер — создание строки параметров с помощью команд VBScript и передача ее на сервер вызовом метода Navigate объекта Window. Вот как может выглядеть обработчик события Click кнопки Command, выполняющий эту функцию.

Sub button1_onClick()

URLString =

"http://www.servername.com/Register.asp?Lname=

Brannon&Fname=Andrea&Email=Abrannon@USA.net"

Window.Navigate URLString

End Sub

Переменная

URLString является обычной длинной строкой. Однако чтобы поместить ее на печатной странице, ее придется разорвать. Обычно такие строки строятся по частям с использованием операции сцепления строк.

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