Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Копирование и вставка данных своего формата из буфера обмена

01.01.2007
// The TClipboard provides easy clipboard access. But what if you 
// want to add (several) custom defined items to the clipboard?
 
// For all actions is the unit Clipboard required.
uses
Clipboard;
 
 
// First you have to register your own ClipBoard format
// Zuerst registrieren wir unser eigenes ClipBoard Format
const
   
MyClipboardFormatStr = 'MyData';
 
 
var
   
MyClpFormat: integer;
 
   
MyClpFormat := RegisterClipboardFormat(MyClipboardFormatStr);
 
 
{ The variable SLMClpFormat will contain a unique format handle for
  your own clipboard format
.
 
 
Die Variable SLMClpFormat enthalt ein einzigartiges Format Handle
  fur unser
ClipBoard Format.
}
 
 procedure
IncPointer(var p: Pointer; increment: Integer);
 
begin
   p
:= PChar(p) + Increment;
 
end;
 
 
// Say you have a data record defined as:
// Definiere zuerst etwa einen solchen Daten Record:
type
   
PMyDataRec = ^TMyDataRec;
   
TMyDataRec = record
     
Name: string[50];
     
Value: Integer;
   
end;
 
 
{ Furthermore let's say the data records are stored in a Listbox
  and shall be copied to a list box.
 
  Angenommen, die Daten Records sind in einer ListBox gespeichert und
  sollen in eine ListBox kopiert werden.
}
 
   // Copy like this:
procedure TForm1.CopyItems;
 var
   i: integer;
   dh: THandle;
   ic: integer;
   p: Pointer;
   pi: pInteger;
 begin
   // get number of items to be copied
  // Die Anzahl zu kopierenden Items
  ic := List1.SelCount;
   dh := GlobalAlloc(GMEM_FIXED or GMEM_ZEROINIT,
     (SizeOf(TMyDataRec) * ic) + SizeOf(Integer));
   { allocate memory for all items plus for a integer variable giving you the number of
    copied items }
   p   := GlobalLock(dh);    { Lock the allocated memory }
   pi  := pInteger(p);
   pi^ := ic;              { write number of items to allocated memory }
   IncPointer(p, SizeOf(Integer)); { increment the pointer behind the written data }
   // You don'
t have to create an instance of clipboard, this is done automatically
 
 
for i := 1 to List1.Items.Count do { check all items if they are selected }
   
begin
     
if List1.Items[i - 1].Selected then
     
begin
       
{ This one is selected -> copy it o the clipboard }
       
PMyDataRec(p)^ := PMyDataRec(List1.Items[i - 1].Data)^;
       
{ of course data must point to a TMyDataRec }
       
IncPointer(p, SizeOf(TMyDataRec));
       
{ increment the pointer behind the written data }
     
end;
   
end;
 
   
// You have now filled the allocated memory with all items that shall be copied.
 
// Now you can put them to the clipboard
 
Clipboard.Open;  { Open the clipboard will prevent overwriting of so far copied items }
   
Clipboard.Clear; { Clear the clipboard first }
   
Clipboard.SetAsHandle(MyClpFormat, Dh);  { Copy to clipboard }
   
Clipboard.Close;  { finally close the clipboard }
   
GlobalUnlock(dh);
   
{ and unlock the allocate memory. But don't free it, it will be used by the clipboard }
 
   if ic = 0 then
     GlobalFree(dh);    { You can free it if you haven'
t copied anything }
 
end;
 
 
// Check first if your items are still available before pasting them from the clipbard
 
if Clipboard.HasFormat(MyClpFormat) then
 
begin
   Form1
.Paste1.Enabled := True;   { Yes, they are still available }
 
end;
 
 
// And this is, how you paste them after Paste1 is clicked
procedure
TMDIForm.Paste1Click(Sender: TObject);
 
var
   dh
: THandle;
   pdr
: PSLMDataRec;
   i
, ic: integer;
   p
: Pointer;
   pi
: pInteger;
   li
: TListItem;
 
begin
   
if Clipboard.HasFormat(MyClpFormat) then
   
// We have already checked, but maybe another application has overwritten the
 
// clipboard in between....
 
begin
     
ClipBoard.Open;       { First open the clipboard again }
     dh
:= Clipboard.GetAsHandle(MyClpFormat); { Catch the handle to the stored items }
     p  
:= GlobalLock(dh);  { and lock it }
     pi
:= pInteger(p);    { The first item is an integer giving the number of items }
     ic
:= pi^;            { so get the number of items }
     
IncPointer(p, SizeOf(Integer)); { increment the pointer behind the read data }
     
for i := 1 to ic do   { get all copied items one after another }
     
begin
       li  
:= List1.Items.Add;  { first create a new listbox item }
       pdr  
:= New(PMyDataRec); { Then create a new pointer to a TMyDataRec }
       pdr
^ := PMyDataRec(p)^; { and fill it with data from the clipboard }
       
IncPointer(p, SizeOf(TSLMDataRec));
       
{ increment the pointer behind the written data }
 
       li
.Data    := pdr;  { Set the data pointer of the list item to the new record }
       LI
.Caption := pdr^.Name;  { Let the item display the record field "Name" }
 
       
// You can of course add more record fields if the item has subitems:
      LI
.SubItems.Add(IntToStr(Value));
     
end;    { All data retrieved from clipboard }
     
Clipboard.Close;  { Close it }
     
GlobalUnlock(dh);
   
{ and unlock the pointer, but don't free it. This will be done by the clipboard itself,
     if necessary }
   end;
 end;

Взято с сайта: https://www.swissdelphicenter.ch


{
Copyright © 1999 by Delphi 5 Developer's Guide - Xavier Pacheco and Steve Teixeira
}
unit cbdata;
interface
uses
  SysUtils, Windows, clipbrd;
 
const
 
  DDGData = '
CF_DDG'; // constant for registering the clipboard format.
type
 
  // Record data to be stored to the clipboard
 
  TDataRec = packed record
    LName: string[10];
    FName: string[10];
    MI: string[2];
    Age: Integer;
    BirthDate: TDateTime;
  end;
 
  { Define an object around the TDataRec that contains the methods
    for copying and pasting the data to and from the clipboard }
  TData = class
  public
    Rec: TDataRec;
    procedure CopyToClipBoard;
    procedure GetFromClipBoard;
  end;
 
var
  CF_DDGDATA: word; // Receives the return value of RegisterClipboardFormat().
 
implementation
 
procedure TData.CopyToClipBoard;
{ This function copies the contents of the TDataRec field, Rec, to the
  clipboard as both binary data, as text. Both formats will be
  available from the clipboard }
const
  CRLF = #13#10;
var
Data: THandle;
  DataPtr: Pointer;
  TempStr: string[50];
begin
  // Allocate SizeOf(TDataRec) bytes from the heap
  Data := GlobalAlloc(GMEM_MOVEABLE, SizeOf(TDataRec));
  try
    // Obtain a pointer to the first byte of the allocated memory
    DataPtr := GlobalLock(Data);
    try
      // Move the data in Rec to the memory block
      Move(Rec, DataPtr^, SizeOf(TDataRec));
      { Clipboard.Open must be called if multiple clipboard formats are
        being copied to the clipboard at once. Otherwise, if only one
        format is being copied the call isn'
t necessary }
     
ClipBoard.Open;
     
try
       
// First copy the data as its custom format
       
ClipBoard.SetAsHandle(CF_DDGDATA, Data);
       
// Now copy the data as text format
       
with Rec do
         
TempStr := FName + CRLF + LName + CRLF + MI + CRLF + IntToStr(Age) +
            CRLF
+
           
DateTimeToStr(BirthDate);
       
ClipBoard.AsText := TempStr;
       
{ If a call to Clipboard.Open is made you must match it
         
with a call to Clipboard.Close }
     
finally
       
Clipboard.Close
     
end;
   
finally
     
// Unlock the globally allocated memory
     
GlobalUnlock(Data);
   
end;
 
except
   
{ A call to GlobalFree is required only if an exception occurs.
     
Otherwise, the clipboard takes over managing any allocated
      memory to it
.}
   
GlobalFree(Data);
   
raise;
 
end;
end;
 
procedure
TData.GetFromClipBoard;
{ This method pastes memory saved in the clipboard if it is of the
  format CF_DDGDATA
. This data is stored in the TDataRec field of
 
this object. }
var
 
Data: THandle;
 
DataPtr: Pointer;
 
Size: Integer;
begin
 
// Obtain a handle to the clipboard
 
Data := ClipBoard.GetAsHandle(CF_DDGDATA);
 
if Data = 0 then
   
Exit;
 
// Obtain a pointer to the memory block referred to by Data
 
DataPtr := GlobalLock(Data);
 
try
   
// Obtain the size of the data to retrieve
   
if SizeOf(TDataRec) > GlobalSize(Data) then
     
Size := GlobalSize(Data)
   
else
     
Size := SizeOf(TDataRec);
   
// Copy the data to the TDataRec field
   
Move(DataPtr^, Rec, Size)
 
finally
   
// Free the pointer to the memory block.
   
GlobalUnlock(Data);
 
end;
end;
 
initialization
 
// Register the custom clipboard format
  CF_DDGDATA
:= RegisterClipBoardFormat(DDGData);
end.
{
Copyright © 1999 by Delphi 5 Developer's Guide - Xavier Pacheco and Steve Teixeira
}
 
unit MainFrm;
 
interface
 
uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls, clipbrd, Mask, ComCtrls;
type
 
  TMainForm = class(TForm)
    edtFirstName: TEdit;
    edtLastName: TEdit;
    edtMI: TEdit;
    btnCopy: TButton;
    btnPaste: TButton;
    meAge: TMaskEdit;
    btnClear: TButton;
    lblFirstName: TLabel;
    lblLastName: TLabel;
    lblMI: TLabel;
    lblAge: TLabel;
    lblBirthDate: TLabel;
    memAsText: TMemo;
    lblCustom: TLabel;
    lblText: TLabel;
    dtpBirthDate: TDateTimePicker;
    procedure btnCopyClick(Sender: TObject);
    procedure btnPasteClick(Sender: TObject);
    procedure btnClearClick(Sender: TObject);
  end;
 
var
  MainForm: TMainForm;
 
implementation
uses cbdata;
 
{$R *.DFM}
 
procedure TMainForm.btnCopyClick(Sender: TObject);
// This method copies the data in the form'
s controls onto the clipboard
var
 
DataObj: TData;
begin
 
DataObj := TData.Create;
 
try
   
with DataObj.Rec do
   
begin
     
FName := edtFirstName.Text;
     
LName := edtLastName.Text;
      MI
:= edtMI.Text;
     
Age := StrToInt(meAge.Text);
     
BirthDate := dtpBirthDate.Date;
     
DataObj.CopyToClipBoard;
   
end;
 
finally
   
DataObj.Free;
 
end;
end;
 
procedure
TMainForm.btnPasteClick(Sender: TObject);
{ This method pastes CF_DDGDATA formatted data from the clipboard to
  the form
's controls. The text version of this data is copied to the
  form'
s TMemo component. }
var
 
DataObj: TData;
begin
  btnClearClick
(nil);
 
DataObj := TData.Create;
 
try
   
// Check if the CF_DDGDATA format is available
   
if ClipBoard.HasFormat(CF_DDGDATA) then
     
// Copy the CF_DDGDATA formatted data to the form's controls
     
with DataObj.Rec do
     
begin
       
DataObj.GetFromClipBoard;
        edtFirstName
.Text := FName;
        edtLastName
.Text := LName;
        edtMI
.Text := MI;
        meAge
.Text := IntToStr(Age);
        dtpBirthDate
.Date := BirthDate;
     
end;
 
finally
   
DataObj.Free;
 
end;
 
// Now copy the text version of the data to form's TMemo component.
 
if ClipBoard.HasFormat(CF_TEXT) then
    memAsText
.PasteFromClipBoard;
end;
 
procedure
TMainForm.btnClearClick(Sender: TObject);
var
  i
: integer;
begin
 
// Clear the contents of all controls on the form
 
for i := 0 to ComponentCount - 1 do
   
if Components[i] is TCustomEdit then
     
TCustomEdit(Components[i]).Text := '';
end;
 
end.