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


В приложении Label, определяемая программой функция EditCopy копирует текущий выбор в буфер обмена. Эта функция делает перечисленное ниже:

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

В зависимости от текущего выбора, функция 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; 
}

 

Назад в оглавление темы
На главную страницу темы

Hosted by uCoz