скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

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



Оформил: DeeCo

// 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;





Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook