Title: Copying large amounts of Text to the Clipboard.
Question: Normally copying text to the clipboard in Delphi is a simple process. The data being copied is usually contained in a standard control such as a 'TMemo' so the contents may be copied using the 'CopyToClipboard' method.
Answer:
Normally copying text to the clipboard in Delphi is a simple process. The data being copied is usually contained in a standard control such as a 'TMemo' so the contents may be copied using the 'CopyToClipboard' method. Alternatively text that is 255 characters or less may be copied by assigning it to the 'ClipBoard.AsText' property. An alternative technique is required when the size of the text exceeds 255 characters and the data is coming from a source that does not have implicit clipboard support.
The following example demonstrates how I performed such an operation using data from a stream. When entering the following code it is assumed that 'CurStream' is a previously opened stream. If you haven't had any experience using streams they are worth looking at because they provide an application with the flexibility to treat in memory data the same as file data.
As text data on the clipboard must be null terminated the code appends a null in case there is not one present in the stream. Obviously the example may be used as the basis for clipboard operations on types other than text.
Note below that the memory that is allocated is not released unless an error occurs. This is because the data passed to the clipboard must stay valid even if our application terminates. It is the responsibility of the clipboard to free the memory area when no longer required.
procedure TMainForm.Copy1Click(Sender: TObject);
var
Buffer: THandle;
BufferPtr: Pointer;
StartPos, EndPos, BytesToCopy: Integer;
P: PChar;
begin
{Setup StartPos and EndPos here }
BytesToCopy := EndPos - StartPos + 1;
try
ClipBoard.Open;
Buffer := GlobalAlloc(GMEM_MOVEABLE, BytesToCopy + 1);
try
BufferPtr := GlobalLock(Buffer);
try
CurStream.Seek(StartPos, soFromBeginning);
CurStream.Read(BufferPtr^, BytesToCopy);
P := BufferPtr;
P[BytesToCopy] := #0;
Clipboard.SetAsHandle(CF_TEXT, Buffer);
finally
GlobalUnlock(Buffer);
end;
except
GlobalFree(Buffer);
raise;
end;
finally
Clipboard.Close;
end;
end;