Controlling Data Display in the Clipboard

There are two reasons why an application might wish to control the display of information in the Clipboard application:

The application may have a private data type that is difficult or impossible to display in a meaningful way.

The application may have a private data type that requires special knowledge to display.

Using a Display Format for Private Data

You can use a display format to represent a private data format that would otherwise be difficult or impossible to display. The data associated with display formats are text, bitmaps, or metafile pictures that the clipboard viewer can display as substitutes for the corresponding private data. To use a display format, you copy both the private data and the display data to the clipboard. When the clipboard viewer chooses a format to display, it chooses the display format instead of the private data.

There are three display formats: CF_DSPTEXT, CF_DSPBITMAP, and CF_DSPMETAFILEPICT. The data associated with these formats are identical to the text, bitmap, and metafile-picture formats, respectively. Since text, bitmaps, and metafile pictures are also standard formats, the clipboard viewer can display them without help from the application.

The following description assumes that the application has already taken ownership of the clipboard and set data handles. For a description of the steps, see “Copying Text to the Clipboard”.

To force the display of a private data type in a standard data format, the application must take the following steps:

1.Open the clipboard for alteration by calling the OpenClipboard function.

2.Create a global handle that contains text, a bitmap, or a metafile picture, specifying the information that should be displayed in the clipboard viewer.

3.Set the handle to the clipboard by calling the SetClipboardData function. The format code passed should be CF_DSPTEXT if the handle is to text, CF_DSPBITMAP if the handle is for a bitmap, and CF_DSPMETAFILEPICT if it is for a metafile picture.

4.Signal that the application has finished altering the clipboard by calling the CloseClipboard function.

Taking Full Control of the Clipboard-Viewer Display

An application can take complete control of the display and scrolling of information in the clipboard viewer. This control is useful when the application has a sophisticated private data type that only it knows how to display. Microsoft Write uses this facility for displaying formatted text.

The following description assumes that the application has already taken ownership of the clipboard and set data handles. For a description of the steps, see “Copying Text to the Clipboard”.

To take control of the display of information in the clipboard viewer:

1.Open the clipboard for alteration by calling the OpenClipboard function.

2.Call the SetClipboardData function, using CF_OWNERDISPLAY as the data format, with a NULL handle.

3.Signal that the application has finished altering the clipboard by calling the CloseClipboard function.

The clipboard owner will then receive special messages associated with the
display of information in the clipboard viewer:

Message Action

WM_PAINTCLIPBOARD Paint the specified portion of the window
WM_SIZECLIPBOARD Take note of the window size change
WM_VSCROLLCLIPBOARD Scroll the window vertically
WM_HSCROLLCLIPBOARD Scroll the window horizontally
WM_ASKCBFORMATNAME Supply the name of the displayed format

Using the Clipboard-Viewer Chain

Chaining together clipboard-viewer windows provides a way for applications to be notified whenever a change is made to the clipboard. The notification, in the form of a WM_DRAWCLIPBOARD message, is passed down the viewer chain whenever the CloseClipboard function is called. The recipient of the WM_DRAWCLIPBOARD message must determine the nature of the change (Empty, Set, etc.) by calling the EnumClipboardFormats function, the GetClipboardData function, and other functions, as desired.

Any window that has made itself a link in the viewer chain must be prepared to do the following:

1.Remove itself from the chain before it is destroyed.

2.Pass along WM_DRAWCLIPBOARD messages to the next link in the chain.

The code for this action looks like this:

case WM_DESTROY:

ChangeClipboardChain(hwnd, my_save_next);

/* rest of processing for WM_DESTROY */

break;

case WM_DRAWCLIPBOARD:

if (my_save_next != NULL)

SendMessage(my_save_next, WM_DRAWCLIPBOARD, wParam, lParam);

/* rest of processing for WM_DRAWCLIPBOARD */

break;

The my_save_next string is the value returned from the SetClipboardViewer function. These clipboard-viewer chain actions should be the first steps taken by the switch-statement branches that process the WM_DESTROY and WM_DRAWCLIPBOARD messages.