Работа с буфером обмена - Использование формата буфера обмена CF_OWNERDISPLAY

ОГЛАВЛЕНИЕ

 

Использование формата буфера обмена CF_OWNERDISPLAY

Если Вы помещаете данные в буфер обмена, используя формат CF_OWNERDISPLAY, то необходимо проделать следующее:

  • Обработать сообщение WM_PAINTCLIPBOARD. Это сообщение посылается владельцу буфера обмена, когда его "окно" должно быть перерисовано.
  • Обработать сообщение WM_SIZECLIPBOARD. Это сообщение посылается владельцу буфера обмена, когда размеры его "окна" изменились либо изменилось его содержимое.

    Обычно при этом, устанавливается положение скрола и диапазон скроллирования окна буфера обмена.

  • Обработать сообщения WM_HSCROLLCLIPBOARD и WM_VSCROLLCLIPBOARD. Эти сообщения посылаются владельцу буфера обмена, когда "окно" буфера обмена было проскроллировано.
  • Обработать сообщение WM_ASKCBFORMATNAME. Это сообщение посылает буфер обмена приложению, чтобы узнать формат.

Ниже представлена оконная процедура, с обработкой этих сообщений.

Пример:

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)
{
//
// Обрабатываем другие сообщения.
//
case WM_PAINTCLIPBOARD:
// Определяем размер лабела.

SetRect(&rc, 0, 0,
pboxLocalClip->rcText.right + CX_MARGIN,
pboxLocalClip->rcText.top * 2 + cyText
);

// Центрируем картинку в окне буфера обмена.

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;
}

// Рисуем изображение, используя структуру PAINTSTRUCT.

lpps = (LPPAINTSTRUCT) GlobalLock((HGLOBAL) lParam);
PaintLabel(lpps, pboxLocalClip, &rc);
GlobalUnlock((HGLOBAL) lParam);
break;

case WM_SIZECLIPBOARD:
// Записываем размеры окна в статической
// структуре RECT.

lprc = (LPRECT) GlobalLock((HGLOBAL) lParam);
memcpy(&rcViewer, lprc, sizeof(RECT));
GlobalUnlock((HGLOBAL) lParam);

// Устанавливаем диапазон скроллирования в ноль.

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;