Delphi World - Копирование и вставка данных своего формата из буфера обмена
Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Копирование и вставка данных своего формата из буфера обмена

Оформил: DeeCo
Автор: http://www.swissdelphicenter.ch

// 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;
Проект Delphi World © Выпуск 2002 - 2017
Автор проекта: Эксклюзивные курсы программирования