Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
2006 г.

WinApi
Лекция из курса «Основы офисного программирования и язык VBA»

Биллиг Владимир Арнольдович
Интернет-Университет Информационных Технологий, 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, следует в первую очередь упомянуть три основные библиотеки:

  1. Kernel32.dll. Эта библиотека предназначена для работы с объектами ядра операционной системы и ее функции позволяют управлять памятью и другими системными ресурсами.
  2. User32.dll. Здесь сосредоточены функции для управления окнами - основным видом объектов операционной системы. Обработка сообщений, работа с меню, таймерами, все это выполняют функции этой DLL.
  3. 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 возвращаемый-тип]

В этих вызовах ключевые слова и параметры имеют следующий смысл:

  • Ключевое слово Public используется, чтобы сделать объявляемую процедуру доступной всем модулям проекта; ключевое слово Private ограничивает доступ к объявленной процедуре лишь модулем, в котором она объявлена. Заметьте, в стандартном модуле можно использовать оба описателя, но в модуле класса разрешается использовать только описатель Private.
  • Ключевое слово Sub в первом случае означает, что речь идет о процедуре; альтернативный ключ Function во втором случае указывает на функцию, возвращающую значение, которое может быть использовано в выражениях.
  • Обязательный параметр имя является именем объявляемой процедуры или функции. Это имя используется при вызовах в VBA программах. Оно может совпадать или отличаться от того имени, под которым процедура (функция) хранится в DLL. Заметьте, для имен функций Win32 API в отличие от Win 16 имеет значение различие между прописными и строчными буквами.
  • После обязательного ключевого слова Lib должно следовать в кавычках имя-библиотеки, содержащей объявляемую процедуру.
  • Ключ Alias позволяет указать, что процедура имеет в DLL другое имя - "псевдоним", благодаря чему можно избежать коллизии имен в программе. Если первый символ параметра " псевдоним" не является признаком числа ( #), псевдоним понимается как имя входной точки DLL для данной процедуры; если же первый символ псевдонима - ( #), следующие за ним число должно задавать порядковый номер входной точки процедуры в DLL. Дело в том, что процедура может иметь несколько точек входа.
  • Необязательный список параметры задает список параметров, передаваемых процедуре при вызове.
  • As возвращаемый-тип во втором варианте оператора задает тип значения, возвращаемого функцией; им может быть любой из базисных типов VBA (не допускаются только строки фиксированной длины), тип объекта или определенный пользователем тип.
  • Список параметры - это список разделенных запятыми параметров процедуры; каждый элемент этого списка имеет вид:
    [Optional] [ByVal | ByRef] [ParamArray] переменная[()] [As тип]
    
  • Здесь ключ Optional означает, что данный параметр необязателен; при этом все следующие в списке параметры должны быть необязательными и сопровождаться этим же ключом Optional. Этот ключ нельзя применять, если среди параметров есть массив параметров ParamArray.
  • Ключевые слова ByVal и ByRef указывают на то, что параметр передается по значению или по ссылке; по умолчанию в VBA предполагается передача значения по ссылке (ByRef).
  • Ключевое слово ParamArray позволяет задать массив элементов типа Variant; этот параметр должен быть последним в списке и не должен перед собой иметь ключей ByVal, ByRef или Optional; такой массив позволяет передавать в процедуру произвольное (заранее неизвестное) число параметров.
  • Переменная - произвольное допустимое в VBA имя переменной; пустые скобки () после имени переменной означают, что соответствующий параметр - массив.
  • Необязательное определение As тип задает тип параметра, значения которого могут быть такими же, как и у описанного выше определения возвращаемый-тип. Задав произвольный тип (As Any), Вы исключите проверку при передаче параметра процедуре.

Вот пример задания оператора 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, описать необходимые типы и константы, - все это может быть не столь простой задачей.

Оглавление Вперёд

Новости мира IT:

Архив новостей

Последние комментарии:

Loading

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 985 1945361
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2015 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...