Articles - Copying large amounts of Text to the Clipboard

'

Introduction

This article was written by Peter Johnson. Peter has written a number of articles, components and applications, unfortunately the web address we have is no longer valid, if you know where it is now please let us know.

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;

Google
Web www.Delphi-Central.com
Delphi Central - Delphi Programming Tutorials, Hints and Tips