Работа с буфером обмена - Копирование информации в буфер обмена

ОГЛАВЛЕНИЕ

 

Копирование информации в буфер обмена

Процесс копирования информации в буфер обмена осуществляется следующим образом:

  1. Открываем буфер обмена функцией OpenClipboard.
  2. Очищаем буфер обмена функцией EmptyClipboard.
  3. Вызываем функцию SetClipboardData для каждого формата буфера обмена, которые поддерживает приложение.
  4. Закрываем буфер обмена функцией CloseClipboard.

Для того чтобы скопировать выделенный текст, используется следующая структура:

#define BOX_ELLIPSE  0
#define BOX_RECT 1

#define CCH_MAXLABEL 80
#define CX_MARGIN 12

typedef struct tagLABELBOX {
RECT rcText; // координаты прямоугольника с текстом
BOOL fSelected; // TRUE если выделен label
BOOL fEdit; // TRUE если текст выделен
int nType; // прямоугольное или овальное
int ichCaret; // позиция каретки
int ichSel; // with ichCaret, delimits selection
int nXCaret; // window position corresponding to ichCaret
int nXSel; // window position corresponding to 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();

// Получаем указатель на структуру LABELBOX.

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);
}

// Если текст не выделен, то копируем весь label.

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;

// Помещаем в буфер обмена данные трёх форматов.

SetClipboardData(uLabelFormat, NULL);
SetClipboardData(CF_OWNERDISPLAY, NULL);
SetClipboardData(CF_TEXT, NULL);
}

// Закрываем буфер обмена.

CloseClipboard();

return TRUE;
}