Разработка библиотеки-расширения
Методические указания. В целом последовательность создания собственного DLL-расширения MFC включает следующие основные этапы:
· создание каркаса библиотеки с помощью мастера MFC AppWizard (dll);
· добавление в библиотеку класса (классов);
· компиляция и сборка библиотеки.
Это все правильно, если класс уже есть, причем отлаженный, а ежели его нет? Тогда надо сначала разработать и отладить класс, а уже потом создавать библиотеку и включать в нее класс. Хотя, как говорилось выше, можно заниматься и отладкой библиотеки при наличии, естественно, клиентского приложения.
Шаг 1. Создание тестового клиентского приложения для отладки класса.
Создайте приложение с графическим интерфейсом пользователя (GUI), отключите в нем поддержку архитектуры документ/вид. Собственно, нам необходимо простейшее приложение, в котором мы могли бы отладить класс, предназначенный для построения графика некоторой функции. Назовите проект, допустим, TestCls, хотя это и не имеет решающего значения.
В качестве примера предлагается разработать класс, предназначенный для построения графика функции одного аргумента. График функции будет выглядеть так, как на рис. 1.
|
Рис. 1. Реализация класса для построения графика функции в действии
Если вам такой класс покажется ну совсем уж не заслуживающим вашего внимания – напишите свой, лучший, или доработайте предлагаемый.
Итак, добавьте в приложение новый класс (ProjectèAdd class) и не забудьте выбрать шаблон класса «С++ Class». Если вы его нарекли как CGraphic, то получите два файла: Graphic.h и Graphic.cpp. Доведите содержимое этих файлов до приведенного ниже вида и осмыслите приведенный код.
![]() |
![]() |
![]() |
![]() |
// выбираем новое перо CPen newPen(PS_DOT,2,(COLORREF)255); /* красное перо шириной 2 пиксела*/ cdc.SelectObject(&newPen); // рисование графика double scx,scy; if(fabs(X[0])>X[Count-1]) scx=fabs(X[0])/(Width/2); else scx=X[Count-1]/(Width/2); double maxy=fabs(Y[0]); for(int i=1;i<Count;i++) if(maxy<fabs(Y[i])) maxy=fabs(Y[i]); scy=maxy/(Height/2); scy*=1.1; scx*=1.1; int ix,iy; ix=X[0]/scx+xc; iy=-Y[0]/scy+yc; cdc.MoveTo(ix,iy); for(int i=1;i<Count;i++) { ix=X[i]/scx+xc; iy=-Y[i]/scy+yc; cdc.LineTo(ix,iy); } ////////////////////////////////////////////////////// cdc.SelectStockObject(BLACK_PEN); // newPen отсоединяется return true; } |
Шаг 2. Включение класса в тестовое приложение.
Если вы создали тестовое приложение в соответствии с приведенными выше рекомендациями, то в вашем проекте будет файл с именем ChildView.cpp. Добавьте в начало этого файла директивы препроцессора:
#include "Graphic.h"
#include <math.h>
Класс CGraphic можно использовать по-разному, многими способами. Главное – передать конструктору класса указатель на окно, в котором должен быть прорисован график. Если после вывода графика его надо перерисовать в связи с тем, что требуется обновить изображение в окне по какой-либо веской причине (окно было перекрыто, были изменены его размеры и т.п.), то требуется повторно вызвать метод класса DrawGraphic().
В данном случае мы поступим примитивно и поместим весь код в метод CChildView::OnPaint(), который вызывается системой всякий раз, когда содержимое окна надо обновить (то что доктор прописал!). Итак, наполните этот метод таким немудреным кодом:
![]() |
Если вы бог, то программа должна сразу откомпилироваться и работать «как часы». В противном случае у вас появится возможность проявить свои недюжинные способности в отладке программы. Проверьте, что при изменении размеров окна график, как по мановению волшебной палочки, быстренько перерисовывается, а по завершению программы в окне Debug нет оскорбляющих ваше самолюбие сообщений вроде “Memory leaks …”.
Шаг 3. Создание каркаса библиотеки DLL-расширения.
Выполните, как обычно при создании нового проекта, команду FileèNew Project и в появившемся окне задайте Project types==MFC, Templates==MFC DLL, Name==ExtDLL. Навалитесь на ОК, на вкладке Application Settings выберите (обязательно!) DLL type==MFC extension DLL, налягте на Finish. Поставьте свечку в церкви во благополучие Вашего проекта и возвращайтесь к продолжению работы.
Просмотрите и проанализируйте файл ExtDLL.cpp, который содержит, кроме директив препроцессора, только заготовку функции DllMain(). Сравните: в обычной (RegDLL) библиотеке этой функции не было, так что свечку вы покупали не напрасно.
Шаг 4. Включение в библиотеку класса CGraphic.
Скопируйте файлы Graphic.h и Graphic.cpp в каталог этого проекта библиотеки и с помощью команды меню ProjectèAdd Existing Itemвыберите и включите эти файлы в проект. Пока вы никаких видимых изменений в файлах проекта не заметите, даже если и обладаете экстрасенсорными способностями и умеете ходить туда-сюда не только по прототипам, но и по виртуальным реальностям.
Шаг 5. Редактирование файла Graphic.h.
В этом файле надо заменить строку
Class CGraphic
на следующую
class AFX_EXT_CLASS CGraphic
Макрос AFX_EXT_CLASS намекает на то, что этот класс экспортируется библиотекой. Клиентское приложение, использующее библиотеку, тоже должно в соответствующем заголовочном файле (Graphic.h) содержать этот макрос.
Шаг 6. Постройте библиотеку с помощью команды меню BuildèBuild ExtDLL.dll.
В папке …\ExtDLL\Debug вы должны обнаружить файлы ExtDLL.dll и ExtDLL.lib. Если их там нет, значит, они были съедены вирусами, которым очень нравятся библиотеки.