Страница 14 из 55
Копирование информации в Буфер обмена В прикладной программе Метка, функция EditCopy, определяемая программой, копирует текущий выбор в буфер обмена. Эта функция делает следующее: - Открывает буфер обмена путем вызова функции OpenClipboard.
- Очищает буфер обмена путем вызова функции EmptyClipboard.
- Вызывает функцию SetClipboardData для каждого формата буфера обмена, которыми обеспечена прикладная программа.
- Закрывает буфер обмена путем вызова функции CloseClipboard.
В зависимости от текущего выбора, функция 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; }
|