Дополняем наш проект. Нам нужно создать новый класс. Создадим его мы другим методом. Как положено. Описание класса в своем заголовочном файле, а реализация в своем файле. Для того, чтобы добавить в проект класс нужно перейти в окно Class View(просмотр классов), нажать правую кнопку мышки на элементе step16 classes и выбрать пункт меню New Class (новый класс).
Появится диалоговое окно. Заполняем его.
Внизу можно указать класс отца, но он нам не нужен. Посмотрите на ClassView, там Вы должны увидеть, что в проекте появился новый класс.
Нам нужно подключить описание этого класс к нашему коду.
...... #include "resource.h" // Идентификаторы ресурсов #include "MyClip.h" // описание нашего класса #define IDC_MYBUTTON 100 // Идентификатор кнопки ......
В описание класса CMyClip нужно добавить описание двух функций.
// MyClip.h: interface for the CMyClip class. // ///////////////////////////////////////////// #if !defined(AFX_MYCLIP_H__3F50824B_6C97_11D5_B617_D466F313FE46__INCLUDED_) #define AFX_MYCLIP_H__3F50824B_6C97_11D5_B617_D466F313FE46__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "afxwin.h" class CMyClip { public: CMyClip(); virtual ~CMyClip(); void CopyText(CString test); CString GetText(); }; #endif // !defined(AFX_MYCLIP_H__3F......__INCLUDED_)
И реализация функций:
// MyClip.cpp: implementation of the CMyClip class. // ////////////////////////////////////////////////////// #include "MyClip.h" /////////////////////////////////////////// // Construction/Destruction /////////////////////////////////////////// CMyClip::CMyClip() { } CMyClip::~CMyClip() { } CString CMyClip::GetText() { char * buffer; // указатель на данные if(AfxGetMainWnd()->OpenClipboard()) // если буфер обмена удалось открыть, то { buffer = (char*)GetClipboardData(CF_TEXT);// получить из буфера текст CloseClipboard(); // закрыть буфер обмена return buffer; // вернуть результат } return ""; } void CMyClip::CopyText(CString test) { if (AfxGetMainWnd()->OpenClipboard())// если буфер обмена удалось открыть то { if (EmptyClipboard()) // Очистить буфер { HGLOBAL clipbuffer; char * buffer; // указатель на данные clipbuffer = GlobalAlloc(GMEM_DDESHARE, test.GetLength()+1);// выделить память buffer = (char*)GlobalLock(clipbuffer); // блокировать буфер strcpy(buffer, LPCSTR(test)); // копировать в него данные GlobalUnlock(clipbuffer); // разблокировать SetClipboardData(CF_TEXT,clipbuffer); // установить данные и тип if (!CloseClipboard()) AfxMessageBox("Error Close");// закрыть } else AfxMessageBox("Error Empty"); } else AfxMessageBox("Error Open"); }
Объявите класс буфера и функцию реакции:
class CMainWnd : public CFrameWnd { public: CMainWnd(); // Конструктор по умолчанию void OnCopyBuffer();// копировать в буфер void OnOpen(); // эта функция вызовется при выборе меню Open ...... CMenu m_wndMenu; // Это наш класс Меню CMyClip clip; // Это класс буфера обмена DECLARE_MESSAGE_MAP();// таблица откликов }
Необходимо создать реакцию на одинарное нажатие кнопки:
BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd)// таблица откликов на сообщения ...... ON_COMMAND(ID_OPEN,OnOpen) // Реакция на выбор меню Open ON_BN_CLICKED(IDC_MYBUTTON,OnCopyBuffer) // нажали на кнопку левой кнопкой мыши ON_COMMAND(ID_FILE_EXIT,MenuExit) // Вот она, обработка реакции на выбор меню ......
И реализацию реакции:
void CMainWnd::OnCopyBuffer() { clip.CopyText("Hello My Text"); // копировать в буфер текст }
Поменяем действия по нажатию на клавишу:
void CMainWnd::OnKeyDown( UINT, UINT, UINT) { AfxMessageBox(clip.GetText()); // показать текст }
В объявлении класса ничего нового, мы подключили стандартную библиотеку MFC для доступа к функциям. Ведь данный файл будет отдельным объектным файлом obj и ему необходим доступ к библиотекам. Смотрим функцию CopyText нам для работы необходимо открыть буфер. Но для этого необходим указатель на наше окно. Вот мы его и открываем OpenClipboard(), буфер открыть можно не всегда поэтому эта функция BOOL.
Дальше мы очищаем буфер и заводим две переменные. Буфер, как видите, очистить тоже можно не всегда. HGLOBAL - это указатель на переменную, но не простую, а на глобальную. К ней доступ будет из любого места памяти (из любой программы), ведь это же буфер обмена, правда?
Дальше для этого буфера выделяем память, по размеру как переданная строка+1 и с атрибутом GMEM_DDESHARE, что говорит про то, что мы не жадные и разрешаем к ней доступ. После этого мы блокируем память для копирования. Ведь у нас многозадачная среда, и если в момент копирования кто-то потянет руки к памяти, будет нехорошо. Одновременно приравнивая указатель с локальным buffer. Теперь будем копировать.
После копирования необходимо память разблокировать. И только потом установить в буфер текст, еще и указав тип. Ведь в буфере могут быть данные любого типа TEXT,RTF,BMP,WMF,OLE и т.д. После всех операций буфер нужно закрыть.
Функция GetText() получает данные, методика похожа, за исключением функции GetClipboardData() с указанием типа получаемой информации.
Теперь пробуем. Запустите блокнот NotePad. Запустите нашу программу. Введите в блокноте слово и скопируйте его в буфер. Перейдите в программу и нажмите на пробел. Вы увидите содержимое буфера.
Теперь нажмите на кнопку. В буфер поместится текст. Вставьте его в блокнот. Там будет Hello My Text. Ну вот, немного терпения и все работает.
Откройте буфер:
...... if (AfxGetMainWnd()->OpenClipboard())// если буфер обмена удалось открыть то ......
Очистите:
...... if (EmptyClipboard()) // Очистить буфер ......
Выделите глобальную память и скопируете туда строку.
...... clipbuffer = GlobalAlloc(GMEM_DDESHARE, test.GetLength()+1);// выделить память ...... strcpy(buffer, LPCSTR(test));// копировать в него данные ......
Установите данные:
...... SetClipboardData(CF_TEXT,clipbuffer);// установить данные и тип ......
Закройте буфер:
...... if (!CloseClipboard()) AfxMessageBox("Error Close");// закрыть ......