Private Data Formats

So far we've dealt with only the standard clipboard formats defined by Windows. However, you may want to use the clipboard to store a ”private data format.“ The Windows WRITE program uses this technique to store text that contains font and formatting information.

At first, this concept may seem nonsensical. If the purpose of the clipboard is to transfer data between applications, why should the clipboard contain data that only one application understands? The answer is simple: The clipboard also exists to allow the transfer of data between different instances of the same program, and these instances obviously understand the same private formats.

There are several ways to use private data formats. The easiest involves data that is ostensibly in one of the standard clipboard formats (text, bitmap, or metafile) but that has meaning only to your program. In this case, you use one of the following wFormat values in your SetClipboardData and GetClipboardData calls: CF_DSPTEXT, CF_DSPBITMAP, or CF_DSPMETAFILEPICT. DSP stands for ”display“—these formats allow CLIPBOARD to display the data as text, a bitmap, or a metafile. However, another program that calls GetClipboardData using the normal CF_TEXT, CF_BITMAP, or CF_METAFILEPICT format won't obtain this data.

If you use one of these formats to put data in the clipboard, you must also use the same format to get the data out. But how do you know if the data is from another instance of your program or from another program using one of these formats? Here's one way: You can first obtain the clipboard owner by calling:

hwndClipOwner = GetClipboardOwner () ;

You can then get the name of the window class of this window handle:

char szClassName [16] ;

[other program lines]

GetClassName (hwndClipOwner, &szClassName, 16) ;

If the class name is the same as your program's, then the data was put into the clipboard by another instance of your program.

The second way to use private formats involves the CF_OWNERDISPLAY flag. The global memory handle to SetClipboardData is NULL:

SetClipboardData (CF_OWNERDISPLAY, NULL) ;

This is the method that WRITE uses to show formatted text in the client area of the CLIPBOARD clipboard viewer. Obviously, CLIPBRD.EXE doesn't know how to display this formatted text. When WRITE specifies the CF_OWNERDISPLAY format, WRITE is taking responsibility for painting CLIPBOARD's client area.

Because the global memory handle is NULL, a program that calls SetClipboardData with the CF_OWNERDISPLAY format (the clipboard owner) must process the delayed rendering messages sent to the clipboard owner by Windows as well as five additional messages. These five messages are sent by the clipboard viewer to the clipboard owner:

WM_ASKCBFORMATNAME—The clipboard viewer sends this message to the clipboard owner to get a name for the format of the data. The lParam parameter is a pointer to a buffer, and wParam is the maximum number of characters for this buffer. The clipboard owner must copy the name of the clipboard format into this buffer.

WM_SIZECLIPBOARD—This message tells the clipboard owner that the size of the clipboard viewer's client area has changed. The wParam parameter is a handle to the clipboard viewer, and lParam is a pointer to a RECT structure containing the new size. If the RECT structure contains all zeros, the clipboard viewer is being destroyed or made an icon. Although CLIPBRD.EXE allows only one instance of itself to be running, other clipboard viewers can also send this message to the clipboard owner. Handling these multiple clipboard viewers isn't impossible for the clipboard owner (given that wParam identifies the particular viewer), but it isn't easy, either.

WM_PAINTCLIPBOARD—This message tells the clipboard owner to update the clipboard viewer's client area. Again, wParam is a handle to the clipboard viewer's window. The lParam parameter is a pointer to a PAINTSTRUCT structure. The clipboard owner can obtain a handle to the clipboard viewer's device context from the hdc field of this structure.

WM_HSCROLLCLIPBOARD and WM_VSCROLLCLIPBOARD—These messages inform the clipboard owner that a user has scrolled the clipboard viewer's scroll bars. The wParam parameter is a handle to the clipboard viewer's window, the low word of lParam is the scrolling request (the same as wParam in normal scroll bar messages), and the high word of lParam is the thumb position if the low word is SB_THUMBPOSITION. (This value is the same as the low word of lParam in a normal scroll bar message.)

Handling these messages may look like more trouble than it's worth. However, the process does provide a benefit to the user: When copying text from WRITE to the clipboard, the user will find it comforting to see the text still formatted in CLIPBOARD's client area.

The third way to use private clipboard data formats is to register your own clipboard format name. You supply a name for this format to Windows, and Windows gives your program a number to use as the format parameter in SetClipboardData and GetClipboardData. Programs that use this method generally also copy data to the clipboard in one of the standard formats. This approach allows CLIPBRD.EXE to display data in its client area (without the hassles involved with CF_OWNERDISPLAY) and permits other programs to copy data from the clipboard.

As an example, let's assume we've written a vector drawing program that copies data to the clipboard in a bitmap format, a metafile format, and its own registered clipboard format. CLIPBRD.EXE will display the metafile. Other programs that can read bitmaps or metafiles from the clipboard will obtain those formats. However, when the vector drawing program itself needs to read data from the clipboard, it will copy the data in its own registered format, because that format probably contains more information than the bitmap or metafile.

A program registers a new clipboard format by calling:

wFormat = RegisterClipboardFormat (lpszFormatName) ;

The wFormat value is between 0xC000 and 0xFFFF. A clipboard viewer (or a program that obtains all the current clipboard formats by calling EnumClipboardFormats) can obtain the ASCII name of this format by calling:

GetClipboardFormatName (wFormat, lpsBuffer, nMaxCount) ;

Windows copies up to nMaxCount characters into lpsBuffer.

Programmers who use this method for copying data to the clipboard might want to publicize the format name and the actual format of the data. If the program becomes popular, other programs can then copy data in this format from the clipboard.