Если окно передает дескриптор со значением ПУСТО (NULL) в функцию SetClipboardData, оно должно обрабатывать сообщения WM_RENDERFORMAT и WM_RENDERALLFORMATS, чтобы предоставлять данные по запросу.
Если сообщение WM_RENDERFORMAT задерживает предоставление конкретного формата, а приложение требует данные в этом формате, сообщение отправляется владельцу буфера обмена. Если сообщение WM_RENDERFORMAT задерживает предоставление одного или нескольких форматов, сообщение отправляется владельцу буфера обмена до того, как оно разрушается.
Чтобы предоставить формат буфера обмена, оконная процедура должна поместить дескриптор данных в буфер обмена при помощи использования функции SetClipboardData. Не нужно открывать буфер обмена перед вызовом SetClipboardData.
Приложение Label обрабатывает сообщения WM_RENDERFORMAT и WM_RENDERALLFORMATS как указано ниже.
case WM_RENDERFORMAT:
RenderFormat((UINT) wParam);
break;
case WM_RENDERALLFORMATS:
RenderFormat(uLabelFormat);
RenderFormat(CF_TEXT);
break;
|
В обоих случаях оконная процедура вызывает определяемую программой функцию RenderFormat, определяемую как ниже указано.
Структура, называемая LABELBOX, определяется как ниже указано.
Демонстрационный пример
#define BOX_ELLIPSE 0
#define BOX_RECT 1
#define CCH_MAXLABEL 80
#define CX_MARGIN 12
typedef struct tagLABELBOX { // окно
RECT rcText; // координаты прямоугольника с текстом
BOOL fSelected; // TRUE, если ярлык выбран
BOOL fEdit; // TRUE, если текст выбран
int nType; // прямоугольный или эллиптический
int ichCaret; // позиция каретки
int ichSel; // с ichCaret, разграничивает выбор
int nXCaret; // позиция окна, соответствующая ichCaret
int nXSel; // позиция окна, соответствующая ichSel
int cchLabel; // протяженность текста в atchLabel
TCHAR atchLabel[CCH_MAXLABEL];
} LABELBOX, *PLABELBOX;
|
Демонстрационный пример
void WINAPI RenderFormat(UINT uFormat)
{
HGLOBAL hglb;
PLABELBOX pbox;
LPTSTR lptstr;
int cch;
if (pboxLocalClip == NULL)
return;
if (uFormat == CF_TEXT)
{
// Выделяем буфер для текста.
cch = pboxLocalClip->cchLabel;
hglb = GlobalAlloc(GMEM_MOVEABLE,
(cch + 1) * sizeof(TCHAR));
if (hglb == NULL)
return;
// Копируем текст из pboxLocalClip.
lptstr = GlobalLock(hglb);
memcpy(lptstr, pboxLocalClip->atchLabel,
cch * sizeof(TCHAR));
lptstr[cch] = (TCHAR) 0;
GlobalUnlock(hglb);
// Помещаем дескриптор в буфер обмена.
SetClipboardData(CF_TEXT, hglb);
}
else if (uFormat == uLabelFormat)
{
hglb = GlobalAlloc(GMEM_MOVEABLE, sizeof(LABELBOX));
if (hglb == NULL)
return;
pbox = GlobalLock(hglb);
memcpy(pbox, pboxLocalClip, sizeof(LABELBOX));
GlobalUnlock(hglb);
SetClipboardData(uLabelFormat, hglb);
}
}
|