В приложении Label, определяемая программой функция EditCopy копирует текущий выбор в буфер обмена. Эта функция делает перечисленное ниже:
В зависимости от текущего выбора, функция EditCopy или копирует блок текста, или копирует определенную приложением структуру, представляющую запись ярлыка. Структура, названная 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; |
Ниже определение функции EditCopy.
Демонстрационный пример
BOOL WINAPI EditCopy(VOID) { PLABELBOX pbox; LPTSTR lptstrCopy; HGLOBAL hglbCopy; int ich1, ich2, cch; if (hwndSelected == NULL) return FALSE; // Открываем буфер обмена и очищаем его. if (!OpenClipboard(hwndMain)) return FALSE; EmptyClipboard(); // Получаем указатель на структуру для выбранной метки. pbox = (PLABELBOX) GetWindowLong(hwndSelected, 0); // Если выбран текст, то для его копирования // используем формат CF_TEXT. if (pbox->fEdit) { if (pbox->ichSel == pbox->ichCaret) // выбор нулевой длины { CloseClipboard(); return FALSE; } if (pbox->ichSel < pbox->ichCaret) { ich1 = pbox->ichSel; ich2 = pbox->ichCaret; } else { ich1 = pbox->ichCaret; ich2 = pbox->ichSel; } cch = ich2 - ich1; // Для текста назначаем глобальный объект памяти. hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (cch + 1) * sizeof(TCHAR)); if (hglbCopy == NULL) { CloseClipboard(); return FALSE; } // Блокируем дескриптор и копируем текст в буфер. lptstrCopy = GlobalLock(hglbCopy); memcpy(lptstrCopy, &pbox->atchLabel[ich1], cch * sizeof(TCHAR)); lptstrCopy[cch] = (TCHAR) 0; // символ нуля GlobalUnlock(hglbCopy); // Помещаем дескриптор в буфер обмена. SetClipboardData(CF_TEXT, hglbCopy); } // Если текст выбран, ярлык копируется полностью. else { // Сохраним копию выбранного ярлыка как локальный объект // памяти. Эта копия используется для предоставления данных // по запросу. Она освобождается в ответ на сообщение // WM_DESTROYCLIPBOARD. pboxLocalClip = (PLABELBOX) LocalAlloc( LMEM_FIXED, sizeof(LABELBOX) ); if (pboxLocalClip == NULL) { CloseClipboard(); return FALSE; } memcpy(pboxLocalClip, pbox, sizeof(LABELBOX)); pboxLocalClip->fSelected = FALSE; pboxLocalClip->fEdit = FALSE; // Поместим зарегистрированный формат, собственный // дисплейный формат и формат CF_TEXT в буфер обмена, // используя отложенное предоставление. SetClipboardData(uLabelFormat, NULL); SetClipboardData(CF_OWNERDISPLAY, NULL); SetClipboardData(CF_TEXT, NULL); } // Закроем буфер обмена. CloseClipboard(); return TRUE; } |