Буфер обмена Windows - это специальный контейнер для текста
или графики, которые вырезаются, копируются и вставляются из одних приложений в
другие. В данной статье рассказывается, как использовать объект TClipboard для
выполнения операций вырезки/копирования/вставки в Вашем Delphi-приложении.
Буфер обмена в общих чертах
Вероятно, Вы знаете, что буфер обмена (далее - БО) может
содержать только один фрагмент данных в конкретный момент времени. Именно с
этими данными выполняются все основные операции обмена между приложениями.
Вполне логично, что формат данных, хранимых в БО в конкретный момент, также
чётко опеределён. Если в БО записывается новая "порция" данных, то информация,
которая содержалась в нём ранее, уничтожается. Содержимое БО не удаляется после
вставки в данных в конкретное приложение, т.е. информация будет храниться там до
тех пор, пока не будет записана какая-либо другая, либо пока БО не будет
принудительно очищен.
Объект TClipboard
Для того, чтобы работать с БО в своём приложении, мы должны
подключить модуль ClipBrd в uses нашего проекта, за
исключением тех случаев, когда мы используем готовые методы некоторых компонент
для работы с БО.
Примерами таких компонентов могут быть TEdit, TMemo, TOLEContainer,
TDDEServerItem, TDBEdit, TDBImage и TDBMemo. В модуль ClipBrd включен объект
TClipboard, обращаться к которому можно просто Clipboard. Мы будем использовать
методы CutToClipboard, CopyToClipboard, PasteFromClipboard,
Clear и HasFormat при работе с БО и манипуляциями с текстом и
графикой.
Отправка и получение текста
Для того, чтобы отправить в БО некоторый текстовый фрагмент,
нужно использовать свойство AsText объекта Clipboard. Если мы хотим, к примеру,
отправить текст, хранящийся в переменной SomeStringData в БО, то следует
использовать такой код (всё, что было в БО до этого, будет уничтожено):
uses ClipBrd;
...
Clipboard.AsText := SomeStringData_Variable;
Чтобы получить текст из БО, следует делать так:
uses ClipBrd;
...
SomeStringData_Variable := Clipboard.AsText;
Примечание: если требуется просто скопировать текст в буфер
обмена, например из TEdit, то не обязательно подключать модуль ClipBrd. У TEdit
есть метод CopyToClipboard, который автоматически копирует выделенный текст из
этого компонента в БО (данные переводятся в формат CF_TEXT).
procedure TForm1.Button2Click(Sender: TObject) ;
begin
//Следующий код выделяет весь текст в TEdit
{Edit1.SelectAll;}
Edit1.CopyToClipboard;
end;
Чтобы извлекать изображения из БО, программа должна знать, в
каком формате там храниться изображение. Аналогично, чтобы записывать в БО
графику, приложение должно "сообщить" буферу обмена тип отправляемого
изображения. Некоторые возможные значения параметра Format приведены ниже;
однако в Windows определено гораздо больше форматов.
CF_TEXT - Текст, где каждая строка заканчивается CR-LF
комбинацией символов.
CF_BITMAP - Изображение в формате Windows bitmap.
CF_METAFILEPICT - Изображение Windows metafile.
CF_PICTURE - Объект типа TPicture.
CF_OBJECT - Любой значимый объект.
Метод HasFormat возвращает True, если данные в буфере
обмена хранятся в указанном формате и могут быть прочитаны:
if Clipboard.HasFormat(CF_METAFILEPICT) then
ShowMessage('Clipboard has metafile');
Чтобы отправить изображение в БО, следует использовать метод
Assign. Например, следующий код скопирует bitmap из объекта,
содержащего графические данные, названного MyBitmap, в буфер обмена:
Clipboard.Assign(MyBitmap);
В общем случае, MyBitmap - это объект одного из типов:
TGraphics, TBitmap, TMetafile или TPicture.
Чтобы получить графические данные из БО, нужно: проверить
текущий формат содержимого БО и использовать метод Assign, указав конечный
объект для импорта данных:
{Поместите на форму кнопку (TButton) и изображение (TImage)}
{До выполнения этого кода нажмите комбинацию клавиш [Alt]+[PrintScreen]}
uses clipbrd;
...
procedure TForm1.Button1Click(Sender: TObject) ;
begin
if Clipboard.HasFormat(CF_BITMAP) then Image1.Picture.Bitmap.Assign(Clipboard) ;
end;
Немного о расширенной работе с буфером обмена
Буфер обмена хранит информацию, которую мы можем перемещать
между разными приложениями, в самых различных форматах; к тому же, сами
приложения могут работать с разными форматами. Однако при чтении данных из БО в
Delphi-приложении через объект TClipboard, мы можем использовать только
стандартные форматы: текст, графика и мета-файлы.
Допустим, у нас есть 2 запущенных Delphi-приложения... Что Вы
скажете насчёт того, чтобы определить собственный формат БО для пересылки данных
между этими двумя приложениями? Допустим, мы создали в меню команду "Вставить" и
хотим, чтобы этот пункт был недоступен, когда, к примеру, в буфере обмена нет
текстовых данных... С тех пор, как с БО начала работать какая-либо другая
программа, мы не можем отследить момента, когда в буфере произойдёт какое-либо
изменение... У класса TClipboard не предусмотрено таких событий, которые
оповещали бы нас об этом... Всё, что нам нужно сделать - это поставить "хуки" в
систему событий буфера обмена и тогда наше приложение будет автоматически
узнавать обо всех изменениях его содержимого.
Если нам нужна более гибкая система работы с буфером обмена,
уведомления об изменениях в содержимом буфера и специальные форматы данных, мы
можем всё это реализовать. Но об этом в следующей статье...
|