Динамический обмен данными (Dynamic Data Exchange - DDE) - мощное средство системы Windows, которое позволяет пользователю осуществлять доступ к данным параллельно исполняемого Windows-приложения. В своей программе пользователь может работать с этими данными в их естественном формате (как они определены в “родном” приложении) и с теми значениями, которые данные имеют на текущий момент.
Суть DDE состоит в установлении “диалогов” (каналов связи) между двумя параллельно исполняемыми Windows-приложениями. Одно из приложений, предоставляя данные, выступает в роли DDE-сервера, другое, получая данные, выступает в роли DDE-клиента. Любое приложение может быть как DDE-клиентом, получая данные от некоторого приложения, так и DDE-сервером, предоставляя данные некоторому приложению. Между DDE-сервером и
DDE-клиентом можно одновременно установить несколько “диалогов”.Для того, чтобы стать DDE-сервером, Clarion-приложение должно:
Для того, чтобы стать DDE-клиентом, Clarion-приложение должно:
Прототипы процедур динамического обмена содержатся в файле DDE.CLW, который должен вставляться оператором INCLUDE в MAP структуру вашей программы. Процесс динамического обмена данными инициирует не связанные с экранными объектами DDE-события для ACCEPT-цикла того окна в программе-сервере, и программе-клиенте, которое установило канал связи между приложениями.
События
DDE-процесс регулируется рядом не связанных с полем DDE-событий. Эти события направляются ACCEPT-циклу того окна и сервера, и клиента, которое установило канал связи между приложениями.
Если Clarion-приложение выступает в качестве сервера, то для него будут инициироваться следующие события:
EVENT:DDErequest
Клиент осуществил запрос элемента данных.
EVENT:DDEadvise
Клиент осуществил запрос на предоставление элемента данных всякий раз, когда данные обновляются.
EVENT: DDEexecute
Клиент исполнил оператор DDEEXECUTE.
EVENT:DDEpoke
Клиент прислал незапрашиваемые данные
Если Clarion-приложение выступает в качестве клиента, то для него будут инициироваться следующие события:
EVENT:DDEdata
Сервер предоставил обновленный элемент данных.
EVENT: DDEclosed
Сервер закрыл канал связи
DDE.При возникновении DDE-события, используя приведенные ниже процедуры, можно выяснить причину этого события:
После того, как Clarion-программа создала DDE-сервер, внешние клиенты могут связаться с сервером и запросить данные. Каждый запрос данных сопровождается строкой (формат которой известен сервер-программе), где конкретизируется запрашиваемый элемент данных. Если значение требуемого элемента уже известно Clarion-серверу, то сервер автоматически снабжает этим значением клиента, без порождения какого-либо события. В противном случае для цикла ACCEPT окна сервера инициируется одно из событий EVENT:DDErequest или EVENT:DDEadvise.
После того, как Clarion-программа создала DDE-клиента, он может связываться с внешними серверами для получения данных. Если сервер первый раз предоставляет значение требуемого элемента, то клиент получает это значение автоматически, без порождения какого-либо события. Если клиент установил с сервером связь типа “горячей линии”, то всякий раз, когда сервер предоставляет клиенту обновленное значение элемента данных, для ACCEPT-цикла окна клиента инициируется событие EVENT:DDEdata.
DDE Процедуры
DDEACKNOWLEDGE (послать подтверждение приема с DDE сервера)
DDEACKNOWLEDGE(
ответ )
DDEACKNOWLEDGE
Посылает подтверждение приема текущего оператора DDEPOKE или DDEEXECUTE, посланного на DDE сервер.
ответ Целочисленная константа, переменная или выражение, содержащее значение ноль (0) или единица (1), указывающее на отрицательное или положительное подтверждение.
Процедура
DDEACKNOWLEDGE позволяет программе, являющейся DDE сервером, немедленно подтвердить прием незапрашиваемых данных, посланных из DDEPOKE, или команд, посланных из DDEEXECUTE. Это позволяет клиентскому приложению незамедлительно продолжить работу. Хотя оператор CYCLE после EVENT:DDEpoke или EVENT:DDEexecute также посылает клиенту положительное подтверждение, DDEACKNOWLEDGE позволяет посылать еще и отрицательное подтверждение.Пример:
!
Текст клиентского приложения содержит следующее:
WinOne WINDOW,AT(0,0,160,400)
END
SomeServer LONG
DDEChannel LONG
CODE
OPEN(WinOne)
DDEChannel = DDECLIENT('MyServer','System') !
Открыть канал связи с приложением MyServerDDEEXECUTE(DDEChannel,'[ShowList]') !
Сынициировать его на выполнение какого-либо!действия
!
Текст приложения-сервера содержит следующий текст:WinOne WINDOW,AT(0,0,160,400)
END
DDEChannel LONG
CODE
OPEN(WinOne)
DDEChannel = DDESERVER('MyServer','System') !
Открыть каналACCEPT
CASE EVENT()
OF EVENT:DDEExecute
CASE DDEVALUE() !
Проверить запрашиваемое действиеOF 'ShowList'
DDEACKNOWLEDGE(1) !
Послать положительное подтверждение приемаDO ShowList !
и предпринять действиеELSE !
Если запрашиваемое действие неопознаноDDEACKNOWLEDGE(0) !
Послать отрицательное подтверждение приемаEND
END
END
Смотри также:
DDEPOKE, DDEEXECUTE
DDEAPP (получить имя сервер-приложения)
DDEAPP( )
Процедура
DDEAPP возвращает строку, содержащую имя приложения того DDE-канала, который инициировал последнее по времени DDE-событие. Обычно - это имя, указываемое первым параметром в процедурах DDESERVER или DDECLIENT при установлении DDE-канала.Возвращаемый тип данных:
STRING
Пример:
ClientApp STRING(20)
WinOne WINDOW,AT(0,0,160,400)
STRING(@S20),AT(5,5,90,20),USE(ClientApp)
END
TimeServer LONG
DateServer LONG
FormatTime STRING(5)
FormatDate STRING(8)
CODE
OPEN(WinOne)
TimeServer = DDESERVER('SomeApp','Time') !
Регистрация сервераDateServer = DDESERVER('SomeApp','Date') !
Регистрация сервераACCEPT
CASE EVENT()
OF EVENT:DDErequest
CASE DDECHANNEL()
OF TimeServer
ClientApp = DDEAPP() !
Получить имя клиента
DISPLAY !
и отобразить на экранFormatTime = FORMAT(CLOCK(),@T1)
DDEWRITE(TimeServer,DDE:manual,'Time',FormatTime)
OF DateServer
ClientApp = DDEAPP() !
Получить имя клиентаDISPLAY !
и отобразить на экранFormatDate = FORMAT(TODAY(),@D1)
DDEWRITE(DateServer,DDE:manual,'Date',FormatDate)
END
END
END
Смотри
также: DDECLIENT, DDESERVER
DDECHANNEL (получить номер DDE-канала)
DDECHANNEL( )
Процедура
DDECHANNEL возвращает целое число типа LONG, определяющее номер DDE-канала, который инициировал последнее по времени DDE-событие для клиент-или сервер-приложения. То же самое значение возвращается функциями DDESERVER или DDECLIENT при установлении DDE-канала.Возвращаемый тип данных:
LONG
Пример:
WinOne WINDOW,AT(0,0,160,400)
END
TimeServer LONG
DateServer LONG
FormatTime STRING(5)
FormatDate STRING(8)
CODE
OPEN(WinOne)
TimeServer = DDESERVER('SomeApp','Time') !
Регистрация сервераDateServer = DDESERVER('SomeApp','Date') !
Регистрация сервераACCEPT
CASE EVENT()
OF EVENT:DDErequest
CASE DDECHANNEL
() !проверить какой каналOF TimeServer
FormatTime = FORMAT(CLOCK(),@T1)
DDEWRITE(TimeServer,DDE:manual,'Time',FormatTime)
OF DateServer
FormatDate = FORMAT(TODAY(),@D1)
DDEWRITE(DateServer,DDE:manual,'Date',FormatDate)
END
END
END
Смотри
также: DDECLIENT, DDESERVER
DDECLIENT (возвратить номер канала DDE-клиента)
DDECLIENT( [
приложение ] [, раздел ] )
DDECLIENT
Возвращает номер канала нового DDE-клиента.приложение Строковая константа или переменная для указания имени сервер-приложения, с которым нужно установить связь. Обычно это – имя приложения. Если параметр не указан, то используется имя приложения первого из зарегистрированных DDE-серверов.
раздел Строковая константа или переменная для указания имени раздела данных, относящихся к приложению. Если параметр не указан, то используется первый из разделов ранее определенных в приложении
.Процедура
DDECLIENT возвращает номер канала нового DDE-клиента, которым идентифицируются приложение и раздел. Если приложение не было запущено на исполнение, то DDECLIENT возвращает нулевое значение (0).Обычно, когда DDE-канал открывается клиентом, приложение - это имя сервер-приложения. Раздел - это строка, содержимое которой используется либо как имя доступного раздела
приложения, когда это приложение регистрирует его в Windows, либо как некоторое значение, которое говорит приложению какие данные оно должно предоставить. Приложения и разделы, зарегистрированные на данный момент в Windows, можно просмотреть используя процедуру DDEQUERY.Возвращаемый тип данных:
LONG
Пример:
DDEReadVal REAL
WinOne WINDOW,AT(0,0,160,400)
ENTRY(@s20),USE(DDEReadVal)
END
ExcelServer LONG
CODE
OPEN(WinOne)
!
Создать клиента Excel-таблицы:ExcelServer = DDECLIENT('Excel','MySheet.XLS')
IF NOT ExcelServer !
Если сервер не был запущен, тоMESSAGE('Please start Excel') !
предложить пользователю запустить егоRETURN !
и осуществить следующую попыткуEND
DDEREAD(ExcelServer,DDE:auto,'R5C5',DDEReadVal)
ACCEPT
CASE EVENT()
OF EVENT:DDEdata !
Когда обновленные данные поступают от ExcelPassedData(DDEReadVal) !
обработать ихEND
END
Смотри
также: DDEQUERY, DDEWRITE, DDESERVERзавершить диалог с DDE-сервером)
DDECLOSE(
канал )
DDECLOSE
Закрывает открытый канал DDE.канал Метка переменной типа LONG, указывающая номер канала - то значение, которое возвращают процедуры DDESERVER или DDECLIENT.
Процедура
DDECLOSE пpедоставляет программе DDE-клиента возможность закрыть указанный канал. Когда закрывается окно, открывшее канал, то автоматически закрывается и сам канал.
Выдаваемые сообщения об ошибках:
601 Invalid DDE Channel (Недопустимый DDE-канал)
602 DDE Channel Not Open (Канал DDE не открыт)
605 Time Out (Ошибка по тайм-ауту)
Пример:
WinOne WINDOW,AT(0,0,160,400)
END
SomeServer LONG
CODE
OPEN(WinOne)
SomeServer = DDECLIENT('SomeApp','MyTopic') !Канал клиента
ACCEPT
END
DDECLOSE(SomeServer)
Смотри
также: DDECLIENT, DDESERVER
DDEEXECUTE (послать команду DDE серверу)
DDEEXECUTE(
канал, команда )
DDEEXECUTE
Посылает командную строку в открытый канал DDE-клиента.канал Целочисленная константа типа LONG или переменная, указывающие канал клиента - то значение, которое возвращает процедура DDECLIENT.
команда Строковая константа или переменная, содержащие команду, предназначенную для исполнения сервер-приложением.
Процедура
DDEEXECUTE позволяет программе DDE-клиента передавать команду серверу. Формат команды должен быть таким, чтобы сервер мог ее понять и исполнить. В качестве сервера может быть и не Clarion-программа. По принятому соглашению строка-команда заключается в квадратные скобки ([ ]).DDE-сервер Clarion-приложения может воспользоваться процедурой DDEVALUE() для того, чтобы узнать какую команду послал клиент. Оператор CYCLE в конце обработки события DDE:EVENT
execute присылает клиенту положительное подтверждение приема посланной им команды. DDEACKNOWLEDGE может посылать как положительное, так и отрицательное подтверждение.
Выдаваемые сообщения об ошибках:
601 Invalid DDE Channel (Недопустимый DDE-канал)
602 DDE Channel Not Open (Канал DDE не открыт)
603 DDEEXECUTE Failed (Ошибка команды DDEEXECUTE)
605 Time Out (Ошибка по тайм-ауту)
Генерируемые события:
EVENT:DDEexecute Клиент прислал запрос-команду.
Пример:
!
Фрагмент программы сервер-приложения:
WinOne WINDOW,AT(0,0,160,400)
END
SomeServer LONG
DDEChannel LONG
CODE
OPEN(WinOne)
!
Открыть канал связи с Windows Program Manager:DDEChannel = DDECLIENT('PROGMAN','PROGMAN')
!
Создать группу для новой программы:DDEEXECUTE(DDEChannel,'[CreateGroup(Clarion Applications)]')
!
Отобразить ее на экран:DDEEXECUTE(DDEChannel,'[ShowGroup(1)]')
!
Создать новый элемент группы, используя вторую иконку в progman.exeDDEEXECUTE(DDEChannel,'[AddItem(MYAPP.EXE,My Program,PROGMAN.EXE,2)]')
Смотри также:
DDEACKNOWLEDGE, DDEVALUE
DDEITEM (получить имя элемента данных сервера)
DDEITEM( )
Для имевшего место DDE-события процедура
DDEITEM возвращает строку с наименованием элемента динамического обмена между клиентом и сервером. Под элементом подразумевается либо элемент, запрошенный оператором DDEREAD, либо элемент данных, предоставленный DDEPOKE.Возвращаемый тип данных:
STRING
Пример:
WinOne WINDOW,AT(0,0,160,400)
END
Server LONG
FormatTime STRING(5)
FormatDate STRING(8)
CODE
OPEN(WinOne)
Server = DDESERVER('SomeApp','Clock') !Зарегистрировать сервер для моего раздела
ACCEPT
CASE EVENT()
OF EVENT:DDErequest
CASE DDEITEM()
OF 'Time'
FormatTime = FORMAT(CLOCK(),@T1)
DDEWRITE(Server,DDE:manual,'Time',FormatTime)
OF 'Date'
FormatDate = FORMAT(TODAY(),@D1)
DDEWRITE(Server,DDE:manual,'Date',FormatDate)
END
OF EVENT:DDEadvise
CASE DDEITEM()
OF 'Time'
FormatTime = FORMAT(CLOCK(),@T1)
DDEWRITE(Server,1,'Time',FormatTime)
OF 'Date'
FormatDate = FORMAT(TODAY(),@D1)
DDEWRITE(Server,60,'Date',FormatDate)
END
END
END
Смотри
также: DDEREAD, DDEEXECUTE, DDEPOKE(послать незапрашиваемые данные DDE-серверу)
DDEPOKE(
канал, элемент, значение )
DDEPOKE
Посылает DDE-серверу незапрашиваемые данные через открытый канал DDE-клиента.канал Целочисленная константа типа LONG или переменная, указывающие канал клиента - то значение, которое возвращает процедура DDECLIENT.
элемент Строковая константа или переменная, указывающие относящийся к приложению элемент, на имя которого посылаются неиспрашиваемые данные.
значение Строковая константа или переменная, в которых находятся данные, предназначенные для элемента
.Процедура
DDEPOKE позволяет программе DDE-клиента пересылать незапрашиваемые данные серверу. Чтобы сервер смог распознать и обработать данные, параметры элемент и значение должны быть представлены в формате данных сервер-приложения. В качестве сервера может быть и не Clarion-программа.DDE-сервер Clarion-приложения, чтобы выяснить что ему прислал клиент, может воспользоваться процедурами DDEITEM() и DDEVALUE(). Опреатор CYCLE в конце обработки события DDE:EVENTpoke присылает клиенту положительное подтверждение приема неиспрашиваемых данных. DDEACKNOWLEDGE может посылать как положительное, так и отрицательное подтверждение.
Выдаваемые сообщения об ошибках:
601 Invalid DDE Channel (Недопустимый DDE-канал)
602 DDE Channel Not Open (Канал DDE не открыт)
604 DDEPOKE Failed (Ошибка команды DDEPOKE)
605 Time Out (Ошибка по тайм-ауту)
Генерируемые события:
EVENT:DDEpoke Клиент прислал незапрашиваемые данные.
Пример:
WinOne WINDOW,AT(0,0,160,400)
END
DDEChannel LONG
CODE
OPEN(WinOne)
DDEChannel = DDECLIENT('Excel','System') !
Открыть канал связи с ExcelDDEEXECUTE(DDEChannel,'[NEW(1)]') !
Создать новую таблицуDDEEXECUTE(DDEChannel,'[Save.As("DDE_CHART.XLS")]') !
Сохранить ее в файле DDE_CHART.XLSDDECLOSE(DDEChannel) !
Завершить диалогDDEChannel = DDECLIENT('Excel','DDE_CHART.XLS') !
Установить канал связи с новой диашраммойDDEPOKE(DDEChannel,'R1C2','Widgets') !
Переслать в нее данные
DDEPOKE(DDEChannel,'R1C3','Gadgets')
DDEPOKE(DDEChannel,'R2C1','East')
DDEPOKE(DDEChannel,'R3C1','West')
DDEPOKE(DDEChannel,'R2C2','450')
DDEPOKE(DDEChannel,'R3C2','275')
DDEPOKE(DDEChannel,'R2C3','340')
DDEPOKE(DDEChannel,'R3C3','390')
DDEEXECUTE(DDEChannel,'[SELECT("R1C1:R3C2")]') !
Подсветить переданные данныеDDEEXECUTE(DDEChannel,'[NEW(2,2)]') !
и создать новую диаграмму!
Посылаем ряд команд по форматированию диаграммы и работы и нею
DDECLOSE(DDEChannel) !Закрыть канал после окончания работы
Смотри также:
DDEACKNOWLEDGE, DDEITEM, DDEVALUE
DDEQUERY (просмотр зарегистрированных DDE-серверов)
DDEQUERY(
[ приложение ] [, раздел ] )
DDEQUERY
Возвращает список зарегистрированных на данный момент DDE-серверов.приложение Строковая константа или переменная для указания имени опрашиваемого приложения. Для большинства приложений - это имя приложения. Если параметр не указан, то возвращается список всех приложений, которые зарегистрированы вместе с указанным разделом
.раздел
Строковая константа или переменная для указания имени опрашиваемого раздела данных, относящихся к приложению. Если параметр не указан, то возвращается список всех разделов приложения.Процедура
DDEQUERY возвращает строку, содержащую имена приложений и их разделов зарегистрированных на данный момент DDE-серверов.Если параметр раздел опущен, то в строке будут указаны все разделы, принадлежащие данному приложению. Если не указан параметр приложение, то в строке будут перечислены все зарегистрированные приложения с данным разделом. Если же не определены оба параметра, то DDEQUERY возвратит все зарегистрированные на данный момент DDE-серверы.
Данные в возвращаемой строке представляются в формате приложение
:раздел, где пары приложение, раздел отделяются - когда их больше одной - друг от друга символом запятой (например, ‘Excel:MySheet.XLS,ClarionApp:DataFile.DAT’).Возвращаемый тип данных:
STRING
Пример:
!Этот пример не обрабатывает DDEADVISE
WinOne WINDOW,AT(0,0,160,400)
END
SomeServer LONG
ServerString STRING(200)
CODE
OPEN(WinOne)
LOOP
ServerString = DDEQUERY()
!Указать все зарегистрированные серверыIF NOT INSTRING('SomeApp:MyTopic',ServerString,1,1)
MESSAGE('Open SomeApp, Please')
ELSE
BREAK
END
END
SomeServer = DDECLIENT('SomeApp','MyTopic') !Зарегистрировать клиента
ACCEPT
END
DDECLOSE(SomeServer)
получить данные от DDE-сервера)
DDEREAD(
канал, режим, элемент [, переменная ] )
DDEREAD
Получает данные из ранее открытого канала DDE-клиента.канал Целочисленная константа типа LONG или переменная, указывающие канал клиента - то значение, которое возвращает процедура DDECLIENT.
режим Символическое имя, определяющее тип канала передачи данных:
DDE:auto, DDE:manual или DDE:remove (определены в файле EQUATES.CLW).элемент
Строковая константа или переменная, указывающие связанное с приложением имя запрашиваемого элемента данных.переменная Имя переменной, в которую будут занесены запрашиваемые данные. Если параметр не указан и установлен режим DDE:remove, то обрываются все связи с элементом.
Процедура
DDEREAD дает возможность программе DDE-клиента читать данные из канала в переменную. Параметром режим определяется способ обновления данных. Значение параметра элемент в качестве строки передается сервер-приложению для указания элемента данных, который запрашивается клиентом. Формат и структура строки элемента зависит от сервер-приложения.Если текущим режимом является DDE:
auto, переменная обновляется сервером постоянно (“горячая” связь). Событие EVENT:DDEdata генерируется всякий раз, когда переменная обновлена с сервера.Если текущим режимом является DDE:manual, переменная обновляется единожды, и больше не генерируется никаких событий. Для проверки на наличие каких-нибудь изменившихся значений (“холодная” связь), серверу должен быть послан другой запрос DDEREAD.
Если текущим режимом является DDE:remove, предыдущая “горячая” связь с переменной прекращается. При наличии режима DDE:remove и отсутствии параметра переменная все предыдущие “горячие” связи с разделом прекращаются независимо от того, какие переменные были связаны. Это означает, что клиент должен послать серверу другой запрос DDEREAD, предназначенный для проверки любых измененных значений.
Выдаваемые сообщения об ошибках:
601 Invalid DDE Channel (Недопустимый DDE-канал)
602 DDE Channel Not Open (Канал DDE не открыт)
605 Time Out (Ошибка по тайм-ауту)
Генерируемые события:
Клиент-приложению посылаются следующие события:
EVENT:DDEdata
Сервер прислал обновленный элемент данных по “горячей” линии.
EVENT:DDEclosed
Сервер завершил диалог.
Пример:
WinOne WINDOW,AT(0,0,160,400)
END
ExcelServer LONG(0)
DDEReadVal REAL
CODE
OPEN(WinOne)
!
Клиент Excel таблицыExcelServer = DDECLIENT('Excel','MySheet.XLS')
IF NOT ExcelServer !
Если сервер не был запущенMESSAGE('Please start Excel') !
предложить пользователю запустить егоCLOSE(WinOne)
RETURN
END
!
Запрос серверу на постоянное обновление:DDEREAD(ExcelServer,DDE:auto,'R5C5',DDEReadVal)
ACCEPT
CASE EVENT()
OF EVENT:DDEdata !
При поступлении от Excel обновленных данных
PassedData(DDEReadVal) !
вызвать процедуру их обработкиEND
END
Смотри
также: DDEQUERY, DDEWRITE, DDESERVER
DDESERVER (возвратить номер канала DDE- сервера)
DDESERVER( [
приложение ] [, раздел ] )
DDESERVER
Возвращает номер канала нового DDE-сервера.приложение Строковая константа или переменная для указания имени приложения. Обычно это - имя приложения. Если параметр не указан, то используется имя файла (без расширения) программы.
раздел Строковая константа или переменная для указания имени раздела данных, относящихся к приложению. Если параметр не указан, то приложение будет удовлетворять любой запрос данных.
Процедура
DDESERVER возвращает номер канала нового DDE-сервера, которым идентифицируются приложение и раздел. Номер канала определяет тот раздел, данные которого будут предоставляться приложением. Это дает возможность одному Clarion-приложению регистрироваться в качестве DDE-сервера нескольких разделов.
Возвращаемый тип данных:
LONG
Пример:
DDERetVal STRING(20)
WinOne WINDOW,AT(0,0,160,400)
ENTRY(@s20),USE(DDERetVal)
END
MyServer LONG
CODE
OPEN(WinOne)
MyServer = DDESERVER('MyApp','DataEntered') !
Регистрируется серверACCEPT
CASE EVENT()
OF EVENT:DDErequest !
Обслуживание однократного запроса данныхDDEWRITE(MyServer,DDE:manual,'DataEntered',DDERetVal) !
Однократное предоставление данныхOF EVENT:DDEadvise !
Обслуживание запроса на постоянное обновлениеDDEWRITE(MyServer,15,'DataEntered',DDERetVal)
!
Отслеживать изменения каждые 15 секунд!
и предоставить данные как только они обновилисьEND
END
Смотри
также: DDECLIENT, DDEWRITE
DDETOPIC (получить имя раздела сервера)
DDETOPIC( )
Процедура
DDETOPIC возвращает строку, содержащую имя раздела того DDE-канала, который инициировал последнее по времени DDE-событие.Возвращаемый тип данных:
STRING
Пример:
WinOne WINDOW,AT(0,0,160,400)
END
TimeServer LONG
DateServer LONG
FormatTime STRING(5)
FormatDate STRING(8)
CODE
OPEN(WinOne)
TimeServer = DDESERVER('SomeApp') !
Регистрация сервераACCEPT
CASE EVENT()
OF EVENT:DDErequest
CASE DDETOPIC() !
Получить имя запрошенного разделаOF 'Time'
FormatTime = FORMAT(CLOCK(),@T1)
DDEWRITE(TimeServer,DDE:manual,'Time',FormatTime)
OF 'Date'
FormatDate = FORMAT(TODAY(),@D1)
DDEWRITE(DateServer,DDE:manual,'Date',FormatDate)
END
END
END
Смотри
также: DDEREAD, DDECLIENT, DDESERVER
DDEVALUE (получить значение данных, посланных серверу)
DDEVALUE( )
Процедура
DDEVALUE возвращает строку с данными, посланными DDE-серверу Clarion-приложения оператором DDEPOKE, либо командой, выполненной оператором DDEEXECUTE.Возвращаемый тип данных:
STRING
Пример:
WinOne WINDOW,AT(0,0,160,400)
END
TimeServer LONG
TimeStamp FILE,DRIVER(ASCII),PRE(Tim)
Record RECORD
FormatTime STRING(5)
FormatDate STRING(8)
Message STRING(50)
END
END
CODE
OPEN(WinOne)
TimeServer = DDESERVER('TimeStamp') !
Зарегистрировать серверACCEPT
CASE EVENT()
OF EVENT:DDEpoke
OPEN(TimeStamp)
Tim:FormatTime = FORMAT(CLOCK(),@T1)
Tim:FormatDate = FORMAT(TODAY(),@D1)
Tim:Message = DDEVALUE() !
Получить данные
ADD(TimeStamp)
CLOSE(TimeStamp)
CYCLE !
Подтвердить получениеEND
END
Смотри также:
DDEPOKE, DDEEXECUTE
DDEWRITE (предоставить данные DDE-клиенту)
DDEWRITE(
канал, режим, элемент [, переменная ] )
DDEWRITE
Передает данные в открытый канал DDE-сервера.канал Целочисленная константа типа LONG или переменная, указывающие канал сервера - то значение, которое возвращает процедура DDESERVER.
режим Либо целочисленная константа или переменная для указания интервала времени (в секундах), в по истечению которого каждый раз производится опрос переменной для проверки изменения ее значения, либо символическое имя, определяющее тип канала передачи данных:
DDE:auto, DDE:manual или DDE:remove (определены в файле EQUATES.CLW).элемент
Строковая константа или переменная, указывающие связанное с приложением имя предоставляемого элемента данных.переменная Имя переменной предоставляющей данные. Если параметр не указан и установлен режим DDE:remove, то обрываются все каналы связи с элементом .
Процедура
DDEWRITE дает возможность программе DDE-сервера предоставлять клиенту значение переменной. Значение параметра элемент представляет собой строку для указания предоставляемого элемента данных. Формат и структура строки элемента зависит от сервер-приложения. Параметром режим определяется способ обновления данных.Если параметр режим принимает значение DDE:auto, то клиент-программа получает текущее значение переменной и на все последующие запросы этого (или любого другого) клиента внутренние библиотеки будут предоставлять тоже самое значение. Когда клиент запросил обмен данными по “горячей” линии, то Clarion-программа должна сама отслеживать любые изменения значения переменной и посылать клиенту обновленные данные посредством исполнения оператора DDEWRITE.
Если параметр режим принимает значение DDE:manual, то переменная обновляется только один раз. Когда клиент запросил обмен данными по “горячей” линии, то Clarion-программа должна сама отслеживать любые изменения значения переменной и посылать клиенту обновленные данные посредством исполнения оператора DDEWRITE. Для установки или получения величины интервала времени для связи DDE (по умолчанию пять секунд) может использоваться
PROP:DDETimeOut.Если параметр режим принимает целые положительные значения, то внутренние библиотеки по истечению указанного промежутка времени (в секундах) каждый раз проводят проверку значения переменной. Если значение изменилось, то внутренние библиотеки автоматически (дополнительные Clarion-операторы не нужны) передают клиенту обновленное значение. Следует отметить, что при этом - в зависимости от данных - возникают значительные накладные расходы, и использовать данный режим рекомендуется только по необходимости.
Если для параметра режим указано значение DDE:remove, то разрывается ранее установленная “горячая” линия связи с переменной. Если для параметра режим указано значение DDE:remove, а параметр переменная не указан, то разрываются все ранее установленные “горячие” линии связи с элементом, независимо от того, какие переменные были с ним связаны. Поэтому, для обнаружения изменения значения данных клиенту нужно снова послать серверу DDEREAD запрос.
Выдаваемые сообщения об ошибках:
601 Invalid DDE Channel (Недопустимый DDE-канал)
602 DDE Channel Not Open (Канал DDE не открыт)
605 Time Out (Ошибка по тайм-ауту)
Генерируемые события:
EVENT:DDErequest
Запрос клиента на элемент данных (“холодная линия”).
EVENT:DDEadvise
Запрос клиента на постоянное обновление элемента данных (“горячая” линия).
Пример:
DDERetVal STRING(20)
WinOne WINDOW,AT(0,0,160,400)
ENTRY(@s20),USE(DDERetVal)
END
MyServer LONG
CODE
OPEN(WinOne)
MyS
erver = DDESERVER('MyApp','DataEntered') !Зарегистрировать серверACCEPT
CASE EVENT()
OF EVENT:DDErequest !
Сервер для однократно запрашиваемых данныхDDEWRITE(MyServer,DDE:manual,'DataEntered',DDERetVal) !
Однократное предоставление данныхOF EVENT:DDEadvise !
Сервер запроса непрерывного обновленияDDEWRITE(MyServer,15,'DataEntered',DDERetVal)
!
Проверка на изменение каждые 15 сек!
и предоставление измененных данныхEND
END
Смотри также:
DDEQUERY, DDEREAD, DDESERVER
Связывание и внедрение объектов
Механизм связывания и внедрения объектов (Object Linking and Embedding - OLE) позволяет “объекты” из одного приложения Windows связать или включить в “документ” (структуру данных) другого приложения. Приложение, создающее и поддерживающее объект, является приложением-сервером OLE, тогда как приложение, которое содержит объект, называется OLE контроллером (его иногда еще называют OLE клиентом). Объекты внедрения или связывания - это структуры данных, присущие приложению – серверу OLE (такие как график из электронной таблицы или рисунок из приложения - графического редактора). Этот объект помещается в окно-контейнер приложения контроллера. В приложении на языке Clarion окно контейнер и является управляющим элементом типа OLE.
Реализация OLE в Clarion для Windows позволяет, написанным на нем приложениям, служить OLE контроллером, связывая или включая объекты от любого приложения - OLE сервера. Реализация в Clarion OLE поддерживает также автоматизацию OLE, которая представляет собой способность OLE контроллера динамически управлять OLE сервером, используя его макроязык.
Связывание объектов
Связывание объектов в общем случае означает, что в OLE контроллере содержится “ссылка” на объект, будь то объект целой структурой данных (подобно файлу электронной таблицы) или компонентом такой структуры (как, например, диапазон ячеек в той же таблице). При связывании объекта с OLE контроллером контроллер содержит только информацию, необходимую для нахождения связанных данных. Эта информация может храниться или в поле BLOB или файле - комплексном хранилище (OLE Compound Storage file).
Внедрение объектов
Внедрение объектов означает, что OLE контроллер хранит весь объект целиком, независимо от приложения-сервера OLE. Внедренный в приложение-контроллер объект не существует в виде отдельного файла, к которому могло бы обращаться приложение-сервер. Приложение - OLE контроллер полностью содержит активный объект, который хранится либо в BLOB,
либо в файле - комплексном хранилище (OLE Compound Storage file).Поддержка объектов OLE
Любой OLE объект в приложении-контроллере, внедренный или связанный, поддерживается приложением-сервером, создавшим этот объект. Это означает, что когда пользователь хочет изменить этот объект, то для того чтобы сделать эти изменения, OLE контроллер активизирует приложение-сервер. Есть два способа активизации сервера: активизация “на месте” (in place) и активизация в “режиме открытия” (“open-mode”).
Активизация “на месте”
Активизация “на месте” означает, что пользователю кажется, будто бы он остается в приложении OLE контроллере, но меню и панель инструментов сервера объединяются с меню и инструментами контроллера, а текущим исполняемым приложением является приложение-сервер. Редактируемый объект имеет мерцающую рамку, чтобы обозначить то, что он находится в режиме редактирования.
Если в приложении сервере имеется одна или несколько панелей инструментов, то эта панель инструментов появляется либо в виде всплывающей панели, либо присоединенной к одному из краев рамки, либо в сочетании этих подходов. Это может приводить к “выпаданию” вниз объектов управления вашего окна, так что будьте внимательны при проектировании окна с OLE объектами.
Активизация в режиме открытия
Активизация в режиме открытия означает, что пользователь переключается на приложение-сервер, выполняемый в отдельном окне. Редактируемый объект находится в приложении-сервере, в то время как в приложении-контроллере он мерцает, чтобы обозначить то, что объект редактируется в отдельном окне.
Свойства контейнера объекта OLE
С контейнером объекта OLE связаны несколько свойств, относящихся только к объектам типа OLE (но не OCX).
Свойства-атрибуты
PROP:Create Атрибут CREATE (пробел, если нет такого атрибута). (только присвоение значения)
PROP:Open Атрибут OPEN (пробел, если нет такого атрибута). (только присвоение значения)
PROP:Document Атрибут DOCUMENT (пробел, если нет такого атрибута). (только присвоение значения)
PROP:Link Атрибут LINK (пробел, если нет такого атрибута). (только присвоение значения)
PROP:Clip Атрибут CLIP. Атрибут-переключатель. Присвоение нулевой строки (‘’) или 0 выключает его, ‘1’ или 1 - включает. (Только присвоение значения)
PROP:Stretch Атрибут STRETCH. Атрибут-переключатель. Присвоение нулевой строки (‘’) или 0 выключает его, ‘1’ или 1 - включает. (Только присвоение значения)
PROP:Autosize Атрибут AUTOSIZE. Атрибут-переключатель. Присвоение нулевой строки (‘’) или 0 выключает его,
‘1’ или 1 - включает. (Только присвоение значения)PROP:Zoom Атрибут ZOOM. Атрибут-переключатель. Присвоение нулевой строки (‘’) или 0 выключает его,
‘1’ или 1- включает. (Только присвоение значения)PROP:Compatibility Атрибут COMPATIBILITY (пробел, если нет такого атрибута) (только присвоение значения)
Необъявленные свойства
PROP:Blob Преобразует объект в/из переменную BLOB. (ЧТЕНИЕ/ЗАПИСЬ)
PROP:SaveAs Сохраняет объект в файле - комплексном хранилище. (Только ЗАПИСЬ). Для занесения объекта в комплексное хранилище используется синтаксис:
‘имя_файла\!компонент’. Например:?controlx{PROP:SaveAs} = ‘myfile\!objectx’
PROP:DoVerb Выполняет
OLE doverb команду из следующего набора команд. (Только ЗАПИСЬ):DOVERB:Primary (0)
Вызывает первичные действия объекта. Что это за действия, определяется самим объектом, а не контейнером. Если для объекта поддерживается активизация “на месте”, то обычно первичное действие это и делает.
DOVERB:Show (-1)
Сообщает объекту о том, что он должен открыться для просмотра и редактирования. С помощью этой команды отображается вновь созданный объект и высвечивается источник связи. Обычно эта команда является алиасом для некого другого действия, определяемого самим объектом.
DOVERB:Open (-2)
Сообщает объекту о том, что он должен открыться для просмотра и редактирования в отдельном от контейнера окне (это относится объектам, поддерживающим активизацию “на месте”). Если объект активизацию “на месте” не поддерживает, то эта команда для него эквивалентна команде DOVERB:Show.
DOVERB:Hide (-3)
Сообщает объекту о том, что он должен убрать свой интерфейс пользователя. Эта команда применима только к объектам, активизируемым “на месте”.
DOVERB:UIActivate (-4)
Активизирует объект “на месте” наряду с его полным набором инструментальных средств, включая меню, панели инструментов и его имя в строке заголовка окна-контейнера.
DOVERB:InPlaceActivate (-5)
Активизирует объект “на месте” не включая набор инструментальных средств (меню и панели инструментов), которые необходимы пользователю для изменения внешнего вида и поведения объекта.
DOVERB:DiscardUndoState (-6)
Предписывает объекту уничтожить содержимое буфера изменений (UNDO), которые объект возможно поддерживает, не деактивируя при этом сам объект.
DOVERB:Properties (-7)
Вызывает модуль просмотра системных модальных свойств объекта, чтобы позволить пользователю установить их значения.
PROP:Deactivate Деактивизирует OLE объект, активизированный “на месте”. (ЧТЕНИЕ/ЗАПИСЬ/ВЫПОЛНЕНИЕ)
PROP:Update Предписывает объекту обновить самого себя. (ЧТЕНИЕ /ЗАПИСЬ/ ВЫПОЛНЕНИЕ)
PROP:CanPas
te Можно ли объект помещать во внутренний буфер обмена? (Только ЧТЕНИЕ)PROP:Paste Помещает объект из внутреннего буфера обмена в экранный контейнер. (ЧТЕНИЕ/ЗАПИСЬ/ВЫПОЛНЕНИЕ).
PROP:CanPasteLink Можно ли объект, находящийся во внутреннем буфере обмена поместить в контейнер в виде связи? (Только ЧТЕНИЕ)
PROP:PasteLink Помещает и связывает объект, находящийся во внутреннем буфере, в OLE контейнер. (ЧТЕНИЕ/ЗАПИСЬ/ВЫПОЛНЕНИЕ)
PROP:Copy Копирует объект из OLE контейнера во внутренний буфер. (ЧТЕНИЕ/ЗАПИСЬ/ВЫПОЛНЕНИЕ)
PROP:ReportException
Послать объекту OLE прерывание (для отладки) (Только ЗАПИСЬ).
PROP:OLE Определить находится ли в контейнере объект OCX или OLE? (Только ЧТЕНИЕ)
PROP:Language "Номер" языка, используемого для OLE или OCX. Номер US English 0409H, номера других языков могут быть вычислены в WINNT.H файле в MS Windows SDK (ЧТЕНИЕ/ЗАПИСЬ).
Пример
:
PROGRAM
MAP
INCLUDE('OCX.CLW')
SelectOleServer PROCEDURE(OleQ PickQ),STRING
END
INCLUDE 'XL.CLW' !
Константы, используемые ExcelINCLUDE 'ERRORS.CLW' !
Включить коды ошибокSaveLinks FILE,DRIVER('TopSpeed'),PRE(SAV),CREATE
Object BLOB
Record RECORD
LinkType STRING(1) !F = File, B = BLOB
LinkFile STRING(64) !
Имя файла комплексного хранилища OLE и объектовEND
END
i LONG !
Счетчики цикла
j LONG
ResultQ QUEUE !
Очередь для хранения данных из OLEDIRECTORYName CSTRING(64)
CLSID CSTRING(64)
ProgID CSTRING(64)
END
MainWin WINDOW('OLE Demo'),AT(,,350,200),STATUS(-1,-1),SYSTEM,GRAY,RESIZE,MAX,TIMER(1)
MENUBAR
MENU('&File')
ITEM('e&xit'),USE(?exit)
END
MENU('&Objects')
ITEM('Create Object'),USE(?CreateObject)
ITEM('Paste Object'),USE(?PasteObject)
ITEM('PasteLink Object'),USE(?PasteLinkObject)
ITEM('Save Object to BLOB'),USE(?SaveObjectBlob),DISABLE
ITEM('Save Object to OLE File'),USE(?SaveObjectFile),DISABLE
ITEM('Retrieve Saved Object'),USE(?GetObject),DISABLE
END
MENU('&Activate')
ITEM('&Spreadsheet'),USE(?ActiveExcel)
ITEM('&Any OLE Object'),USE(?ActiveOLE),DISABLE
END
END
OLE,AT(5,10,160,100),COLOR(0808000H),USE(?ExcelObject)
MENUBAR
MENU('&Clarion App')
ITEM('&Deactivate Excel'),USE(?DeactExcel)
END
END
END
OLE,AT(170,10,160,100),USE(?AnyOLEObject),AUTOSIZE
MENUBAR
MENU('&Clarion App')
ITEM('&Deactivate Object'),USE(?DeactOLE)
END
END
END
END
CODE
OPEN(SaveLinks)
IF ERRORCODE() !
Проверить, что Open без ошибокIF ERRORCODE() = NoFileErr !
Если файл не существует
CREATE(SaveLinks) !
то создать егоIF ERRORCODE() THEN HALT(,ERROR()) END
OPEN(SaveLinks) !
а затем открытьIF ERRORCODE() THEN HALT(,ERROR()) END
ELSE
HALT(,ERROR())
END
END
OPEN(MainWin)
?ExcelObject{PROP:Create} = 'Excel.Sheet.5' !
Создать объект - таблицу ExcelDO BuildSheetData !
заполнить ее произвольными даннымиIF RECORDS(SaveLinks) !
Проверить существование сохраненной записи
SET(SaveLinks) !
взять ееNEXT(SaveLinks)
POST(EVENT:Accepted,?GetObject) !
и отобразитьDO MenuEnable
ELSE
ADD(SaveLinks) !
или добавить пустую записьEND
IF ERRORCODE() THEN HALT(,ERROR()) END
ACCEPT
CASE EVENT()
OF EVENT:CloseWindow
?ExcelObject{PROP:Deactivate} !
Закрыть приложение - сервер?AnyOLEObject{PROP:Deactivate}
OF EVENT:Timer
IF CLIPBOARD()
IF ?AnyOLEObject{PROP:CanPaste} !
Допустима вставка из буфера обмена?IF ?PasteObject{PROP:Disable}
ENABLE(?PasteObject)
END
ELSIF NOT ?PasteObject{PROP:Disable}
DISABLE(?PasteObject)
END
IF ?AnyOLEObject{PROP:CanPasteLink} !
Допустима вставка из буфера обмена?IF ?PasteLinkObject{PROP:Disable}
ENABLE(?PasteLinkObject)
END
ELSIF NOT ?PasteLinkObject{PROP:Disable}
DISABLE(?PasteLinkObject)
END
END
OF EVENT:Accepted
CASE FIELD()
OF ?Exit
POST(EVENT:CloseWindow)
OF ?CreateObject
OLEDIRECTORY(ResultQ,0) !
Получить список установленных OLE серверов?AnyOLEObject{PROP:Create} = SelectOleServer(ResultQ) !
Дать пользоваптелю выбрать?AnyOLEObject{PROP:DoVerb} = 0 !
Активизировать OLE сервер в режиме “по умолчанию”DO MenuEnable
OF ?PasteObject
?AnyOLEObject{PROP:Paste} !
Вставить объектSETCLIPBOARD('Paste Completed') !
Поместить в буфер простой текст
DO MenuEnable
OF ?PasteLinkObject
?AnyOLEObject{PROP:PasteLink} !объект PasteLink
SETCLIPBOARD('PasteLink Completed') !
Поместить в буфер простой текстDO MenuEnable
OF ?SaveObjectBlob !
Запомнить объект в поле BLOBSAV:Object{PROP:Handle} = ?AnyOLEObject{PROP:Blob}
SAV:LinkType = 'B'
PUT(SaveLinks)
IF ERRORCODE() THEN STOP(ERROR()) END
OF ?SaveObjectFile !
Сохранить в OLE Compound Storage file
?AnyOLEObject{PROP:SaveAs} = 'TEST1.OLE\!Object'
SAV:LinkFile = 'TEST1.OLE\!Object'
SAV:LinkType = 'F'
PUT(SaveLinks)
IF ERRORCODE() THEN STOP(ERROR()) END
OF ?GetObject
IF SAV:LinkType = 'F' !
Сохранить в OLE Compound Storage file??AnyOLEObject{PROP:Open} = SAV:LinkFile
ELSIF SAV:LinkType = 'B' !
Сохранить в BLOB??AnyOLEObject{PROP:Blob} = SAV:Object{PROP:Handle}
END
DISPLAY
OF ?ActiveExcel
?ExcelObject{PROP:DoVerb} = 0 !
Запустить Excel “на месте”OF ?ActiveOLE
?AnyOLEObject{PROP:DoVerb} = 0 !
Активизировать OLE сервер в режиме “по умолчанию”OF ?DeactExcel
?ExcelObject{PROP:Deactivate} !
Вернуться в Clarion программуOF ?DeactOLE
?AnyOLEObject{PROP:Deactivate} !
Вернуться в Clarion программуEND !CASE FIELD()
END !CASE EVENT0()
END !ACCEPT
BuildSheetData ROUTINE !
Использовать для построения таблицы!OLE автоматизацию
?ExcelObject{PROP:ReportException} = TRUE !Excel сообщит о любых ошибках
?ExcelObject{'Application.Calculation'} = xlManual !
выключить автопересчетLOOP i = 1 TO 3 !
Заполнить таблицу значениямиLOOP j = 1 TO 3
?ExcelObject{'Cells(' & i & ',' & j & ').Value'} = Random(100,900)
END
?ExcelObject{'Cells(4,' & i & ').Value'} = 'Sum'
?ExcelObject{'Cells(5,' & i & ').FormulaR1C1'} = '=SUM(R[-4]C:R[-2]C)'
?ExcelObject{'Cells(6,' & i & ').Value'} = 'Average'
?ExcelObject{'Cells(7,' & i & ').FormulaR1C1'} = '=AVERAGE(R[-6]C:R[-4]C)'
END
!turn auto recalc back on
?ExcelObject{'Application.Calculation'} = xlAutomatic
DISPLAY
MenuEnable ROUTINE !
Включить пункты менюENABLE(?ActiveOLE)
ENABLE(?SaveObjectBlob,?GetObject)
SelectOleServer PROCEDURE(OleQ PickQ)
window WINDOW('Choose OLE Server'),AT(,,122,159),CENTER,SYSTEM,GRAY
LIST,AT(11,8,100,120),USE(?List),HVSCROLL, |
FORMAT('146L~Name~@s64@135L~CLSID~@s64@20L~ProgID~@s64@'),FROM(PickQ)
BUTTON('Select'),AT(42,134),USE(?Select)
END
CODE
OPEN(window)
SELECT(?List,1)
ACCEPT
CASE ACCEPTED()
OF ?Select
GET(PickQ,CHOICE(?List))
IF ERRORCODE() THEN STOP(ERROR()) END
POST(EVENT:CloseWindow)
END
END
RETURN(PickQ.ProgID)
Свойства, влияющие на интерфейс
PROP:Object Взять изначальный интерфейс объекта. (ТОЛЬКО ЧТЕНИЕ)
В Visual Basic для панели инструментов и объекта-иерархической структуры для отображения пиктограмм на кнопках инструментов и в дереве используется объект “image-list” (список изображений). Для того, чтобы связать объект - изображение с инструментальной панелью, используется следующий оператор:
?toolbar{'ImageList'} = ?imagelist{prop:object}
PROP:SelectInterface Выбирает интерфейс, который следует использовать с данным объектом. (ТОЛЬКО ПРИСВОЕНИЕ)
?x{PROP:SelectInterface} = 'x.y'
?x{'z(1)'} = 1
?x{'z(2)'} = 2
имеет то же значение, что и
?x{'x.y.z(1)'} = 1
?x{'x.y.z(2)'} = 2
PROP:AddRef Увеличить счетчик обращений для интерфейса. (ТОЛЬКО ПРИСВОЕНИЕ)
PROP:Release
Уменьшить счетчик обращений для интерфейса (ТОЛЬКО ПРИСВОЕНИЕ)
Библиотеки Clarion OLE/OCX и иерархия объектов:
Во время проектирования и реализации библиотеки Clarion OLE, отказ в доступе к вторичным объектам, созданных первичным объектом (например из excel: ExcelUse{'Application.Charts.Add'}), не считался проблемой, так как существовали другие способы получения доступа к объекту:
ExcelUse {'Application.Charts(Chart1).ChartWizard(' &?ex{'Range(A5:C5)'}&','&xl3DPie&',7,1,0,0,2,,,,)'}.
В то время был известен только один случай, когда это нельзя было использовать. Это возможно и на сегодняшний день, так как стандарты OLE регламентирует, что коллекция реализации объектов должна также реализовывать метод для доступа к объектам путем индексирования.
Из-за особого случая, упомянутого выше, когда объект был создан одним полем и был передан в другой объект как параметр, метод, который будет более или менее прозрачными для пользователя, был осуществлен.
Вызывая метод, который возвращает IDispatchInterface преобразованный в специальное представление ( '`' сопровождающиеся множеством цифр). Это специальное представление признано в паре мест в библиотеке OLE.
Место, которое вы найдете наиболее полезным - когда специальное представление находится на месте где интерфейс мог бы обнаружиться в синтаксисе свойств, где он заменит любой предыдущий интерфейс в доступе свойств или методов объекта. Например:
x=y{'charts.add()')
y{x&'p(7)'}
где y – ole-объект, а x - cstring. Это пример метода, возвращающего интерфейс и затем этот интерфейс использован для доступа к методу p с параметром 7.
В этом контексте, дальнейшее осложнение возникает в формировании указателя подсчитывающего использование в
OLE. Это означает, что если объект используется неоднократно, он должен иметь такой указатель-счетчик увеличивающийся перед использованием.
x=y{'charts.add()')
y{PROP:AddRef}=x
y{x&'p(7)'}
y{x&'p(7)'} ;последнее использование x
OLEDIRECTORY (получить список установленных OLE/OCX)
OLEDIRECTORY(
список , флаг [, битность ] )
OLEDIRECTORY
Получить список установленных OLE серверов или объектов OCX.список Метка структуры QUEUE, в которую заносится список.
флаг Целочисленная константа или переменная, которая определяет, получить ли спсиок OLE серверов (флаг = 0) или список объектов OCX (флаг
= 1).битность
Целочисленная константа или переменная, которая определяет, что следует получить список либо 16-битных, либо 32-битных элементов управления OCX. Если параметр равен единице (1), то возвращаются только 16-битные элементы управления OCX. Если параметр равен двум (2), то возвращаются только 32-битные элементы управления OCX. Если параметр равен трем (3), то возвращаются и 16-битные, и 32-битные элементы управления OCX. Если этот параметр пропущен или равен нулю, 16-битные программы возвращают 16-битные элементы управления OCX, а 32-битные программы - соответственно 32-битные элементы управления OCX.Замечание: 16-ти битная поддержка не поддерживается данным релизом, должен использоваться исключительно 32-х битный режим.
С помощью
OLEDIRECTORY получается список всех установленных OLE серверов или OCX объектов и заносится в очередь-список. Очередь-список должна иметь точно такую же структуру, что и очередь OleQ, объявленная в EQUATES.CLW:OleQ QUEUE,TYPE
Name CSTRING(64) !
Имя приложения - OLE сервераCLSID CSTRING(64) !
Уникальный идентификатор для операционной системыProgID CSTRING(64) !
Регистрационное имя, как напр.: Excel.Sheet.5END
Пример:
ResultQ QUEUE(OleQ). !
Объявить ResultQ такую же как OleQ QUEUE в EQUATES.CLW
CODE
OLEDIRECTORY(ResultQ,0) !
Получить список установленных OLE серверов!
поместить его в ResultQ?OleControl{PROP:Create} = SelectOleServer(ResultQ)
!
Процедура выбора пользователем OLE сервера:SelectOleServer PROCEDURE(OleQ PickQ)
window WINDOW('Choose OLE Server'),AT(,,122,159),CENTER,SYSTEM,GRAY
LIST,AT(11,8,100,120),USE(?List),HVSCROLL, |
FORMAT('146L~Name~@s64@135L~CLSID~@s64@20L~ProgID~@s64@'),FROM(PickQ)
BUTTON('Select'),AT(42,134),USE(?Select)
END
CODE
OPEN(window)
SELECT(?List,1)
ACCEPT
CASE ACCEPTED()
OF ?Select
GET(PickQ,CHOICE(?List))
IF ERRORCODE() THEN STOP(ERROR()) END
POST(EVENT:CloseWindow)
END
END
RETURN(PickQ.ProgID)
OLE (.OCX)
Пользовательские OLE объекты обычно имеют расширение .OCX. Поэтому обычно их называют объектами .OCX. Эти объекты подобны объектам .VBX в том смысле, что они самодостаточны и, будучи использованными в программе, выполняют определенную функцию. Однако, объекты .OCX не имеют ограничений присущих . VBX, поскольку построены по спецификациям Microsoft OLE 2, которые разработаны с учетом межязыковой совместимости (для языков, отличных от Visual Basic).
Название
ОписаниеPROP:Create Атрибут CREATE (если атрибут отсутствует, то принимается равным пробелу). (ТОЛЬКО ПРИСВОЕНИЕ)
PROP:DesignMode Имеет ли объект контейнер для режима редактирования (имеется ли ограничительная рамка вокруг него)? (ТОЛЬКО ПРИСВОЕНИЕ)
PROP:Ctrl Это объект .OCX? (ТОЛЬКО ЧТЕНИЕ)
PROP:GrabHandles Высвечивает для объекта “зацепки” для изменения размеров. (ТОЛЬКО ПРИСВОЕНИЕ)
PROP:OLE Находится ли в контейнере объект OCX или OLE? (ТОЛЬКО ЧТЕНИЕ)
PROP:IsRadio Это OCX - кнопка радио (с зависимой фиксацией)? (ТОЛЬКО ЧТЕНИЕ)
PROP:LastEventName
Получить имя последнего события присланного объекту .OCX. (ТОЛЬКО ЧТЕНИЕ)
PROP:SaveAs Сохранить объект в файле - комплексном хранилище (OLE Compound Storage file). (ТОЛЬКО ПРИСВОЕНИЕ)
Синтаксис оператора для помещения объекта в файл – хранилище таков: ‘имя_файла
\!компонент’ Например:?controlx{PROP:SaveAs} = 'myfile\!objectx'
PROP:ReportException
Сообщение об исключительных ситуациях OLE (для отладки). (ТОЛЬКО ДЛЯ ЗАПИСИ)
PROP:DoVe
rb Выполняет OLE doverb команду из следующего набора команд. (Только ЗАПИСЬ)DOVERB:Primary (0)
Вызывает первичные действия объекта. Что это за действия, определяется самим объектом, а не контейнером. Если для объекта поддерживается активизация “на месте”, то обычно первичное действие это и делает.
DOVERB:Show (-1)
Сообщает объекту о том, что он должен открыться для просмотра или редактирования. С помощью этой команды отображается вновь созданный объект и высвечивается источник связи. Обычно эта команда является псевдонимом для некого другого действия, определяемого самим объектом.
DOVERB:Open (-2)
Сообщает объекту о том, что он должен открыться для просмотра и редактирования в отдельном от контейнера окне (это относится к объектам, поддерживающим активизацию “на месте”). Если объект активизацию “на месте” не поддерживает, то эта команда для него эквивалентна команде DOVERB:Show.
DOVERB:Hide (-3)
Сообщает объекту о том, что он должен убрать свой интерфейс пользователя. Эта команда применима только к объектам, активизируемым “на месте”.
DOVERB:UIActivate (-4)
Активизирует объект “на месте” наряду с его полным набором инструментальных средств, включая меню, панели инструментов и его имя в строке заголовка окна-контейнера.
DOVERB:InPlaceActivate (-5)
Активизирует объект “на месте” не включая набор инструментальных средств (меню и панели инструментов), которые необходимы пользователю для изменения внешнего вида и поведения объекта.
DOVERB:DiscardUndoState (-6)
Предписывает объекту уничтожить содержимое буфера изменений (UNDO), которые объект возможно поддерживает, не деактивируя при этом сам объект.
DOVERB:Properties (-7)
Вызывает модуль просмотра системных модальных свойств объекта, чтобы позволить пользователю установить их значения.
PROP:Language Номер языка, используемый для OLE Автоматизации или OCX Метода. Номер Американского Английского языка -0409-ый, номера же других языков могут быть вычислены с помощью данных, содержащихся в файле WINNT.H в MS Windows (ДЛЯ ЧТЕНИЯ/ДЛЯ ЗАПИСИ).
Оконные функции являются стандартным средством программирования под Windows во многих языках программирования. Оконная функция представляет собой процедуру или функцию, которую вы (программист) пишете для обработки особых ситуаций, относительно которых операционная система полагает, что программисту возможно необходимо отреагировать на нее. Оконная функция вызывается операционной системой всякий раз, когда нужно обработать такую ситуацию. Поэтому, оконная функция не выглядит частью логической последовательности выполнения программы, а кажется обособленной и “магической”, не имеющей логической связи с другими процедурами программы.
Язык Clarion для Windows не требует от вас писать собственные оконные функции для выполнения наиболее общих действий, как это имеет место в других языках программирования, поскольку эти действия отслеживаются функциями библиотеки времени выполнения и циклом ACCEPT. Однако, поскольку объекты OCX обычно написаны на других языках, в которых требуется написание своих оконных функций, вам понадобится их написать для обработки событий и других программных аспектов связанных с работой объектов OCX, использованных в программе на языке Clarion. Поскольку методы класса, имеют своим неявным первым параметром имя класса, они не могут быть использованы
в качестве функции вызова.Существует три вида оконных функций, которые вам возможно придется написать: обработчик событий, контроллер редактирования свойств и обработчик изменения свойств. Вы можете называть их как угодно, но они имеют специфические требования к передаваемым им параметрам.
Оконная функция - обработчик событий
OCXПрототип этого события должен выглядеть так:
OcxEventFuncName PROCEDURE(*SHORT,SIGNED,LONG),LONG
От операционной системы передаются следующие параметры:
*SHORT Параметр-указатель, который передается другим библиотечным функциям объекта OCX: OCXGETPARAM, OCXGETPARAMCOUNT и OCXSETPARAM в качестве первого параметра.
SIGNED Номер поля, присвоенный объекту. Это тот самый номер, который представляется мнемонической меткой соответствия данного объекта.
LONG Номер события, относящегося к OCX. Мнемонические имена для некоторых заранее определенных номеров событий содержатся в файле OCXEVENT.CLW .
Возвращаемое значение типа LONG сообщает операционной системе необходима ли некая дальнейшая обработка. Возврат нуля (0) означает необходимость дополнительных действий (таких как изменение значения USE-переменной или выключение радио кнопки), тогда как возврат любого другого значения говорит о том, что обработка события завершена.
Обработка событий, генерируемых объектом .OCX, должна выполняться быстро, поскольку некоторые события критичны ко времени. Поэтому у пользователя не должно быть возможности помешать выполнению этой функции (т.е. нельзя использовать процедуру MESSAGE или оператор A
SK или другие операторы касающиеся обработки данного окна). Программный код функции - обработчика события должен выполнять только необходимые действия и как можно быстрее (обычно это подразумевает исключение обработки событий, связанных с мышью).
Функция - контроллер редактирования свойств OCX
Прототип этой функции должен выглядеть следующим образом:
OcxPropEditFuncName PROCEDURE(SIGNED,STRING),LONG
От операционной системы передаются следующие параметры:
SIGNED Номер поля, присвоенный объекту. Это тот самый номер, который представляется мнемонической меткой соответствия данного объекта.
STRING Название свойства, значение которого должно изменяться.
Возвращаемое значение типа LONG сообщает операционной системе допустимо ли редактирование значения свойства. Если возвращаемое значение равно (0), то процедура не разрешает изменение значения свойства и пользователь не может этого делать. Если процедура возвращает любое другое значение, то это означает возможность изменения пользователем данного свойства.
Функция - обработчик изменения свойств OCX
Прототип этой функции должен выглядеть следующим образом:
OcxPropChangeProcName PROCEDURE(SIGNED,STRING)
ПРИЛОЖЕНИЕ
А Библиотека DDE, OLE, и .OCX 721От операционной системы передаются следующие параметры:
SIG
NED Номер поля, присвоенный объекту. Это тот самый номер, который представляется мнемонической меткой соответствия данного объекта.STRING Название изменяемого свойства.
Эта процедура вызывается, при изменении значения свойства.
Пример:
!
В этой программе используется OCX – календарь который Microsoft поставляет вместе с Access95
! (в составе MS Office Professional для Windows).
PROGRAM
MAP
INCLUDE('OCX.CLW')
EventFunc PROCEDURE(*SHORT Reference,SIGNED OleControl,LONG CurrentEvent),LONG
PropChange PROCEDURE(SIGNED OleControl,STRING CurrentProp)
PropEdit PROCEDURE(SIGNED OleControl,STRING CurrentProp),LONG
END
INCLUDE('OCXEVENT.CLW') !
Константы, используемые событиями OCXINCLUDE('ERRORS.CLW') !
Константы кодов ошибок
GlobalQue QUEUE !Очередь событий и смены отображения
F1 STRING(255)
END
SaveDate FILE,DRIVER('TopSpeed'),PRE(SAV),CREATE
Record RECORD
DateField STRING(10)
END
END
MainWin WINDOW('OCX Demo'),AT(,,350,200),STATUS(-1,-1),SYSTEM,GRAY,MAX,RESIZE
MENUBAR
MENU('&File')
ITEM('Save Date to File'),USE(?SaveObjectValue)
ITEM('Retrieve Saved Date'),USE(?GetObject)
ITEM('E&xit'),USE(?exit)
END
MENU('&Object')
ITEM('About Box'),USE(?AboutObject)
ITEM('Set Date to TODAY'),USE(?SetObjectValueToday)
ITEM('Set Date to 1st of Month'),USE(?SetObjectValueFirst)
END
ITEM('&Properties!'),USE(?ActiveObj)
END
LIST,AT(237,6,100,100),USE(?List1),HVSCROLL,FROM(GlobalQue)
OLE,AT(5,10,200,150),USE(?OcxObject)
END
END
CODE
OPEN(SaveDate)
IF ERRORCODE() !
Проверить успешность открытияIF ERRORCODE() = NoFileErr !
если файл не существуетCREATE(SaveDate) !
создать егоIF ERRORCODE() THEN HALT(,ERROR()) END
OPEN(SaveDate) !
и открытьIF ERRORCODE() THEN HALT(,ERROR()) END
ELSE
HALT(,ERROR())
END
END
OPEN(MainWin)
?OcxObject{PROP:Create} = 'MSACAL.MSACALCtrl.7' !
Объект OCX MS Access 95 календарь
IF RECORDS(SaveDate) !
Проверить существование сохраненной записиSET(SaveDate) !
и взять ееNEXT(SaveDate)
IF ERRORCODE() THEN STOP(ERROR()).
POST(EVENT:Accepted,?GetObject)
ELSE
ADD(SaveDate) !
иначе добавить записьIF ERRORCODE() THEN STOP(ERROR()).
END
IF ?OcxObject{PROP:OLE} !
Это объект OLE ?GlobalQue = 'An Object is in the OLE control'
ADD(GlobalQue)
IF ?OcxObject{PROP:Ctrl} !
НЕ является ли объект OCXGlobalQue = 'It is an OCX Object'
ADD(GlobalQue)
END
END
DISPLAY
OCXREGISTEREVENTPROC(?OcxObject,EventFunc) !
Зарегистрировать функцию - обработчик событийOCXREGISTERPROPCHANGE(?OcxObject,PropChange) !
Зарегистрировать функцию - контроллер
OCXREGISTERPROPEDIT(?OcxObject,PropEdit) !
Зарегистрировать функцию - редактор свойств?OcxObject{PROP:ReportException} = 1 !
Включить возможность сообщений об ошибках в OCXACCEPT
CASE EVENT()
OF EVENT:Accepted
CASE FIELD()
OF ?Exit
POST(EVENT:CloseWindow)
OF ?AboutObject
?OcxObject{'AboutBox'} !
вывести окно AboutOF ?SetObjectValueToday
?OcxObject{'Value'} = FORMAT(TODAY(),@D1) !
Установить сегодняшнюю дату
OF ?SetObjectValueFirst
?OcxObject{'Value'} = MONTH(TODAY()) & '/1/' & SUB(YEAR(TODAY()),3,2)
OF ?SaveObjectValue !
Сохранить значение в файлеSAV:DateField = ?OcxObject{'Value'}
PUT(SaveDate)
IF ERRORCODE() THEN STOP(ERROR()).
OF ?GetObject !
Взять значение из файла?OcxObject{'Value'} = SAV:DateField
OF ?ActiveObj
?OcxObject{PROP:DoVerb} = 0 !
Открыть диалог свойств объекта
END
END
END
!
Функция - обработчик событийEventFunc PROCEDURE(*SHORT Reference,SIGNED OleControl,LONG CurrentEvent)
Count LONG
Res CSTRING(200)
Parm CSTRING(30)
CODE
IF CurrentEvent <> OCXEVENT:MouseMove !
Пропустить события - перемещения мышиRes = 'Event: ' & OleControl{PROP:LastEventName}
LOOP Count = 1 TO OCXGETPARAMCOUNT(Reference) !
Цикл по всем параметрамParm = OCXGETPARAM(Reference,Count) !
беря имя каждого параметра
Res = CLIP(Res) & ' - ' & Parm !
и сцепляя их вместеEND
GlobalQue = Res !
Поместить их в буфер глобальной QUEUEADD(GlobalQue) !
и добавить элементDISPLAY
END
RETURN(True)
!
функция - контроллер изменения свойствPropChange PROCEDURE(SIGNED OleControl,STRING CurrentProp)
CODE
GlobalQue = 'PropChange: ' & CurrentProp & ' = ' & OleControl{CurrentProp}
!
занести в глобальную QUEUE
ADD(GlobalQue) !добавить элемент для отображения
IF ERRORCODE() THEN STOP(ERROR()).
!
функция редактирования свойствPropEdit PROCEDURE(SIGNED OleControl,STRING CurrentProp)
CODE
!
Спросить резрешения редактировать свойство:IF MESSAGE('Allow?','Change',ICON:Question,BUTTON:Yes+BUTTON:No,BUTTON:Yes,1) = BUTTON:Yes
RETURN(1) !
разрешить изменениеELSE
RETURN(0) !
запретить изменение
END
Как OLE Автоматизация к приложению OLE Сервера, так и OCX/ActiveX объекты создают методы (процедуры), которые могут быть вызваны для выполнения объектом заданных действий. Поскольку OCX являются OLE преемниками элементов управления VBX, большинство поставщиков OCX снабжают их примерами исходного кода, демонстрирующие использование синтаксиса Visual Basic (VB), а те, что могут использоваться в программах, написанных на C++, обычно также имеют примеры исходного кода на C++.
Перевод этих примеров в соответствующий код Clarion обычно требует некоторого знания синтаксиса VB или C++. В этом разделе продемонстрированы наиболее общие типы вызовов методов в примерах на VB, а также то, как они переводятся на язык Clarion.
Для вызова любого OLE/OCX метода используется синтаксис описания свойства языка Clarion. Вы определяете тот элемент управления, которому принадлежит метод или свойство, как метку соответствия поля элемента управления OLE, а затем записываете вызов метода в константу типа string внутри фигурных скобок
({}).Пример исходного кода, поставляемый с большинством OLE элементов управления, использует применяемый в VB/C++ синтаксис “точечного свойства”, чтобы задать имя элемента управления, а также вызываемый метод или устанавливаемое свойство. Для примера представлен следующий код VB:
ControlName.AboutBox
который переводится на язык Clarion следующим образом:
?Ole{'AboutBox'}
Этот текст отображает диалог “О программе” (“About”) для элемента управления
ControlName. Этот текст VB примера можно встретить также в следующем виде:Form1.ControlName.AboutBox
В этом случае просто задается диалог, содержащий объект
ControlName. Аналог этого текста на языке Clarion выглядит так же.Ссылка на объект OLE/OCX в тексте Clarion программы всегда осуществляется по метке соответствия поля элемента управления OLE. При этом не имеет значения, какое имя этот элемент управления имеет в модуле, написанном на VB, поскольку зарегистрированное имя объекта определено в атрибуте CREATE или OPEN элемента управления OLE. Таким образом, исполняемая библиотека Clarion для однозначной идентификации объекта, на который осуществляется ссылка, должна знать только метку соответствия используемого при этом поля.
Перевод такой языковой конструкции VB, как “With”
Многие примеры текста OLE/OCX, чтобы связать многократные присвоения свойств и/или вызовы метода с одним отдельным объектом, используют такую структуру VB, как
With ... End With. В этом случае, объект определяется в выражении With, а все присвоения свойств и вызовы методов в пределах этой структуры начинаются с точечного разделителя, а затем уже следует имя устанавливаемого свойства или вызываемого метода. Например, следующий код VB:
With Form1.VtChart1
'displays a 3d chart with 8 columns and 8 rows data
.chartType = VtChChartType3dBar
.columnCount = 8
.rowCount = 8
For column = 1 To 8
For row = 1 To 8
.column = column
.row = row
.Data = row * 10
Next row
Next column
'use the chart as the backdrop of the legend
.ShowLegend = True
End With
переводится на язык Clarion следующим образом:
!
отображает трехмерную таблицу с 8 столбцами и 8 строками данных
?Ole{'chartType'} = VtChChartType3dBar
?Ole{'columnCount'} = 8
?Ole{'rowCount'} = 8
LOOP column# = 1 TO 8
LOOP row# = 1 TO 8
?Ole{'column'} = column#
?Ole{'row'} = row#
?Ole{'Data'} = row# * 10
END
END
!
использует диаграмму в качестве фона для надписи?Ole{'ShowLegend'} = True
Поскольку в языке Clarion отсутствует прямой эквивалент такой структуре VB, как
With ... End With, то при каждом присвоении свойства или вызове метода необходимо только явным образом назвать метку соответствия поля элемента управления OLE. Одиночная кавычка (‘), присутствующая в исходном коде VB, означает начало строки комментария.VB разрешает использование вложенных структур
With ... End With, так, чтобы найти имя объекта, вам возможно придется затем “пропутешествовать” в обратном направлении. Приведенный ниже пример демонстрирует использование вложенных With структур VB:
With MyObject
.Height = 100 '
Эквивалентно MyObject.Height = 100..Caption = "Hello World" '
Эквивалентно MyObject.Caption = "Hello World".With .Font
.Color = Red '
Эквивалентно MyObject.Font.Color = Red..Bold = True '
Эквивалентно MyObject.Font.Bold = True.End With
End With
что переводится на язык Clarion следующим образом:
?Ole{'Height'} = 100 ! MyObject.Height = 100
?Ole{'Caption'} = 'Hello World' ! MyObject.Caption = "Hello World"
?Ole{'Font.Color'} = Red ! MyObject.Font.Color = Red
?Ole{'Font.Bold'} = True ! MyObject.Font.Bold = True
параметров OLE/OCX Методам
Также, как и в Clarion, в VB существует всего два способа передачи параметров: по значению и по адресу (по ссылке). Такие ключевые слова VB, как
ByVal и ByRef, присутствующие в коде VB, определяют эти два метода передачи. Термины эти в VB означают то же самое, что и в Clarion - при передаче параметра по значению передается копия содержимого переменной, при передаче параметра по ссылке (в VB этот способ используется по умолчанию) передается непосредственно адрес переменной, так что принимающий метод может изменять ее содержимое.Использование Круглых скобок
В синтаксисе VB круглые скобки, в которые заключается список передаваемых параметров, могут либо использоваться, либо нет. Если метод VB не возвращает значение, или вы не собираетесь использовать возвращаемое значение, параметры в VB могут передаваться и без круглых скобок, как показано ниже:
VtChart1.InsertColumns 6,3
Если же возвращаемое значение Вам необходимо, то параметры в VB передаются заключенными внутрь круглых скобок, как показано ниже:
ReturnValue = VtChart1.InsertColumns (6,3)
Синтаксис Clarion, однако, всегда требует, чтобы передаваемые параметры были заключены в круглые скобки. Поэтому оба вышеприведенных примера переводятся следующим образом:
?Ole{'InsertColumns(6,3)'}
ReturnValue = ?Ole{'InsertColumns(6,3)'}
Передача Параметров По Значению
В этом случае параметры передаются объектам OLE/OCX в виде строк (кроме Булевых параметров). Поскольку OLE/OCX объекты предполагают приведение поступающих на их вход данных к правильным типам данных путем использования механизма VARIANT (подобно преобразованию типов данных в Clarion), это позволяет достичь большей совместимости при минимальных трудозатратах. Любая строка, требующая знака двойной кавычки (“) должна включать две их (“ “).
Параметры по значению могут быть переданы в методы объекта OLE/OCX как константы или как переменные. Приведенные выше примеры передают параметры как константы. В этих константах, если только они не заключены в двойные кавычки, не могут присутствовать пробелы (например, “Значение с пробелами”).
Существует два способа передачи переменной по значению из Clarion в OLE/OCX метод: связывание в константу типа string, которая используется при вызове метода, или же использование BIND на имя переменной и размещение этого имени переменной непосредственно в константе типа string, которая используется при вызове метода. Например, можно переписать используемую в вышеприведенном примере передачу значений переменных в состыкованной строке:
ColumnNumber = 6
NumberOfColumns = 3
?Ole{'InsertColumns(' & ColumnNumber & ',' & NumberOfColumns & ')'}
!Same as ?Ole{'InsertColumns(6,3)'}
4д
ОПИСАНИЕ ЯЗЫКАВторой способ передачи переменных по значению - это связать их (BIND) и перечислить их имена в константе типа string таким образом, как показано ниже:
BIND('ColumnNumber',ColumnNumber)
BIND('NumberOfColumns',NumberOfColumns)
?Ole{'InsertColumns(ColumnNumber,NumberOfColumns)'}
!Same as ?Ole{'InsertColumns(6,3)'}
Этот метод делает текст программы более удобочитаемым, однако перед передачей значений все передаваемые переменные должны быть связаны (BIND).
Передача Параметров По Адресу (Ссылке)
Параметры, передаваемые по адресу, могут быть переданы методам объекта OLE/OCX только путем задания имен переменных в строке константы. Поэтому необходимо использовать оператор BIND на имена этих переменных и поместить эти имена непосредственно в константе типа string, которая передается методу с предшествующим имени переменной знаком амперсанд, говорящим о том, что переменная передается по ссылке. Например, можно следующим образом переписать вышеприведенный пример для передачи значений переменных по адресу:
ColumnNumber = 6
NumberOfColumns = 3
BIND('ColumnNumber',ColumnNumber)
BIND('NumberOfColumns',NumberOfColumns)
?Ole{'InsertColumns(&ColumnNumber,&NumberOfColumns)'}
Параметры, передаваемые по адресу, передаются объектам OLE/OCX как тип данных связанной переменной (кроме Булевых параметров). Переменные фактически передаются в виде временных строковых переменных, которые автоматически распознаются библиотекой Clarion. Таким образом, любые изменения, внесенные OLE/OCX методом в значение
переданной переменной, отображаются и в обратном направлении, на оригинал переданной переменной.
Булевы Параметры
Булевы параметры (1/0 или Истина/Ложь) могут передаваться как по значению, так и по адресу. При передаче по значению Вы можете применять либо передачу константы (1 или 0, или же такие слова, как TRUE или FALSE), как показано в следующем примере:
Ole{'ODBCConnect(&DataSource,1,&RetVal)'}
?Ole{'ODBCConnect(&DataSource,TRUE,&RetVal)'}
либо передачу имени переменной (после его предварительного связывания (BIND)) внутри вызова “bool()”, как это показано ниже:
BoolParm = 1
BIND('BoolParm',BoolParm)
?Ole{'ODBCConnect(&DataSource,bool(BoolParm),&RetVal)'}
Bool() представляет собой конструкцию, которая сообщает синтаксическому анализатору, что это значение передается как Булевское. Конструкция Bool() может быть использована только внутри строки вызова OLE/OCX метода.
Для передачи по ссылке необходимо внутри конструкции bool() просто пристыковать спереди к имени переменной символ амперсанд, как это показано ниже:
BIND('BoolParm',BoolParm)
?Ole{'ODBCConnect(&DataSource,bool(&BoolParm),&RetVal)'}
Поименованные Параметры
В VB имеется два способа передачи параметров: позиционно или в качестве “поименованного аргумента”. Позиционные параметры подразумевают, что при вызове метода Вы должны либо передать параметр, либо оставить пустыми позиции, соответствующие пропущенным параметрам в разделенном запятыми списке. А так как некоторым методам может передаваться большое количество параметров, то это может привести к возникновению очень длинной строки, состоящей из одних только запятых, в то время как передать методу Вам нужно всего лишь один или два параметра. В VB эта проблема решена путем разрешения программистам “называть” параметры, что
позволяет при вызове метода передать только те немногие параметры, которые выбраны безотносительно к их положению или порядку следования в списке параметров.Поименованные параметры в VB универсальным образом не поддерживаются, так что поставщик OLE/OCX должен предоставить специально предназначенные для их поддержки методы. В файле помощи на OLE/OCX должно быть объявлено, поддерживаются ли поименованные параметры, или же с этой целью Вы можете использовать Окно Просмотра Объектов VB.
Для присвоения значения имени параметра, синтаксисом VB для поименованных параметров предусмотрено использование сочетания символов
:= . Например, для следующего выражения VB:OpenIt(Name:=, [Exclusive]:=, [ReadOnly]:=, [Connect]:=)
можно вызвать метод на VB путем использования позиционных параметров, как здесь:
Db = ?Ole{'OpenIt("MyFile",False,False,"ODBC;UID=Fred")'}
что переводится на язык Clarion (с использованием позиционных параметров) как:.
730 CLARION 4д ОПИСАНИЕ ЯЗЫКАDb = ?Ole{'OpenIt("MyFile",False,False,"ODBC;UID=Fred")'}
Можно вызвать тот же самый метод на VB, используя поименованные параметры, как это показано ниже (подчеркнутый символ представляет собой в VB символ продолжения строки):
Db = OpenIt(Name:="MyFile",Exclusive:=False,ReadOnly:=False, _ Connect:="ODBC;UID=Fred")
что переводится на язык Clarion как:
Db = ?Ole{'OpenIt(Name="MyFile",Exclusive=False,ReadOnly=False, ' & | 'Connect="ODBC;UID=Fred")'}
или же Вы можете передать параметры в VB в другом порядке:
Db = OpenIt(Connect:="ODBC;UID=Fred", _
Name:="MyFile", _
ReadOnly:=False, _
Exclusive:=False")
что переводится на язык Clarion как:
Db = ?Ole{'OpenIt(Connect="ODBC;UID=Fred",Name="MyFile",' & |
'Exclusive=False,ReadOnly=False')'}
(установить контроллер свойств)
OCXREGISTERPROPEDIT(
объект , процедура )
OCXREGISTERPROPEDIT
Установить функцию - контроллер редактирования свойств.
объект Целочисленное выражение, содержащее номер поля или мнемоническая метка соответствия
OLE-объекта к которому относится процедура.процедура Имя функции редактирования свойств объекта
.Процедура
OCXREGISTERPROPEDIT устанавливает процедуру – контроллер редактирования свойств объекта. Она управляет редактированием свойств, запрещая или разрешая редактирование.Пример:
OCXREGISTERPROPEDIT(?OleControl,CallbackFunc)
Смотри также:
Оконные функции
OCXREGISTERPROPCHANGE (установить функцию - редактор)
OCXREGISTERPROPCHANGE(
объект , процедура )
OCXREGISTERPROPCHANGE
Устанавливает процедуру - редактор свойств объекта.
объект Целочисленное выражение, содержащее номер поля или мнемоническая метка соответствия
OLE-объекта к которому относится действие.процедура Имя процедуры изменения свойств объекта
.Процедура
OCXREGISTERPROPCHANGE устанавливает процедуру – редактор свойств объекта. Эта процедура вызывается, когда происходит изменение свойств объекта.Пример:
OCXREGISTERPROPCHANGE(?OleControl,CallbackProc)
Смотри также:
Оконные функции
OCXREGISTEREVENTPROC (установить процедуру обработки событий)
OCXREGISTEREVENTPROC(
объект , процедура )
OCXREGISTEREVENTPROC
Устанавливает для объекта OCX процедуру обработки событий.
объект Целочисленное выражение, содержащее номер поля или мнемоническая метка соответствия
OLE-объекта к которому относится действие.процедура Имя процедуры - обработчика событий для объекта.
Процедура
OCXREGISTEREVENTPROC устанавливает для объекта OCX процедуру обработки событий. К этой процедуре происходит обращение при передаче операционной системой любого события относящегося к данному объекту.Смотри также:
Оконные функции
OCXUNREGISTERPROPEDIT (отменить функцию - контроллер свойств)
OCXUNREGISTERPROPEDIT(
объект )
OCXUNREGISTERPROPEDIT
Деинсталлирует процедуру - контроллер свойств.
объект Целочисленное выражение, содержащее номер поля или мнемоническая метка соответствия
OLE-объекта к которому относится действие.Процедура
OCXUNREGISTERPROPEDIT деинсталлирует процедуру – контроллер свойств для объекта.Пример:
OCXUNREGISTERPROPEDIT(?OleControl)
Смотри также:
Оконные функции
OCXUNREGISTERPROPCHANGE (отменить редактор свойств)
OCXUNREGISTERPROPCHANGE(
объект )
OCXUNREGISTERPROPCHANGE
Деинсталлирует процедуру - редактор свойств.
объект Целочисленное выражение, содержащее номер поля или мнемоническая метка соответствия
OLE-объекта к которому относится действие.Процедура
OCXUNREGISTERPROPCHANGE отменяет процедуру - редактор свойств объекта.
Пример:
OCXUNREGISTERPROPCHANGE(?OleControl)
Смотри также:
Оконные функции
OCXUNREGISTEREVENTPROC (отменить процедуру обработки событий)
OCXUNREGISTEREVENTPROC(
объект )
OCXUNREGISTEREVENTPROC
Деинсталлирует процедуру - обработчик
OCX-события.объект Целочисленное выражение, содержащее номер поля или мнемоническая метка соответствия
OLE-объекта к которому относится действие.OCXUNREGISTEREVENTPROC
отменяет процедуру обработки OCX-событий для объекта.Пример:
OCXUNREGISTEREVENTPROC(?OleControl)
Смотри также:
Оконные функции
OCXGETPARAMCOUNT (получить число параметров для события)
OCXGETPARAMCOUNT(
указатель )
OCXGETPARAMCOUNT
Возвращает число параметров, связанных с текущим событием для объекта OCX.
указатель Метка первого параметра процедуры обработки событий.
Процедура
OCXGETPARAMCOUNT возвращает число параметров, связанных с текущим событием для объекта OCX. Использование этой процедуры допустимо, только когда установлена функция - обработчик событий для объекта OCX.
Возвращаемый тип данных:
USHORT
Пример:
OEvent PROCEDURE(Reference,OleControl,CurrentEvent) !
Процедура обработки событий
Count LONG
Res CSTRING(200)
Parm CSTRING(30)
CODE
IF CurrentEvent <> OCXEVENT:MouseMove !
Отключить события по перемещению мышиRes = 'Control ' & OleControl & ' Event ' & OleControl{PROP:LastEventName} & ':'
LOOP Count = 1 TO OCXGETPARAMCOUNT(Reference) !
Цикл по всем параметрамParm = OCXGETPARAM(Reference,Count) !
получим имя каждого параметраRes = CLIP(Res) & ' ' & Parm !
и соединим их
END
GlobalQue = Res !
Поместим в глобальную очередьADD(GlobalQue) !добавить элемент для последнего
! отображения
END !всех событий OCX и их
RETURN(True) !параметров
Смотри также:
Оконные функции, OCXGETPARAM
OCXGETPARAM (получить строку параметра)
OCXGETPARAM(
указатель ,номер )
OCXGETPARAM
Возвращает значение параметра, связанного с текущим событием, относящимся к объекту OCX.указатель Метка первого параметра процедуры - обработчика событий.
номер Номер выбираемого параметра.
Процедура
OCXGETPARAM возвращает значение параметра с указанным номером для текущего события, связанного с объектом OCX. Использование этой процедуры допустимо, только когда установлена функция - обработчик событий для объекта OCX.Возвращаемый тип данных:
STRING
Пример:
OEvent PROCEDURE(Reference,OleControl,CurrentEvent) !
Процедура обработки событий
Count LONG
Res CSTRING(200)
Parm CSTRING(30)
CODE
IF CurrentEvent <> OCXEVENT:MouseMove !
Отключить события по перемещению мышиRes = 'Control ' & OleControl & ' Event ' & OleControl{PROP:LastEventName} & ':'
LOOP Count = 1 TO OCXGETPARAMCOUNT(Reference) !
Цикл по всем параметрамParm = OCXGETPARAM(Reference,Count) !
получение имени каждого параметраRes = CLIP(Res) & ' ' & Parm !
и соединение их
END
GlobalQue = Res !
Положить в буфер глобальной очередиADD(GlobalQue) !
и добавить элемент в очередьEND !
всех событий OCX и их параметровRETURN(True)
Смотри также:
Оконные функции, OCXSETPARAM, OCXGETPARAMCOUNT(установить строку параметра)
OCXSETPARAM(
указатель ,номер ,значение )
OCXSETPARAM
Устанавливает значение параметра, относящегося к текущему событию, связанному с OCX.указатель Метка первого параметра процедуры - обработчика событий для OCX.
номер Номер параметра, значение которого должно быть установлено.
значение Строковая константа или переменная, содержащая устанавливаемое значение.
OCXSETPARAM
присваивает для текущего события значение параметру, указанному номером . Это допустимо только для параметров, которые передаются “по адресу” (относительно устанавливаемых параметров смотрите руководство по конкретному объекту OCX). Если модификация параметра недопустима, то она игнорируется. Использование этой процедуры допустимо, только когда установлена функция – обработчик событий для объекта OCX.
Пример:
OEvent PROCEDURE(Reference,OleControl,CurrentEvent) !
Процедура обработки событий
Count LONG
Res CSTRING(200)
Parm CSTRING(30)
CODE
IF CurrentEvent <> OCXEVENT:MouseMove !
Отключить события по перемещению мышиRes = 'Control ' & OleControl & ' Event ' & OleControl{PROP:LastEventName} & ':'
LOOP Count = 1 TO OCXGETPARAMCOUNT(Reference) !
Цикл по всем параметрамParm = OCXGETPARAM(Reference,Count) !
взять имя каждого параметраRes = CLIP(Res) & ' ' & Parm !
и соединить их вместе
OCXSETPARAM(Reference,1,'1') !
Изменить значение параметраEND
GlobalQue = Res !
Занести строку в очередьADD(GlobalQue) !
и добавить ее в очередьEND !
всех событий OCX и ихRETURN(True) !параметров
Смотри также:
Оконные функции, OCXGETPARAM
OCXLOADIMAGE (получить графический объект)
OCXLOADIMAGE(
имя )
OCXLOADIMAGE
Возвращает графический объект.имя Строковое выражение, содержащее имя файла или ресурса, который следует загрузить.
Процедура
OCXLOADIMAGE возвращает графический объект. Этот объект можно присвоить любому экранному объекту, который использует графический объект (например, “VB imagelist”).Возвращаемый тип данных:
STRING
Пример:
!
добавить изображение в объект ImageList:?imagelist{'ListImages.Add(,,' & OCXLOADIMAGE('CLOCK.BMP') & ')'}