Author: Tomas Rutkauskas
I have used the TRichEdit component to generate some rich text which I am now
holding in a byte array. How can I paste it to the clipboard so that it can be
copied into MS Word?
Answer:
You have to copy it to the clipboard with a specific format. The richedit unit
defines a string constant CF_RTF (very unfortunate name!). You feed that to
RegisterClipboardFormat to obtain a format identifier which you can then use with
Clipboard.SetAshandle.
If you write the data to a memorystream you can use the following procedure to copy
the streams content to the clipboard. Use the format identifier you obtained from
CF_RTF as first parameter.
1 2 procedure CopyStreamToClipboard(fmt: Cardinal; S: TStream);
3 var4 hMem: THandle;
5 pMem: Pointer;
6 begin7 {Rewind stream position to start}8 S.Position := 0;
9 {Allocate a global memory block the size of the stream data}10 hMem := GlobalAlloc(GHND or GMEM_DDESHARE, S.Size);
11 if hMem <> 0 then12 begin13 {Succeeded, lock the memory handle to get a pointer to the memory}14 pMem := GlobalLock(hMem);
15 if pMem <> nilthen16 begin17 {Succeeded, now read the stream contents into the memory the pointer points 18 at}19 try20 S.read(pMem^, S.Size);
21 {Rewind stream again, caller may be confused if the stream position is 22 left at the end}23 S.Position := 0;
24 finally25 {Unlock the memory block}26 GlobalUnlock(hMem);
27 end;
28 {Open clipboard and put the block into it. The way the Delphi clipboard 29 object is written this will clear the clipboard first. Make sure the 30 clipboard is closed even in case of an exception. If left open it would 31 become unusable for other apps.}32 Clipboard.Open;
33 try34 Clipboard.SetAsHandle(fmt, hMem);
35 finally36 Clipboard.Close;
37 end;
38 end39 else40 begin41 {Could not lock the memory block, so free it again and raise an out of 42 memory exception}43 GlobalFree(hMem);
44 OutOfMemoryError;
45 end;
46 end47 else48 {Failed to allocate the memory block, raise exception}49 OutOfMemoryError;
50 end;