В приложении 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;
}
|