Обмен данными с помощью буфера обмена данными Clipboard

Этот способ обмена является наиболее простым, и позволяет выполнить как статический обмен информацией, так и динамический обмен (в ходе выполнения процессов). Буфер обмена – это средство обмена, представляющее собой совокупность разделяемой области динамической памяти и набор системных функций, предназначенных для работы с этой памятью.

Традиционным способом использования буфера обмена является обмен данными при непосредственном участии пользователя. При этом, обычно, выполняются две основных операции:

1. Запись данных в буфер обмена в различных форматах;

2. Чтение из буфера обмена.

Рисунок!!

Запись осуществляется сервером, а чтение – клиентом.

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

Преобразование выполняется средствами ОС на основе ряда стандартных форматов. При этом, стандартизация форматов не ограничивает возможностей их расширения. В приложении можно создать новый формат, отличный от стандартного, и зарегистрировать его в системе с помощью системной функции RegisterClipboardFormat (). Параметром этой функции является строка с именем нового формата. Данная функция возвращает уникальный идентификатор формата. Если другие приложения вызовут эту функцию, указав в ней то же самое имя формата, то функция возвратит уже созданный идентификатор формата. В результате, все приложения будут пользоваться для обмена данными, представленными в этом формате, одним и тем же идентификатором.

Для работы с буфером обмена разработано порядка 25 стандартных форматов. Все они обозначаются константами, имеющими принятые в системе символические имена:

1. cf_Text – строковый формат (ASCII-z строка);

2. cf_BitMap – один из графических форматов;

3. …

Порядок обмена данными через буфер обмена на программном уровне, а не на уровне пользователя, включает выполнение двух основных операций:

1. Передача данных в буфер обмена;

2. Прием данных из буфера обмена.

Передача в буфер осуществляется из процесса-сервера, а прием данных из буфера осуществляется в процессе-клиенте.

Передача данных включает в себя следующие действия:

1. Подготовка данных для передачи в буфер обмена;

2. Открытие буфера обмена;

3. Очистка буфера обмена;

4. Посылка данных в БО;

5. Закрытие буфера обмена.

Подготовка данных для передачи в буфер обмена включает в себя следующие шаги:

1) выделение блока динамической памяти с помощью Ghandle GlobalAlloc (size_t). Возвращает дескриптор блока памяти;

2) фиксация блока от перемещений на время передачи в него данных и получение указателя на этот блок. GPtr GlobalLock( GHandle );

3) копирование передаваемой информации в выделенный блок памяти. Если передается строковая информация, то это действие можно выполнить с помощью StrCpy (GPtr, char*);

4) разрешение перемещения блока памяти. GlobalUnlock (GHandle).

Открытие буфера осуществляется с помощью функции OpenClipboard (GHandle). Данная функция возвращает истину, если буфер обмена не используется другим приложением, и следовательно, с ним возможны последовательные действия.

Очистка буфера обмена. EmptyClipboard(GHandle).

Посылка данных в буфер обмена. SetClipboardData(cf_Text, GHandle).

Закрытие буфера обмена. CloseClipboard (GHandle). После этой функции буфер становится доступным для других приложений.

Чтение из буфера обмена включает в себя выполнение следующих действий:

1. Открытие буфера обмена;

OpenClipboard()

2. Проверка наличия требуемого формата в буфере обмена;

IsClibpoardFormatAvailable()

Параметром является тип формата. (Например, cf_Text)

Возвращает true, если данные запрашиваемого формата присутствуют.

3. Передача данных из буфера обмена;

В случае успешного выполнения двух предыдущих операций.

Действия:

a) получение дескриптора блока памяти, содержащего данные требуемого формата.
GetClipboardData();

Возвращает GHandle.

b) получение адреса данного блока памяти и фиксирование его от возможных перемещений на время считывания данных;

GPtr GlobalLock (GHandle);

c) выделение локальной памяти в области памяти процесса для записи в неё требуемых данных;

GetMem (void *P, …);

d) копирование данных из глобальной памяти в локальную память;
В том случае, если передаются данные текстового типа, для этой операции может использоваться StrCpy (p, GPtr);

e) разрешение перемещения глобального блока памяти в локальную память.

GlobalUnlock (GHandle);

4. Закрытие буфера обмена.

CloseCliboard ();

Как следует из данного примера, программная реализация обмена данными через буфер обмена требует выполнения достаточно большого количества действий. При этом, реализация обмена для других, более сложных, чем текстовый, форматов, становится еще более сложной. Поэтому в современных системах программирования существуют встроенные средства, позволяющие упростить разработку процедур обмена через буфер обмена.

Например, в Delphi существует модуль Clipbrd, включение которого в проект позволяет использовать возможности класса TClipboard. При этом, компоненты TEdit, TMemo, TImage получают возможность использования своих методов работы с буфером обмена.