Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Unit ClipboardFormatUnit; interface implementation end



После ключевого слова interface добавляем раздел type и объявление структуры TLineData и нового объекта TLineClipboard.

type TLineData=record Name:String[100]; LastName:String[100]; Bothday:String[10]; Age:Integer; Telephone:String[15]; end;

TLineClipboard=class

public LineData:TLineData; procedure CopyToClipboard; procedure PasteFromClipboard;

end;

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

После структуры идёт объявление нового объекта. Здесь мы объявляем новый объект вручную описывая все его метода и свойства. Чаще всего за нас это делал Delphi. Обрати внимание на то, что он объявлен, как простой объект без каких либо родителей (TLineClipboard=class). Несмотря на это, он будет иметь родителя – TObject, потому что все объекты должны иметь родителя и если ничего не указано, то будет использоваться базовый объект TObject. У нового объекта будет только одно свойство типа структуры TLineData и два метода для копирования и вставки данных в буфер обмена.

Теперь, после раздела type напишем var и опишем одну переменную:

var CF_PERSONDATA:word;

В этой переменной будет храниться указатель на зарегистрированный формат для буфера обмена. Давай не будем откладывать это дело на потом, а сразу же реализуем регистрацию в системе этого нового формата. Для этого в конце модуля, перед последним «end.» пишем:

initialization CF_PERSONDATA:=RegisterClipboardFormat('CF_PDATA');

End.

Здесь мы объявили блок initialization, который всегда выполняется автоматически при обращении к модулю или любому его содержимому. В этом блоке я присваиваю переменной CF_PERSONDATA результат выполнения функции RegisterClipboardFormat. Эта функция регистрирует новый формат для буфера обмена с именем указанным в качестве единственного параметра. Результат выполнения функции – число, идентифицирующее зарегистрированный формат данных. После этого, этот формат можно увидеть в свойстве Formats объекта Clipboard.

Вот теперь перейдём к реализации функций записи и чтения данных из буфера.

procedure TLineClipboard.CopyToClipboard;

var Data:THandle; DataPtr:Pointer;

begin // Выделяем память под данные Data:=GlobalAlloc(GMEM_MOVEABLE, SizeOf(LineData));

try
DataPtr:=GlobalLock(Data);
Move(LineData, DataPtr^, SizeOf(TLineData));

// Заполняем буфер обмена
Clipboard.Open;
Clipboard.SetAsHandle(CF_PERSONDATA, Data);
Clipboard.AsText:=LineData.Name+#13#10+LineData.LastName+#13#10+

LineData.Bothday+#13#10+IntToStr(LineData.Age)+#13#10+

LineData.Telephone;
Clipboard.Close;
GlobalUnlock(Data);

except GlobalFree(Data); end; end;

В процедуре объявлено две переменные:

Data – в эту переменную мы будем выделять память для хранения структуры, которую надо будет поместить в буфер обмена.

DataPtr – указатель на выделенную для переменной Data память.

В самом начале процедуры я присваиваю переменной Data результат вызова функции GlobalAlloc. Эта функция выделяет нужный кусок памяти в глобальной памяти. У неё два параметра:

1. 1. Параметры (флаги) выделяемой памяти. Здесь я указал флаг GMEM_MOVEABLE, который указывает на то, что память может быть перемещаемой. Например, когда ОС не хватает оперативной памяти, то она может выгрузить некоторую часть памяти на диск и по мере надобности вернуть эту память обратно. Такой флаг позволяет ОС производить такие манипуляции.

2. 2. Размер выделяемой памяти. Здесь я указываю размер SizeOf структуры LineData.

Следующим этапом я блокирую выделенную память с помощью функции GlobalAlloc и получаю указатель на выделенную память, который сохраняется в переменной DataPtr.

У нас есть выделенная память, и мы её временно заблокировали для работы с ней. Теперь мы должны скопировать в эту память структуру, которая должна быть помещена в буфер обмена. Для этого я пользуюсь процедурой Move, которая копирует данные из одного участка памяти (первый параметр – структура LineData) в другой участок (второй параметр – выделенная память DataPtr). Третий параметр – это размер копируемых данных. Я указываю тут размер нашей структуры.

Память подготовлена и в неё занесены данные для буфера обмена. Теперь можно приступать к установке этих данных в буфер. Для начала буфер надо открыть – Open для записи. Следующим этапом я заношу в буфер данные в виде структуры (зарегистрированного нами формата CF_PERSONDATA). Для этого я использую метод SetAsHandle. У этого метода два параметра:

1. 1. Тип заносимых данных.

2. 2. Данные.

Дальше, я заношу данные в виде текста, чтобы программы, которые не знают о существовании моего собственного формата, могли прочитать данные в виде текста. Для этого текст надо занести в свойство AsText объекта Clipboard. В это свойство я заношу все поля структуры, разделённые символами #13#10, Символ #13 означает конец строки, а #10 означает перевод каретки на новую строку. Получается, что каждый параметр будет занесён в виде отдельной строки. Чуть позже ты увидишь, как это выглядит на практике.

Данные занесены, можно уничтожать всё, что мы натворили. Для начала закрываю буфер обмена с помощью вызова метода Close объекта Clipboard. Потом вызываю метод GlobalUnlock, который разблокирует память. Уничтожать выделенную память (вызов GlobalFree) нужно только если во время записи произошла какая-то ошибка, поэтому я поместил вызов этой процедуры в блоке except..end. Если ошибок не было, то память должна остаться целой и невредимой, потому что там храниться структура.

Вот теперь разберёмся с кодом, который получает данные из буфера обмена. Взгляни на процедуру PasteFromClipboard:

procedure TLineClipboard.PasteFromClipboard;

var Data:THandle; DataPtr:Pointer;

begin Data:=ClipBoard.GetAsHandle(CF_PERSONDATA); if Data=0 then exit;

DataPtr:=GlobalLock(Data);

Move(DataPtr^, LineData, SizeOf(TLineData));

GlobalUnlock(Data); end;

В первой строке кода я пытаюсь получить данные из буфера обмена с помощью функции GetAsHandle. Этой функции нужно передать формат, в котором мы хотим получить данные. Если значение, которое нам вернула GetAsHandle равно нулю, то данных в буфере нет, или они имеют несовместимый формат. В этом случае процедура прерывает своё выполнение.

Если всё нормально, то в переменной Data будет указатель на блок памяти с данными буфера обмена. Для их получения я блокирую память и пользуюсь уже знакомой процедурой Move для копирования данных из памяти буфера обмена (первый параметр) в структуру LineData (второй параметр).

Данные получены, можно разблокировать память с помощью процедуры GlobalUnlock.

Всё, модуль готов. Теперь переходим к написанию основной программы, которая будет использовать созданный нами формат данных для копирования и вставки через буфер обмена. У нас уже создан новый проект, в котором мы написали модуль ClipboardFormatUnit. Перейди в основное окно, и помести на форму следующие компоненты:

1. 1. Две кнопки «Копировать» и «Вставить».

2. 2. Компонент StringGrid. В нём нужно изменить свойство goEditing в разделе Option на true, чтобы мы могли редактировать ячейки в сетке.

3. 3. Memo в котором мы будем отображать содержимое буфера в виде текста.

Мою форму ты можешь увидеть на рисунке 23.4.1. Для реализации кнопок я использовал компонент ToolBar, чтобы программа выглядела более эстетично и красиво, но ты можешь поступить и по-другому.

Сразу же добавь в раздел uses наш модуль ClipboardFormatUnit, чтобы ты мог использовать новый формат из главной формы.

Теперь создадим обработчик события OnClick для кнопки «Копировать» и напишем в нём следующее:





Дата публикования: 2014-11-29; Прочитано: 211 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.008 с)...