В прикладной программе Метка, функция EditCopy, определяемая программой, копирует текущий выбор в буфер обмена. Эта функция делает следующее:
В зависимости от текущего выбора, функция EditCopy или копирует область текста, или копирует определяемую программой структуру, представляющую всю пометку. Структура, названная LABELBOX, определяется следующим образом.
#define BOX_ELLIPSE 0 #define BOX_RECT 1 #define CCH_MAXLABEL 80 #define CX_MARGIN 12 typedef struct tagLABELBOX { // box (окно) 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_DDESHARE, (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; }