2006 г.
Биллиг Владимир Арнольдович
Интернет-Университет Информационных Технологий, INTUIT.ru
Оглавление
Программный код большинства примеров данной лекции можно найти в проектах, доступных для просмотра: DocOne6, DocTwo6.
Несколько слов об API, Win32, DLL
API (Application Programming Interface - интерфейс прикладных программ) - это множество функций, организованных, обычно, в виде DLL
. Функции API позволяют организовать интерфейс между прикладной программой и средой, в которой работает эта программа. Вызов функций API позволяет программе получать доступ к ресурсам среды и управлять ее работой. Как правило, API задает стандарт взаимодействия среды и прикладной программы.
Win32 - это название интерфейса, ориентированного на 32-х разрядные приложения и реализованного на таких известных платформах как Windows 95, Windows 98, Windows NT, Windows CE. Функции, составляющие этот интерфейс, позволяют прикладной программе получать доступ к ресурсам операционной системы и управлять ее работой. Более ранние версии Windows используют интерфейс, известный как Win16. Конечно, не все функции, составляющие интерфейс Win32, реализованы в полной мере на всех платформах, так что вызов одной и той же функции под NT приведет к определенному результату, а под Windows 95 работает как вызов заглушки. Любое из приложений, работающее в среде Windows, прямо или косвенно вызывает функции, входящие в Win32 API.
Функции, составляющие Win32 интерфейс, организованы в виде нескольких динамически подключаемых библиотек (DLL
) и исполняемых файлов. Говоря о Win32 API, следует в первую очередь упомянуть три основные библиотеки:
- Kernel32.dll. Эта библиотека предназначена для работы с объектами ядра операционной системы и ее функции позволяют управлять памятью и другими системными ресурсами.
- User32.dll. Здесь сосредоточены функции для управления окнами - основным видом объектов операционной системы. Обработка сообщений, работа с меню, таймерами, все это выполняют функции этой
DLL
. - GDI32.dll. Эта библиотека, обеспечивающая графический интерфейс операционной системы (Graphics Device Interface). Функции управления выводом на экран дисплея, управления выводом принтера, функции для работы со шрифтами - все они входят в состав этой библиотеки.
Заметьте, Win API функции находятся не только в этих библиотеках. С другой стороны API функции не обязательно входят в состав Win32 интерфейса. Например, MAPI интерфейс (Messaging Application Programming Interface) составляют функции, предназначенные для обработки сообщений электронной почты, TAPI (Telephone API) - функции работы с телефонными сообщениями. MAPI, TAPI, также как и Win32 это некоторый набор функций, задающий определенный стандарт взаимодействия
Как мы уже говорили, функции, образующие API, обычно, организованы в виде DLL
- динамически подключаемых библиотеках. Одно из достоинств DLL
состоит в том, что, сколько бы приложений (процессов) не работало с функциями одной и той же DLL
, код DLL
существует в единственном экземпляре.
.VBA и Win32 API
Работая на VBA, неявно всегда приходится иметь дело с функциями Win32 API, только вызов их упрятан в вызываемых VBA функциях или методах объектов Office 2000. Так, например, при работе с объектом Shape
так или иначе будут вызываться функции GDI32, обеспечивающие работу с графикой, при работе c функциями VBA.Interaction
, например GetSettings
, SaveSettings
и другими, будет вызываться соответствующие функции работы с реестром Windows, хранящиеся в библиотеках User32
и advapi32
. Такой косвенный вызов имеет свои преимущества, обеспечивая определенную безопасность в работе VBA программ. Но в ряде случаев VBA программисту необходим доступ ко всем возможностям операционной системы, предоставляемым Win32 API интерфейсом. Естественно, в этом случае он понимает, что на него ложится большая ответственность в обеспечении корректного вызова функций, поскольку ошибки в вызове могут привести к непредвиденным отказам в работе программы.
Вызов функций и оператор Declare
Элементы ActiveX
, COM
объекты могут экспонировать свой интерфейс, - свои свойства и методы. Это означает, что они уведомляют, предоставляют информацию клиентам о своем интерфейсе. Технически это обеспечивается тем, что эти объекты, наряду с DLL
, сопровождаются TypeLib
- библиотекой типов, в которой содержится в требуемом виде информация об интерфейсе объекта. В этом случае, для того чтобы начать работу с объектом, достаточно подключить ссылку на эту библиотеку в меню Tools|References в среде редактора VBE. Эта возможность не раз обсуждалась, когда речь шла о вызове, например, приложения Excel в документах Word. Напомним, что приложения Office 2000 представляют собой ActiveX
объекты, построенные на основе COM
технологии. Они явно экспонируют свой интерфейс, именно поэтому нет проблем при работе с такими приложениями, вызовами свойств и методов их многочисленных объектов. Библиотеки, составляющие Win32 интерфейс, не сопровождаются библиотеками типов TypeLib
. Поэтому необходимо самому программисту уведомить VBA о том, где найти и как следует вызывать ту или иную функцию Win32 API Вызову каждой функции должен предшествовать оператор Declare
, описывающий эту функцию. Этот оператор и сама схема вызова библиотечных функций используется при работе с любыми DLL
, а не только с теми, которые содержат Win32 API функции. В общем случае в DLL
могут храниться как функции, так и процедуры. Два варианта вызова этого оператора соответствуют ссылке на процедуру и на функцию, возвращающую значение. Первый вариант:
[Public | Private] Declare Sub имя Lib "имя-библиотеки" [Alias "псевдоним"] [([параметры])]
Во втором случае его синтаксис:
[Public | Private] Declare Function имя Lib "имя-библиотеки" [Alias "псевдоним"]
[([параметры])] [As возвращаемый-тип]
В этих вызовах ключевые слова и параметры имеют следующий смысл:
Вот пример задания оператора Declare
для двух функций Win32 API:
Private Declare Function CreateRectRgn Lib "gdi32" Alias "CreateRectRgn" _
(ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function GetTempPath Lib "kernel32" _
Alias "GetTempPathA" (ByVal nBufferLength As Long, _
ByVal lpBuffer As String) As Long
Синтаксически оператор Declare
прост и понятен, нужно указать библиотеку, имя функции, под которым она будет вызываться в VBA программе, ее имя (псевдоним) под которым она записана в библиотеке и параметры функции в привычном синтаксисе. Однако реальная жизнь не так проста и в организации вызова функций API есть много подводных камней. Дело в том, что DLL
служат средством межязыкового взаимодействия. Сама DLL
может быть разработана на одном языке, а вызываться в другом. Тогда возникает проблема правильной передачи параметров, поскольку может не быть точного соответствия между типами данных двух используемых языков. Функции Win32 API разработаны в ориентации на синтаксис языка C и C++. Поэтому при записи оператора Declare
требуется корректно указать типы параметров, так чтобы они соответствовали типам, используемым в языке C. Еще одна проблема состоит в том, что помимо оператора Declare
, в ряде случаев необходимо предварительно описать требуемые типы данных и константы, необходимые в процессе вызова функции. Так что, прежде чем вызвать функцию из DLL
, необходимо корректно задать оператор Declare
, описать необходимые типы и константы, - все это может быть не столь простой задачей.
Оглавление Вперёд