В DLL-библиотеке можно хранить не только процедуры и функции, но и экранные формы с визуальными компонентами. Это позволяет в полной мере реализовать модульную структуру программы, когда к головному модулю подсоединяются DLL, реализующие те или иные возможности. По такому принципу строятся многие расширяемые системы, к которым можно добавлять все новые и новые модули.
Добавим форму в проект geta.dll. Активируем его и создадим новую форму (команда меню FileàNewàForm). Сохраним созданный файл в директории Z:\111111\Иванов\DLL под произвольным именем, скажем, main.pas. Переименуем созданную форму (свойство Name) в DLLForm. В файле main.pas в разделе IMPLEMENTATION опишем процедуру:
PROCEDURE ShowModalForm;
BEGIN
DLLForm := TDllForm.Create(Application);
DLLForm.ShowModal;
DLLForm.Free
END;
Данная процедура выполняет трюк барона Мюнхгаузена с поднятием самого себя за волосы: она создает форму DLLForm (метод Create), отображает ее (метод ShowModal) и после закрытия пользователем выгружает из памяти (метод Free).
В раздел описаний надо добавить заголовок процедуры ShowModalForm, чтобы она была доступна из файла geta.dll:
type
TDLLForm = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
procedure ShowModalForm;
var
DLLForm: TDLLForm;
implementation
…
В файле geta.dll в раздел EXPORTS добавляем имя экспортируемой процедуры ShowModalForm:
EXPORTS
ShowModalForm, GetArea;
Библиотека с формой готова. Кстати, на форму можно поместить любые компоненты. Для вызова формы из библиотеки применим статическое связывание. В проекте project1.dpr поместим на форму еще одну кнопку и в ее обработчике запишем:
procedure TForm1.Button2Click(Sender: TObject);
begin
ShowModalForm
end;
А после оператора IMPLEMENTATION запишем:
procedure ShowModalForm; FAR; EXTERNAL 'geta';
Готово! При нажатии на кнопку в программе Project1.exe на экране появится вторая форма, хранящаяся в библиотеке geta.dll.
Одним из преимуществ многозадачной операционной системы является возможность передачи разнообразной информации между одновременно выполняемыми приложениями. Мы давно привыкли, что можно скопировать текст, набранный в Word, и вставить его в Excel, или создать картинку в Adobe Photoshop и поместить ее в CorelDRAW. Рассмотрим, каким образом приложения могут обмениваться информацией.
Наиболее простой и примитивный способ передачи данных – использование буфера обмена(clipboard). Буфер обмена – это выделенная в операционной системе область памяти, которой могут пользоваться все приложения (Рис. 20.1).
Рис. 24.1 Буфер обмена.
В буфер можно помещать данные разного типа: текст, графику, звук и т.д. Для вставки информации из буфера в ту или иную программу необходимо, чтобы эта программа умела обрабатывать данный вид информации. Скажем, не удастся через буфер обмена вставить 3D модель из Компаса в Word.
Для работы с буфером из ваших приложений в проект необходимо подключить модуль Clipbrd:
uses …Clipbrd;
После этого в программе появляется глобальная переменная Clipboard. Это функция, возвращающая ссылку на объект типа TClipboardсо своими свойствами и методами.
Простейшая операция с буфером – помещение в него текста. Делается это так:
Clipboard.SetTextBuf(PCHAR('текст'));
Обратите внимание на команду приведения типа PCHAR. Она преобразует "паскалевскую" текстовую строку в строку, оканчивающуюся нулем (по стандарту языка С). Это связано с тем, что в Windows используется именно стандарт С и для взаимодействия с системным буфером обмена необходимо использовать соглашения Windows.
Для получения значения из буфера обмена в виде текстовой строки применяется метод GetTextBuf:
procedure TForm1.Button1Click(Sender: TObject);
var MyBuffer: PChar;
MyBufferSize: Byte;
MyString: String;
begin
// Копировать содержимое буфера обмена в строку
MyString := Clipboard.AsText;
// Установить длину буфера в длину строки
MyBufferSize := Length(MyString);
// Динамически создать буфер
GetMem(MyBuffer, MyBufferSize);
// Копировать в буфер содержимое буфера обмена Clipboard.GetTextBuf(MyBuffer, MyBufferSize);
// Копировать содержимое буфера в окно Edit, // чтобы убедиться, что все работает корректно
Если в буфере содержится не текстовая информация (изображение), то копирование, естественно, не выполняется. Чтобы проверить, информация какого типа лежит в буфере, следует заглянуть в свойство HasFormat:
if clipboard.HasFormat(CF_TEXT) then
// вставляем текст из буфера
Основные возможные значения типов информации:
CF_TEXT – текст;
CF_BITMAP – растровое изображение в формате bmp;
CF_METAFILEPICT – векторное изображение в формате wmf;
CF_PICTURE – любое изображение;
CF_COMPONENT – объект Delphi.
Помимо перечисленных, существует огромное количество других форматов.
Ряд визуальных компонентов имеют встроенные методы для работы с буфером. Например, компонента Tedit есть методы CopyToClipboard (поместить введенный текст в буфер обмена) и PasteFromClipboard (скопировать текст из буфера в поле ввода). Увы, в Delphi нет простых способов для работы с изображениями через буфер обмена.
Для очистки буфера используется метод Clipboard.Clear. Наконец, для копирования всего экрана в буфер обмена (в виде растровой картинки) можно сымитировать нажатие клавиши PrintScreen командой