Создание DLL-библиотеки для работы с Word/Excel из приложений на Delphi
Создание DLL-библиотеки для работы с Word/Excel из приложений на Delphi Если вы хотите и готовы предложить своим коллегам свои собственные API-функции для работы с документами Word и Excel, то эта статья вам очень пригодится. Весь набор функций, который рассмотрен в статьях №1 и №2, можно реализовать в виде DLL-библиотеки. Реализация в виде DLL дает большие преимущества программисту в гибкости, надежности использования своих программных продуктов и сокращает время на разработку программного обеспечения. В своих библиотеках вы можете заложить базовые функции, которые не будут изменяться довольно часто, при этом основное приложение, которое использует библиотеки, может меняться достаточно часто и совершенствоваться от версии к версии. Функции, оформленные в виде DLL, называются иначе - API-функциями. Система Windows использует как системные, так и пользовательские функции API. Если вы решите создавать библиотеку для работы с Word.Application (Excel.Application), то столкнетесь с некоторыми особенностями, которые укладываются в общее представление о создании динамических библиотек. Эти особенности связаны с преобразованием формата данных, передаваемых через механизм DDE. Приступим к созданию нашей библиотеки (назовем ее MyLWord). Выполним команду меню "File" -> "New..." . В открывшемся окне выберите закладку "New" и далее пиктограмму "DLL", нажмите кнопку "OK". Получим новый проект. Его название изменим на MyLWord и сохраним под тем же именем. Используем нашу библиотеку MyWord, которая была создана ранее (см. "Суперфункции 1.5"). Изменим эту библиотеку, дописав в конец объявления каждой процедуры в секции interface ключевое слово StdCall, которое определяет соглашение о передаче параметров через стек. В файле проекта MyLWord.dpr в секцию подключения внешних модулей uses допишем ссылку на библиотеку MyWord. После секции uses создадим секцию экспортируемых процедур и функций, напишем ключевое слово exports, после которого через запятую перечислим список всех экспортируемых процедур и функций. Если откомпилировать этот проект, то получим файл динамической библиотеки MyLWord.dll. Ниже представлены фрагменты перечисленных выше файлов. Файл - MyLWord.dpr
uses
SysUtils,
Classes,
MyWord;
{$R *.RES}
exports
CreateWord,
VisibleWord,
................,
GetNameIndexShape;
Begin
// Секция инициализации модуля, можно вставлять функции,
которые должны выполняться при загрузке модуля,например
начальная загрузка данных, которые будут использоваться
всеми функциями и процедурами модуля.
end.
Файл - MyWord.pas
interface
const
wdBorder=-1;
......................
wdLineStyleEngrave3D=22;
Function CreateWord:boolean; StdCall
Function VisibleWord(visible:boolean):boolean; StdCall
.........................................
Function SetNewNameShape(NameShape:variant;
NewNameShape:string):string; StdCall
Function GetNameIndexShape(NameIndex:variant):string; StdCall
var W:variant;
implementation
uses ComObj;
Function CreateWord: boolean;
begin
CreateWord:=true;
try
W:=CreateOleObject ('Word.Application');
.........................................
Function DeleteShape (NameShape:variant): variant;
Begin
DeleteShape:=true;
try
W.ActiveDocument.Shapes.Item(NameShape).Delete;
except
DeleteShape:=false;
end;
end;
end.
После создания динамической библиотеки процедур и функций рассмотрим ее использование. Для этого возьмем пример, описанный в предыдущих статьях "Суперфункции". Любую динамическую библиотеку можно использовать двумя основными способами: загрузка библиотеки при старте EXE-модуля и динамическая загрузка, которая выполняется в местах программы, там, где это необходимо. Преимущество первого метода заключается в простоте написания кода, второго - в гибкости, например, в зависимости от каких-либо условий программы можно загружать различные модули, содержащие одинаковые функции. Если используется первый вариант, то при отсутствии модуля DLL программа просто не загрузится, при втором варианте программа загрузится, но в местах вызова модуля будет сгенерирована ошибка, которую можно обработать.
Рассмотрим подробнее вариант загрузки модуля DLL при старте программы, которая его использует. Если вы хотите использовать какую-либо функцию динамической библиотеки, то достаточно в модуле, где будет использоваться функция, добавить строку объявления такого типа:
Function (Procedure) <Имя функции (процедуры)>(<список переменных и типов>): <возвращаемое значение>; external '<Имя файла библиотеки с расширением>' name ' Имя функции или процедуры ';
Конкретные примеры:
external 'MyLWord.dll' name 'CreateWord';
Function VisibleWord(visible:boolean):boolean;
external 'MyLWord.dll' name 'VisibleWord';
.........................
Begin
.....................
if CreateWord then VisibleWord(true);
.....................
End.
Для объявления функций и процедур динамической библиотеки удобно использовать отдельный модуль Unit. В таком модуле в секции interface перечисляются функции и процедуры с указанием имен, параметров и типов возвращаемых значений как в обычном модуле, в секции implementation они описываются с указанием на модули (имена файлов) DLL и оригинальные имена. Например:
interface
Function CreateWord: boolean; StdCall
Function VisibleWord (visible:boolean):boolean; StdCall
.........................................
Implementation
Function CreateWord:boolean;
external 'MyLWord.dll' name 'CreateWord';
Function VisibleWord (visible:boolean):boolean;
external 'MyLWord.dll' name 'VisibleWord';
.........................................
End.
Чтобы использовать данный модуль в приложении, достаточно указать на него ссылку в секции uses. Рассмотрим пример:
.........................................
Begin
// Выполним загрузку Word'а, вызвав необходимые функции.
if CreateWord then VisibleWord(true);
end;
Рассмотрим динамическое выполнение процедур и функций модуля DLL. Для динамической загрузки и выполнения необходимо определить типы вызываемых процедур (функций), загрузить библиотеку DLL, получить адреса входа в процедуру (функцию), выполнить процедуру (функцию) и выгрузить библиотеку.
Для этого рассмотрим следующий пример:
функции CreateWord и VisibleWord. В секции type
определим их типы, они должны совпадать с оригиналом
в модуле DLL.
type
TCreateWord=function: boolean;
TVisibleWord=function (visible:boolean):boolean;
//В разделе описания переменных определим переменную
hdll:thandle, через которую будем обращаться к функциям
работы с библиотекой, и переменные - ссылки на процедуры
динамической библиотеки.
var hdll:thandle;
CreateWord:TCreateWord;
VisibleWord:TvisibleWord;
Begin
//В секции кода выполним загрузку модуля (библиотеки)
и получим ее handle.
hdll:=LoadLibrary ('MyLWord.dll');
//Получим точки входа в функции.
CreateWord:=GetProcAddress (hdll,'CreateWord');
VisibleWord:=GetProcAddress (hdll,'VisibleWord');
// Выполним загрузку Word'а, вызвав необходимые функции.
if CreateWord then VisibleWord(true);
// Выгрузим библиотеку (очистим память от библиотеки).
FreeLibrary(hdll);
end;
Как видно, динамическая загрузка библиотеки немного сложнее, но, несмотря на это, она оправдывает себя. Используя данный материал, вы сможете создать и использовать свою персональную динамическую библиотеку для работы с редакторами Word и Excel. Полные исходные тексты с примерами смотрите по адресу www.kornjakov.ru/st3_1.zip. По всем вопросам можете обратиться к автору по адресу _kvn@mail.ru или www.kornjakov.ru.
Василий КОРНЯКОВ
Литература: Марко Кенту "Delphi 6 " "Питер" 2002.
Ув. Василий, не знаю, прямо как и писать мой вопрос. Я прочитал вашу хорошую лекцию по работе в Дельфи с Word/excel (c API). Но мне требуется наоборот: создать myf(x).dll в Дельфи, а дальше вызвать её в таблицу рабочего листа Excel. Я прочитал одну вредную книжку A. Леоненков, "Решение задач оптимизаци....". В ней излагается технология создания .dll с последующим использованием в Excel.Всё просто: создать f(x).pas-->myf(x).dll сохранить в Window/system и всё. И ВЫЗВАТЬ её в Excel с помощью мастера fx. Мне именно это и требуется. Сделал. И ничего не работает! Вопрос: как правильно вызвать myf(x).dll из Excel 2007. Пожалуйста, напишите самый,самый простой код вызова.Подробно. Вы ведь наверняка это знаете!
Добрый день..Лекция конечно хорошая.. но ничем не отличающаяся от статей на других сайтах (один в один). Это конечно печально. Выполним команду меню "File" -> "New..." . В открывшемся окне нет закладки "New" и тем более пиктограммы "DLL". И что же делать????
Отправить комментарий