Если окно передает дескриптор со значением ПУСТО (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); } } |