Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

MB60UG

.pdf
Скачиваний:
12
Добавлен:
13.02.2015
Размер:
1.47 Mб
Скачать

Глава 11: Особенности MapBasic в среде MS Windows

Спроектированное таким образом приложение сможет работать и в 16-разрядной, и в 32разрядной версии MapInfo.

Следующая программа иллюстрирует сказанное. В ней вызываются две процедуры из двух DLL, условно названных TEST16.DLL и TEST32.DLL. (Окончания “16” и “32” вовсе не обязательны.)

Declare Sub Main

Подготовка вызова функции из 32-разрядной DLL.

Предложение ALIAS позволяет вызывать функцию по имени ' MyDLLFunc32.

Declare Function MyDLLFunc32 Lib ”C:\MI\Test32.DLL”

Alias ”MyDLLFunc” () As Integer

Подготовка вызова функции из 16-разрядной DLL.

Предложение ALIAS позволяет вызывать функцию по имени ' MyDLLFunc16.

Declare Function MyDLLFunc16 Lib ”C:\MI\Test16.DLL”

Alias ”MyDLLFunc” () As Integer

Sub Main

Dim i_system, i_returned As Integer

i_system = SystemInfo(SYS_INFO_MIPLATFORM)

Do Case i_system

Case MIPLATFORM_WIN16

i_returned = MyDLLFunc16()

Case MIPLATFORM_WIN32

i_returned = MyDLLFunc32()

Case Else

Note ” Windows DLL не поддерживаются этой платформой.”

End Case

End Sub

Эта программа использует 16-разрядную или 32-разрядную DLL в зависимости от того, в какой версии MapInfo программа запущена.

Если Вы используете DLL для хранения иконок и/или курсоров (для кнопок инструментальных панелей и самих инструментов), Вы можете использовать аналогичный прием. Но синтаксис несколько изменится: вместо объявления Declare ссылка на ресурсы из DLL производится при помощи предложения File в операторе Create ButtonPad, как показано в следующем примере.

195

Глава 11: Особенности MapBasic в среде MS Windows

Declare Sub Main

Declare Function getDLLname() As String

Declare Sub DoIt

Sub Main

Dim s_dllname As String

s_dllname = getDLLname()

Create ButtonPad ”Новая” As

ToolButton Calling doit

Icon 134 File s_dllname

Cursor 136 File s_dllname

End Sub

Function getDLLname() As String

If SystemInfo(SYS_INFO_MIPLATFORM)

= MIPLATFORM_WIN32 Then getDLLname = ”..\icons\Test32.DLL”

Else

getDLLname = ”..\icons\Test16.DLL” End If

End Function

Sub DoIt

’процедура будет вызвана, если пользователь

’ нажмет на кнопку...

End Sub

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

этой главе.

Советы по работе с DLL

Следующие советы могут пригодиться, если при работе с Вашими DLL-библиотеками

возникают ошибки.

Если Вы используете язык C++ для написания DLL, учтите, что компилятор этого языка автоматически добавляет к названию функций дополнительные символы. Вам следует указать компилятору не производить эту операцию над именами экспортируемых функций (как в языке C).

 16–разрядной версии Windows некоторые DLL соответствуют соглашению о передаче параметров языка Pascal (ключевое слово“__pascal”), а другие - языка C (ключевое слово “__cdecl”). MapBasic предполагает, что используется первое соглашение.

Компилятор Microsoft C (32–битный) поддерживает три типа передачи параметров: «стандартный» (ключевое слово “__stdcall”), «C» (ключевое слово “__cdecl”) «быстрый вызов» (ключевое слово “__fastcall”). Вызываемые из MapBasic процедуры не должны использовать третье соглашение.

196

Глава 11: Особенности MapBasic в среде MS Windows

Если возникли проблемы при передаче созданных Вами типов данных (структур), проверьте, что структуры данных C «упакованы» (выровнены по границе байта).

MapBasic может передавать аргументы как ссылкой (по умолчанию), так значением. Однако, передача аргументов значением для разных компиляторов несколько отличается (например, передача типа double). Может оказаться более надежным передавать аргумент ссылкой; в этом случае передается адрес и меньше оснований ожидать неожиданностей.

Следует придерживаться следующего правила: каждая функция из DLL сама выделяет для себя и освобождает память.

Важно, чтобы объявление Declare было корректным, передаваемые параметры должны быть описаны в соответствии с “устройством” вызываемой из DLL функции (в частности, следует обратить внимание на передачу аргументов ссылкой или значением).

Создание пиктограмм на кнопках и новых курсоров

Средства языка MapBasic позволяют управлять инструментальными панелями MapInfo. Подробно об этом можно прочитать в главе 6.

Вы можете создавать свои кнопки и на каждую кнопку можно поместить пиктограмму. В каждой вычислительной среде поддерживается своя процедура создания кнопок и пиктограмм. В среде Windows пиктограммы помещаются как BMP-ресурсы в DLL-файлы; в среде Macintosh пиктограммы помещаются в PICT-ресурсах; в среде UNIX пиктограммы помещаются в XPM-файлах. В этой главе описано, как создавать пиктограммы в MapInfo для Windows.

Программа MapBasic может также создать свой курсор (изображение указателя мыши для окна Карты или Отчета, например). В этом разделе описано, как создавать курсоры в MapInfo для Windows.

Использование стандартных пиктограмм (иконок)

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

Чтобы посмотреть на встроенные пиктограммы, запустите программу Icon Sampler (ICONDEMO.MBX). Вот одна из создаваемых этой программой инструментальных панелей.

197

Глава 11: Особенности MapBasic в среде MS Windows

Каждая такая пиктограмма имеет свой числовой код. Список кодов есть в файле ICONS.DEF. Программа ICONDEMO.MBX покажет этот код, если задержать на некоторое время указатель мышки над кнопкой.

Создание пиктограмм для Windows

Для создания пиктограмм для MapInfo для Windows Вам понадобится редактор ресурсов. Среда разработки MapBasic не содержит редактора ресурсов, однако MapBasic воспринимает ресурсы, созданные внешними редакторами ресурсов, например, пиктограммы можно создавать программой AppStudio (редактор ресурсов из пакета Microsoft Visual C).

В среде Windows новые пиктограммы помещаются в файле DLL. Перед тем как разрабатывать свои пиктограммы, нужно создать DLL-файл или воспользоваться имеющимся. Такой DLL-файл может быть “пустышкой" (т.е. файл, который не содержит никаких процедур).

Для пиктограммы на кнопке можно создать две растровые картинки. Первая картинка должна быть размером 18 пикселов в ширину на 16 пикселов в высоту; эта картинка предназначена для показа на экране с относительно низким разрешением. Вторая картинка имеет размеры 26 на 24 пикселов; она предназначена для экранов с высоким разрешением (например, 1024 x 768). Вы должны обязательно создать обе картинки, даже если одна Вам не нужна. В MapInfo можно включать режим “Большие кнопки” в диалоге команды НАСТРОЙКИ > ÈНСТРУМЕНТАЛЬНЫЕ ПАНЕЛИ.

Создание пиктограммы состоит из следующих этапов:

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

Открыть этот DLL-файл в редакторе ресурсов, таких, как AppStudio.

Для каждой пиктограммы создать две растровые картинки (BMP-ресурс): одну размером 18 пикселов в ширину на 16 пикселов в высоту и другую размером 26 на 24 пикселов.

Не забывайте, что создается ресурс типа “курсор”, а не “иконка”.

Назначить последовательные номера (ID) обоим растровым ресурсам. Например, если Вы назначили ID равный 100 картинке 18 X 16 пикселов, то картинке 26 x 24 пикселов нужно присвоить ID-номер равный 101.

Создав пару растровых ресурсов, Вы можете в приложении MapBasic использовать их с помощью операторов Create ButtonPad è Alter ButtonPad. Из текста программы Вы должны обращаться к меньшей (18 на 16) картинке. Например, если Вы назначите IDномера 100 и 101 новой пиктограмме, то программа должна обращаться к номеру 100, как показано в следующем примере:

Alter ButtonPad "Программы"

Add PushButton

Icon 100 File "MBICONS1.DLL"

HelpMsg "Добавить новую запись"

Calling new_route

Show

198

Глава 11: Особенности MapBasic в среде MS Windows

DLL-файл, в котором помещаются пиктограммы (в примере выше это MBICONS1.DLL), должен быть установлен в Вашей системе по одному из следующих маршрутов: в том же каталоге, что и MBX-файл, который его использует; в личном каталоге пользователя; в каталоге, содержащем пакет файлов MapInfo; в каталогах WINDOWS или WINDOWS\SYSTEM. Если MapInfo не находит DLL-библиотеку ни в одном из этих каталогов, то поиск продолжается по каталогам, описанным в системной переменной PATH.

Вы можете, разумеется, явно указать каталог.

Функции ProgramDirectory$( )è ApplicatopnDirectory$( ) помогут Вам построить нужные имена каталогов из MBX-программы.

Создание новых курсоров в Windows

Процесс создания нового курсора почти в точности повторяет процесс создания пиктограммы, описанный выше. Курсор, правда, имеет несколько особенностей, например, “точку указывания” (“hot spot").

Новый курсор помещается в виде CURSOR-ресурса в DLL-файл. Вы можете помещать в один DLL-файл как CURSOR-ресурсы, так и BMP-ресурсы.

Связь между приложениями с использованием DDE

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

Если два приложения Windows оба поддерживают DDE, приложения могут обмениваться командами и данными. Например, Windows-программа типа Microsoft Excel, может дать команду MapInfo (например, Map From world).

Обзор DDE-обмена

DDE-связь – процесс, который может происходить между двумя приложениями Windows. Оба приложения должны быть запущены, и оба должны поддерживать протокол DDE. В одном сеансе обмена могут участвовать только две программы; однако, программы (MapInfo, Excel и другие) могут одновременно участвовать во многих сеансах.

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

MapBasic как DDE-клиент

Язык MapBasic поддерживает следующие операторы и функции, позволяющие приложению MapBasic действовать как клиент при DDE-обмене.

199

Глава 11: Особенности MapBasic в среде MS Windows

DDEInitiate( )

Открывает сеанс обмена;

DDERequest$( )

Запрашивает информацию у сервера;

DDEPoke

Посылает информацию серверу;

DDEExecute

Посылает серверу команды;

DDETerminate

Закрывает один или все сеансы DDE-обмена.

DDETerminateAll

 

См. также описание этих операторов и функций в Справочнике MapBasic.

Для того, чтобы начать сеанс DDE-обмена, нужно вызвать функцию DDEInitiate( ). Функции DDEInitiate( ) нужно задать два параметра: имя приложения application è

название объекта topic.

Обычно параметр application – это имя сервера (например, имя “Excel” при DDE-обмене обозначает Microsoft Excel). Список параметров topic зависит от программы. Обычно, параметром topic бывает имя файла или документа, открытого программой-сервером.

Например, пусть в Excel открыта таблица TRIAL.XLS, тогда приложение MapBasic может начать сеанс обмена следующими операторами:

Dim channelnum As Integer

channelnum = DDEInitiate("Excel", "TRIAL.XLS")

В этом примере Excel – имя приложения (application), а TRIAL.XLS – имя объекта (topic).

Многие программы, поддерживающие DDE (и MapInfo тоже), поддерживают специальный объект по имени “System”. Начав сеанс обмена с использованием объекта ”System”, Вы впоследствии можете в этом сеансе получить список всех доступных объектов.

Каждый сеанс DDE обменивается данными через собственный уникальный канал (channel). Функция DDEInitiate( ) возвращает номер канала в виде целого числа. Этот номер в дальнейшем используется другими операторами DDE–обмена.

После установления связи приложение MapBasic может посылать команды серверу посредством оператора DDEExecute. Например, приложение MapBasic может заставить программу-сервер открывать или закрывать файлы.

Используя функцию DDERequest$( ), приложение MapBasic запрашивает информацию у сервера. При вызове DDERequest$( ) нужно определить имя элемента (item), чтобы сервер точно определил, какую именно информацию от него требуют. Например, если сервером является электронная таблица, то запрашиваемым элементом может быть имя ячейки.

Используя функцию DDEPoke, можно посылать информацию программе-серверу. Послание данных из приложения MapBasic через DDE-связь имитирует ввод данных пользователем в соответствующий документ программы-сервера. В следующем примере приложение MapBasic помещает фразу “Привет, друзья!" в ячейку электронной таблицы.

DDEPoke channelnum, "R1C2", "Привет, друзья!"

При вызове функции DDEPoke нужно точно задавать имя элемента, принимающего данные (в примере это R1C2, т.е. Строка 1, Столбец 2).

Когда все работы по DDE-связи выполнены, обмен должен быть завершен клиентом (приложением MapBasic), для чего выполняются операторы DDETerminate èëè

DDETerminateAll. Оператор DDETerminate закрывает один канал DDE-обмена;

200

Глава 11: Особенности MapBasic в среде MS Windows

DDETerminateAll закрывает все DDE-каналы, открытые из данного приложения. При этом другие приложения MapBasic, поддерживающие в это время свои сеансы DDE-обмена, не затрагиваются.

Когда приложение MapBasic является клиентом, то во время работы может порождаться ошибка, если сервер долгое время не отвечает. Время, которое сервер может не отвечать клиенту без порождения ошибки, устанавливается в WIN.INI – стартовом файле Windows. MapInfo создает раздел [MAPINFO] в WIN.INI и задает время задержки в строке DDETimeout:

DDeTimeout=10000

Число представляет собой количество миллисекунд; стандартное значение времени задержки равно десяти тысячам (десять секунд). Если приложение-клиент часто исчерпывает время ожидания в сеансах DDE-связи, и порождается ошибка, Вы можете увеличить значение задержки.

MapInfo в роли DDE-сервера

MapInfo выступает в роли сервера, когда другая Windows-программа начинает сеанс DDEобмена. Программа-клиент может передавать операторы MapBasic, читать значения глобальных переменных MapBasic и изменять их.

Windows-программа, поддерживающая протокол DDE, может выполнять различные действия в MapInfo, такие, как открытие таблиц, показ Карт и Списков. Однако, управляющие операторы MapBasic не могут быть выполнены MapInfo как сервером.

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

Программы и приложения, выступающие в роли DDE-клиентов по отношению к MapBasic, должны задавать параметры application, topic è item, значения которых описаны выше.

Чтобы начать сеанс DDE-связи с MapInfo как с сервером, нужно задать “MapInfo" как значение параметра application.

В качестве параметра topic можно задать “System" или имя действующего в настоящий момент приложения MapBasic (например, “C:\MAPBASIC\GRIDS.MBX"). При этом нужно точно задавать строчные и прописные буквы.

Параметр item зависит от темы (topic). В следующей таблице приведены различные сочетания объектов и элементов, которые можно использовать, если MapInfo выступает в роли DDE-сервера.

Application: “MapInfo”

Topic: “System”

Команды и темы, поддерживаемые в сеансе обмена DDE:

Действие

Параметр item

Результат

 

 

 

201

Глава 11: Особенности MapBasic в среде MS Windows

Действие

Параметр item

Результат

 

 

 

Запрос на

SysItems

На запрос клиента с именем элемента Sysitems

считывание

 

MapInfo возвращает разделенный

данных

 

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

 

 

System: Sysitems Topics Formats

 

 

 

Запрос на

Topics

На запрос клиента с именем элемента Topics

считывание

 

MapInfo возвращает разделенный

данных

 

табуляторами список доступных объектов

 

 

(System и названия всех приложений MapBasic,

 

 

действующих или пребывающих в режиме

 

 

ожидания).

 

 

 

Запрос на

”Formats”

На запрос клиента с именем элемента Formats

считывание

 

MapInfo возвращает список всех

данных

 

поддерживаемых MapInfo форматов обмена

 

 

через Clipboard (TEXT и другие).

Запрос на

”Version”

MapInfo возвращает текстовую строку,

считывание

 

представляющую номер версии MapInfo,

данных

 

умноженный 100. Например, MapInfo 4.0.0

 

 

возвратит "400". См. пример ниже.

 

 

 

Запрос на

Выражение

MapInfo интерпретирует строку как выражение

считывание

MapBasic

MapBasic и возвращает значение в виде строки.

данных

 

Выражение ”If” недопустимо, MapInfo

 

 

возвращает ошибку.

 

 

Эта функциональная возможность появилась в

 

 

MapInfo 4.0.

 

 

 

Execute

Текстовое послание

MapInfo пробует выполнять сообщение как

 

 

оператор MapBasic, словно пользователь

 

 

набрал его в окне MapBasic.

 

 

Оператор не может содержать обращения к

 

 

нестандартным (пользовательским) функциям,

 

 

хотя может содержать обращения к

 

 

стандартным функциям.

 

 

Оператор не может ссылаться на переменные,

 

 

которые определены в оттранслированных

 

 

прикладных программах (.MBХ-файлах). Однако

 

 

оператор может ссылаться на переменные,

 

 

которые были определены при помощи

 

 

оператора Dim в окне MapBasic.

 

 

 

Например, следующая MapBasic-программа, которую Вы можете напечатать непосредственно в окне MapBasic, проводит простой DDE-диалог, используя "MapInfo" как application è "System" êàê topic.

Dim i_channel As Integer

i_channel = DDEInitiate(”MapInfo”, ”System”)

Print DDERequest$(i_channel, ”Version”)

DDETerminate i_channel

202

Глава 11: Особенности MapBasic в среде MS Windows

Функция DDEInitiate( ) начинает сеанс DDE-обмена. Затем функция DDERequest$( )

производит запрос, используя “Version” как item.

Если Вы используете имя приложения MapBasic (например, “C:\MB\SCALEBAR.MBX” или “SCALEBAR.MBX” или “SCALEBAR”) как DDE-topic, Вы можете использовать следующие имена в качестве item:

Application:

“MapInfo”

 

Topic:

Имя запущенной MapBasic-программы

Команды и темы, поддерживаемые в сеансе обмена DDE:

 

 

 

 

 

Действие

Параметр item

Результат

 

 

 

 

 

Запрос на

”{items}”

MapInfo возвращает разделенный символами

 

считывание

 

табуляции список глобальных переменных,

 

данных

 

определенных в приложении. См. пример

 

 

 

 

 

 

íèæå.

 

 

 

 

 

Запрос на

Имя глобальной

MapInfo возвращает строку,

 

считывание

переменной

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

 

данных

 

переменной.

 

 

 

 

 

 

 

 

Запрос на

Строка, не

Если приложение MapBasic содержит

 

считывание

являющаяся именем

функцию с именем

 

данных

глобальной

RemoteQueryHandler( ), MapInfo вызовет ее.

 

 

переменной

 

 

Внутри тела функции можно определить имя

 

 

 

 

 

 

item посредством вызова:

 

 

 

CommandInfo(CMD_INFO_MSG)

 

 

 

Это новое свойство в MapInfo 4.0.

 

 

 

 

 

Поместить

Имя глобальной

MapInfo изменит значение переменной на

 

данные (Poke)

переменной.

новое.

 

 

 

 

 

Execute

Текстовое послание

Если в приложении MapBasic есть процедура

 

 

 

с именем RemoteMsgHandler, MapInfo

 

 

 

вызовет ее. Внутри тела процедуры можно

 

 

 

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

 

 

 

помощи вызова

 

 

 

CommandInfo(CMD_INFO_MSG).

 

 

 

 

Например, следующая программа MapBasic, которую Вы можете напечатать непосредственно в MapBasic-окне, проводит простой DDE диалог, используя "SCALEBAR.MBX" как topic.

При помощи этого диалога выводится список глобальных переменных, используемых приложением SCALEBAR.MBX. Обратите внимание: Этот диалог будет только работать, если приложение SCALEBAR.MBX уже выполняется.

Dim i_channel As Integer

i_channel = DDEInitiate(”MapInfo”, ”SCALEBAR.MBX”)

203

Глава 11: Особенности MapBasic в среде MS Windows

Print DDERequest$(i_channel, ”{items}” )

DDETerminate i_channel

Как MapInfo обрабатывает сообщение DDE-Execute

Имеются два способа, которыми клиентское приложение может посылать MapInfo запрос на выполнение действий:

Когда DDE-диалог использует " System " как topic и клиентское приложение посылает запрос на выполнение действия, MapInfo пробует выполнять определенное сообщение как оператор MapBasic.

Когда диалог использует имя приложения MapBasic как topic, и клиент посылает запрос на выполнение действия, MapInfo вызывает процедуру

RemoteMsgHandler приложения, которая может затем вызывать

CommandInfo () чтобы определить текст сообщения.

Приложение MapBasic может действовать как клиент в одном DDE-диалоге, и одновременно как сервер в другом диалоге. Приложение MapBasic может инициализировать диалог с другим приложением MapBasic или непосредственно с MapInfo.

Связь с приложениями Visual Basic с использованием DDE

Программист может расширить возможности MapBasic за счет более мощного языка Microsoft Visual Basic. Например, можно создавать средствами Visual Basic диалоговые окна более сложные, чем позволяет оператор MapBasic Dialog. Например, Visual Basic позволяет добавлять управляющие элементы диалога, которые нельзя задать оператором

Dialog.

Приложение MapBasic может связываться с приложением Visual Basic с использованием DDE (или автоматизации OLE). Более подробная информация приведена в главе 12.

Пример DDE-обмена

Пример чтения/записи в таблицу Excel с помощью DDE-связи приведен в описании функции DDEInitiate( ) â Справочнике MapBasic.

Программа Watcher (WATCHER.MB), поставляемая вместе с пакетом, содержит более сложный пример DDE-обмена. WATCHER используется при отладке: если Вы запустили приложение MapBasic и следом за ним программу Watcher, то последняя открывает таблицу в Excel и помещает в нее текущие значения глобальных переменных приложения, подвергаемого отладке. Другими словами, WATCHER позволяет просматривать глобальные переменные программы в таблице Excel.

Программа WATCHER проводит несколько сеансов DDE-обмена:

Сначала WATCHER проводит сеанс DDE-обмена, используя “MapInfo" и “System" как параметры application è topic, и запрашивает список действующих приложений MapBasic. Затем WATCHER показывает диалоговое окно, в котором Вы можете выбрать одно из приложений для отладки.

204

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]