- Using the Clipboard
- Implementing the Cut, Copy, and Paste Commands
- Selecting Data
- Creating an Edit Menu
- Processing the WM_INITMENUPOPUP Message
- Processing the WM_COMMAND Message
- Copying Information to the Clipboard
- Pasting Information from the Clipboard
- Registering a Clipboard Format
- Processing the WM_RENDERFORMAT and WM_RENDERALLFORMATS Messages
- Processing the WM_DESTROYCLIPBOARD Message
- Using the Owner-Display Clipboard Format
- Monitoring Clipboard Contents
- Querying the Clipboard Sequence Number
- Creating a Clipboard Format Listener
- Creating a Clipboard Viewer Window
- Adding a Window to the Clipboard Viewer Chain
- Processing the WM_CHANGECBCHAIN Message
- Removing a Window from the Clipboard Viewer Chain
- Processing the WM_DRAWCLIPBOARD Message
- Example of a Clipboard Viewer
- About the Clipboard
- Clipboard Commands
- Clipboard Sequence Number
- Clipboard Viewers
- Clipboard Viewer Windows
- Display Formats
- Owner Display Format
Using the Clipboard
This section has code samples for the following tasks:
Implementing the Cut, Copy, and Paste Commands
This section describes how standard Cut, Copy, and Paste commands are implemented in an application. The example in this section uses these methods to place data on the clipboard using a registered clipboard format, the CF_OWNERDISPLAY format, and the CF_TEXT format. The registered format is used to represent rectangular or elliptical text windows, called labels.
Selecting Data
Before information can be copied to the clipboard, the user must select specific information to be copied or cut. An application should provide a means for the user to select information within a document and some kind of visual feedback to indicate selected data.
Creating an Edit Menu
An application should load an accelerator table containing the standard keyboard accelerators for the Edit menu commands. The TranslateAccelerator function must be added to the application’s message loop for the accelerators to take effect. For more information about keyboard accelerators, see Keyboard Accelerators.
Processing the WM_INITMENUPOPUP Message
Not all clipboard commands are available to the user at any given time. An application should process the WM_INITMENUPOPUP message to enable the menu items for available commands and disable unavailable commands.
Following is the WM_INITMENUPOPUP case for an application named Label.
The InitMenu function is defined as follows.
Processing the WM_COMMAND Message
To process menu commands, add the WM_COMMAND case to your application’s main window procedure. Following is the WM_COMMAND case for the Label application’s window procedure.
To carry out the Copy and Cut commands, the window procedure calls the application-defined EditCopy function. For more information, see Copying Information to the Clipboard. To carry out the Paste command, the window procedure calls the application-defined EditPaste function. For more information about the EditPaste function, see Pasting Information from the Clipboard.
Copying Information to the Clipboard
In the Label application, the application-defined EditCopy function copies the current selection to the clipboard. This function does the following:
- Opens the clipboard by calling the OpenClipboard function.
- Empties the clipboard by calling the EmptyClipboard function.
- Calls the SetClipboardData function once for each clipboard format the application provides.
- Closes the clipboard by calling the CloseClipboard function.
Depending on the current selection, the EditCopy function either copies a range of text or copies an application-defined structure representing an entire label. The structure, called LABELBOX, is defined as follows.
Following is the EditCopy function.
Pasting Information from the Clipboard
In the Label application, the application-defined EditPaste function pastes the content of the clipboard. This function does the following:
Opens the clipboard by calling the OpenClipboard function.
Determines which of the available clipboard formats to retrieve.
Retrieves the handle to the data in the selected format by calling the GetClipboardData function.
Inserts a copy of the data into the document.
The handle returned by GetClipboardData is still owned by the clipboard, so an application must not free it or leave it locked.
Closes the clipboard by calling the CloseClipboard function.
If a label is selected and contains an insertion point, the EditPaste function inserts the text from the clipboard at the insertion point. If there is no selection or if a label is selected, the function creates a new label, using the application-defined LABELBOX structure on the clipboard. The LABELBOX structure is placed on the clipboard by using a registered clipboard format.
The structure, called LABELBOX, is defined as follows.
Following is the EditPaste function.
Registering a Clipboard Format
To register a clipboard format, add a call to the RegisterClipboardFormat function to your application’s instance initialization function, as follows.
Processing the WM_RENDERFORMAT and WM_RENDERALLFORMATS Messages
If a window passes a NULL handle to the SetClipboardData function, it must process the WM_RENDERFORMAT and WM_RENDERALLFORMATS messages to render data upon request.
If a window delays rendering a specific format and then another application requests data in that format, then a WM_RENDERFORMAT message is sent to the window. In addition, if a window delays rendering one or more formats, and if some of those formats remain unrendered when the window is about to be destroyed, then a WM_RENDERALLFORMATS message is sent to the window before its destruction.
To render a clipboard format, the window procedure should place a non-NULL data handle on the clipboard using the SetClipboardData function. If the window procedure is rendering a format in response to the WM_RENDERFORMAT message, it must not open the clipboard before calling SetClipboardData. But if it is rendering one or more formats in response to the WM_RENDERALLFORMATS message, it must open the clipboard and check that the window still owns the clipboard before calling SetClipboardData, and it must close the clipboard before returning.
In both cases, the window procedure calls the application-defined RenderFormat function, defined as follows.
The structure, called LABELBOX, is defined as follows.
Processing the WM_DESTROYCLIPBOARD Message
A window can process the WM_DESTROYCLIPBOARD message in order to free any resources that it set aside to support delayed rendering. For example the Label application, when copying a label to the clipboard, allocates a local memory object. It then frees this object in response to the WM_DESTROYCLIPBOARD message, as follows.
Using the Owner-Display Clipboard Format
If a window places information on the clipboard by using the CF_OWNERDISPLAY clipboard format, it must do the following:
Process the WM_PAINTCLIPBOARD message. This message is sent to the clipboard owner when a portion of the clipboard viewer window must be repainted.
Process the WM_SIZECLIPBOARD message. This message is sent to the clipboard owner when the clipboard viewer window has been resized or its content has changed.
Typically, a window responds to this message by setting the scroll positions and ranges for the clipboard viewer window. In response to this message, the Label application also updates a SIZE structure for the clipboard viewer window.
Process the WM_HSCROLLCLIPBOARD and WM_VSCROLLCLIPBOARD messages. These messages are sent to the clipboard owner when a scroll bar event occurs in the clipboard viewer window.
Process the WM_ASKCBFORMATNAME message. The clipboard viewer window sends this message to an application to retrieve the name of the owner-display format.
The window procedure for the Label application processes these messages, as follows.
Monitoring Clipboard Contents
There are three ways of monitoring changes to the clipboard. The oldest method is to create a clipboard viewer window. WindowsВ 2000 added the ability to query the clipboard sequence number, and WindowsВ Vista added support for clipboard format listeners. Clipboard viewer windows are supported for backward compatibility with earlier versions of Windows. New programs should use clipboard format listeners or the clipboard sequence number.
Querying the Clipboard Sequence Number
Each time the contents of the clipboard change, a 32-bit value known as the clipboard sequence number is incremented. A program can retrieve the current clipboard sequence number by calling the GetClipboardSequenceNumber function. By comparing the value returned against a value returned by a previous call to GetClipboardSequenceNumber, a program can determine whether the clipboard contents have changed. This method is more suitable to programs which cache results based on the current clipboard contents and need to know whether the calculations are still valid before using the results from that cache. Note that this is a not a notification method and should not be used in a polling loop. To be notified when clipboard contents change, use a clipboard format listener or a clipboard viewer.
Creating a Clipboard Format Listener
A clipboard format listener is a window which has registered to be notified when the contents of the clipboard has changed. This method is recommended over creating a clipboard viewer window because it is simpler to implement and avoids problems if programs fail to maintain the clipboard viewer chain properly or if a window in the clipboard viewer chain stops responding to messages.
A window registers as a clipboard format listener by calling the AddClipboardFormatListener function. When the contents of the clipboard change, the window is posted a WM_CLIPBOARDUPDATE message. The registration remains valid until the window unregister itself by calling the RemoveClipboardFormatListener function.
Creating a Clipboard Viewer Window
A clipboard viewer window displays the current content of the clipboard, and receives messages when the clipboard content changes. To create a clipboard viewer window, your application must do the following:
- Add the window to the clipboard viewer chain.
- Process the WM_CHANGECBCHAIN message.
- Process the WM_DRAWCLIPBOARD message.
- Remove the window from the clipboard viewer chain before it is destroyed.
Adding a Window to the Clipboard Viewer Chain
A window adds itself to the clipboard viewer chain by calling the SetClipboardViewer function. The return value is the handle to the next window in the chain. A window must keep track of this value — for example, by saving it in a static variable named hwndNextViewer.
The following example adds a window to the clipboard viewer chain in response to the WM_CREATE message.
Code snippets are shown for the following tasks:
Processing the WM_CHANGECBCHAIN Message
A clipboard viewer window receives the WM_CHANGECBCHAIN message when another window is removing itself from the clipboard viewer chain. If the window being removed is the next window in the chain, the window receiving the message must unlink the next window from the chain. Otherwise, this message should be passed to the next window in the chain.
The following example shows the processing of the WM_CHANGECBCHAIN message.
Removing a Window from the Clipboard Viewer Chain
To remove itself from the clipboard viewer chain, a window calls the ChangeClipboardChain function. The following example removes a window from the clipboard viewer chain in response to the WM_DESTROY message.
Processing the WM_DRAWCLIPBOARD Message
The WM_DRAWCLIPBOARD message notifies a clipboard viewer window that the content of the clipboard has changed. A window should do the following when processing the WM_DRAWCLIPBOARD message:
- Determine which of the available clipboard formats to display.
- Retrieve the clipboard data and display it in the window. Or if the clipboard format is CF_OWNERDISPLAY, send a WM_PAINTCLIPBOARD message to the clipboard owner.
- Send the message to the next window in the clipboard viewer chain.
For an example of processing the WM_DRAWCLIPBOARD message, see the example listing in Example of a Clipboard Viewer.
Example of a Clipboard Viewer
The following example shows a simple clipboard viewer application.
About the Clipboard
The clipboard is a set of functions and messages that enable applications to transfer data. Because all applications have access to the clipboard, data can be easily transferred between applications or within an application.
The clipboard is user-driven. A window should transfer data to or from the clipboard only in response to a command from the user. A window must not use the clipboard to transfer data without the user’s knowledge.
A memory object on the clipboard can be in any data format, called a clipboard format. Each format is identified by an unsigned integer value. For standard (predefined) clipboard formats, this value is a constant defined in Winuser.h; for registered clipboard formats, it is the return value of the RegisterClipboardFormat function.
Except for registering clipboard formats, individual windows perform most clipboard operations. Typically, a window procedure transfers information to or from the clipboard in response to the WM_COMMAND message.
This section discusses the following:
Clipboard Commands
A user typically carries out clipboard operations by choosing commands from an application’s Edit menu. Following is a brief description of the standard clipboard commands.
Cut | Places a copy of the current selection on the clipboard and deletes the selection from the document. The previous content of the clipboard is destroyed. |
Copy | Places a copy of the current selection on the clipboard. The document remains unchanged. The previous content of the clipboard is destroyed. |
Paste | Replaces the current selection with the content of the clipboard. The content of the clipboard is not changed. |
Delete | Deletes the current selection from the document. The content of the clipboard is not changed. This command does not involve the clipboard, but it should appear with the clipboard commands on the Edit menu. |
Clipboard Sequence Number
The clipboard for each window station has an associated clipboard sequence number. This number is incremented whenever the contents of the clipboard change. To obtain the clipboard sequence number, call the GetClipboardSequenceNumber function.
Clipboard Viewers
A clipboard viewer is a window that displays the current content of the clipboard. The clipboard viewer window is a convenience for the user and does not affect the data-transaction functions of the clipboard.
Typically, a clipboard viewer window can display at least the three most common formats: CF_TEXT, CF_BITMAP, and CF_METAFILEPICT. If a window does not make data available in any of these three formats, it should provide data in a display format or use the owner-display format.
A clipboard viewer chain is the linking together of two or more entities so that they are dependent upon one another for operation. This interdependency (chain) allows all running clipboard viewer applications to receive the messages sent to the current clipboard.
The following topics are discussed in this section.
Clipboard Viewer Windows
A window adds itself to the clipboard viewer chain by calling the SetClipboardViewer function. The return value is the handle to the next window in the chain. To retrieve the handle to the first window in the chain, call the GetClipboardViewer function.
Each clipboard viewer window must keep track of the next window in the clipboard viewer chain. When the content of the clipboard changes, the system sends a WM_DRAWCLIPBOARD message to the first window in the chain. After updating its display, each clipboard viewer window must pass this message on to the next window in the chain.
Before closing, a clipboard viewer window must remove itself from the clipboard viewer chain by calling the ChangeClipboardChain function. The system then sends a WM_CHANGECBCHAIN message to the first window in the chain.
Display Formats
A display format is a clipboard format used to display information in a clipboard viewer window. A clipboard owner that uses a private or registered clipboard format, and none of the most common standard formats, must provide data in a display format for viewing in a clipboard viewer window. The display formats are intended for viewing only and must not be pasted into a document.
The four display formats are: CF_DSPBITMAP, CF_DSPMETAFILEPICT, CF_DSPTEXT, and CF_DSPENHMETAFILE. These display formats are rendered in the same way as the standard formats, which are: CF_BITMAP, CF_TEXT, CF_METAFILEPICT, and CF_ENHMETAFILE.
Owner Display Format
For a clipboard owner that does not use any of the common standard clipboard formats, an alternative to providing a display format is to use the owner-display (CF_OWNERDISPLAY) clipboard format.
By using the owner-display format, a clipboard owner can avoid the overhead of rendering data in an additional format by taking direct control over painting the clipboard viewer window. The clipboard viewer window sends messages to the clipboard owner whenever a portion of the window must be repainted or when the window is scrolled or resized.