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.

LRESULT CALLBACK MainWindowProc(hwnd, msg, wParam, lParam)

HWND hwnd;

UINT msg;

WPARAM wParam;

LPARAM lParam;

{

static RECT rcViewer;

RECT rc;

LPRECT lprc;

LPPAINTSTRUCT lpps;

switch (msg)

{

//

// Handle other messages.

//

case WM_PAINTCLIPBOARD:

// Determine the dimensions of the label.

SetRect(&rc, 0, 0,

pboxLocalClip->rcText.right + CX_MARGIN,

pboxLocalClip->rcText.top * 2 + cyText

);

// Center the image in the clipboard viewer window.

if (rc.right < rcViewer.right)

{

rc.left = (rcViewer.right - rc.right) / 2;

rc.right += rc.left;

}

if (rc.bottom < rcViewer.bottom)

{

rc.top = (rcViewer.bottom - rc.bottom) / 2;

rc.bottom += rc.top;

}

// Paint the image, using the specified PAINTSTRUCT

// structure, by calling the application-defined

// PaintLabel function.

lpps = (LPPAINTSTRUCT) GlobalLock((HGLOBAL) lParam);

PaintLabel(lpps, pboxLocalClip, &rc);

GlobalUnlock((HGLOBAL) lParam);

break;

case WM_SIZECLIPBOARD:

// Save the dimensions of the window in a static

// RECT structure.

lprc = (LPRECT) GlobalLock((HGLOBAL) lParam);

memcpy(&rcViewer, lprc, sizeof(RECT));

GlobalUnlock((HGLOBAL) lParam);

// Set the scroll ranges to zero (thus eliminating

// the need to process the WM_HSCROLLCLIPBOARD and

// WM_VSCROLLCLIPBOARD messages).

SetScrollRange((HWND) wParam, SB_HORZ, 0, 0, TRUE);

SetScrollRange((HWND) wParam, SB_VERT, 0, 0, TRUE);

break;

case WM_ASKCBFORMATNAME:

LoadString(hinst, IDS_OWNERDISPLAY,

(LPSTR) lParam, wParam);

break;

default:

return DefWindowProc(hwnd, msg, wParam, lParam);

}

return 0;

}