Опубликован: 17.08.2010 | Доступ: свободный | Студентов: 999 / 59 | Оценка: 4.11 / 3.89 | Длительность: 29:38:00
Самостоятельная работа 16:

Динамически загружаемые библиотеки MFC

Подключение библиотечного модуля

После создания оболочки тестового приложения к нему необходимо подключить библиотечный модуль.

  • Выполните через главное меню оболочки команду Project/Add Existing Item (Добавить существующий элемент)
  • В открывшемся диалоговом окне настройте фильтр 'Files of type:' на значение All Files (*.*)
  • Найдите в каталоге проекта предыдущего DLL -приложения файл с расширением .lib и выберите его в диалоговое окно

  • Посмотрите в панели Solution Explorer и убедитесь, что файл подключен к проекту тестового приложения

Подключение заголовочных файлов

После подключения библиотечного модуля необходимо в тестовое приложение добавить подключение заголовочных файлов всех упакованных в DLL классов, которые будут использоваться в соответствующих файлах исходных текстов, для их видимости компилятором.

  • Выполните команду Project/Add Existing Item (Добавить существующий элемент)
  • В открывшемся диалоговом окне найдите папку DLL -проекта и выберите файл MyModArt.h

  • После щелчка на кнопке Open заголовочный файл добавится к проекту, в чем можно убедиться по панели Solution Explorer

Замечание. Необходимо добавлять заголовочные файлы только тех экспортируемых классов, упакованных в DLL, которые действительно будут использованы в проекте. Если же будут добавлены в приложение заголовочные файлы классов, не востребуемых приложением, то могут возникнуть ошибки линковщика.

Создание экземпляра библиотечного класса

Все функциональные возможности по созданию рисунка из случайных волнистых линий заложены нами ранее в класс MyModArt, который мы создали в DLL -проекте и упаковали его в DLL -библиотеку. В данном тестовом приложении мы создадим экземпляр этого класса и включим его в класс документа.

  • панели Class View выделите класс CTestArtDoc и через контекстное меню Add/Add Variable... вызовите мастер, который заполните так

Мастер включит следующее объявление экземпляра в класс CTestArtDoc:

Создание объекта в файле TestArtDoc.h
class CTestArtDoc : public CDocument
{
......................
private:
  // Объект рисования волнистых линий
  MyModArt m_Drawing;
};

Теперь у нас в классе документа тестового приложения имеется объект, созданный как экземпляр DLL -библиотечного созданного нами ранее класса MyModArt. И мы можем организовать управление этим объектом и заставить его выполнить в тестовом приложении те функциональности, которые нами были в него заложены ранее.

Создание нового рисунка

При создании объекта нового документа в тестовом приложении автоматически срабатывает функция OnNewDocument() этого объекта. Разместим в этой функции блок кода по управлению объектом m_Drawing, чтобы он создал новый рисунок. Для этого нужно получить от класса представления координаты клиентской области рисования и передать объекту m_Drawing. Затем дать команду этому объекту сгенерировать внутри себя полный рисунок, который позднее можно передать для рисования классу представления.

  • Для реализации сказанного дополните функцию OnNewDocument() класса документа следующим кодом
    Дополнение OnNewDocument() в файле TestArtDoc.cpp
    BOOL CTestArtDoc::OnNewDocument()
    {
      if (!CDocument::OnNewDocument())
        return FALSE;
    
      // TODO: add reinitialization code here
      // (SDI documents will reuse this document)
    
      // Получить позицию от представления
      POSITION pos = GetFirstViewPosition();
      if(pos != NULL){
        // Получить указатель на представление View
        CView *pView = GetNextView(pos);
        RECT rWndRect;// Создать структуру
        // Заполнить структуру координатами области рисования
        pView->GetClientRect(&rWndRect);
        // Передать область в наш объект генерации линий
        m_Drawing.SetRect(rWndRect);
        // Сгенерировать координаты линий всего рисунка
        m_Drawing.NewDrawing();
      }
    
      return TRUE;
    }
Сохранение, открытие и удаление рисунка

В класс документа добавим функциональность по управлению возможностью сохранения, восстановления и удаления рисунка.

  • Для сохранения в файле и восстановления из файла отредактируйте в классе документа тестового приложения функцию-член Serialize() следующим образом
    Редактирование функции Serialize() в файле TestArtDoc.cpp
    // CTestArtDoc serialization
      
    void CTestArtDoc::Serialize(CArchive& ar)
    {
      m_Drawing.Serialize(ar);
    }

Редактирование заключается в полном удалении текущего автоматически сгенерированного мастером кода и замене его вызовом функции Serialize() класса рисования MyModArt.

Теперь следует добавить функцию для удаления текущего рисунка. Она должна очищать объект m_Drawing тогда, когда создается новый или открывается сохраненный ранее рисунок. В обеих этих случаях автоматически срабатывает функция DeleteContents() базового класса CDocument. Ее и нужно переопределить в нашем классе документа CTestArtDoc, являющимся расширением базового класса CDocument.

  • В панели Class View выделите класс CTestArtDoc
  • В панели Properties переключитесь в режим Overrides
  • Найдите функцию DeleteContents() и добавьте ее заготовку в класс документа

  • Отредактируйте заготовку функции так
    Переопределение функции DeleteContents() базового класса CDocument в производном классе CTestArtDoc файла TestArtDoc.cpp
    void CTestArtDoc::DeleteContents()
    {
      // TODO: Add your specialized
      // code here and/or call the base class
      // Очищаем массив объектов класса рисунка
      m_Drawing.ClearDrawing();
      
      CDocument::DeleteContents();
    }
Отображение рисунка

За отображение данных, хранящихся в объекте рисунка m_Drawing класса MyModArt, в нашем тестовом SDI -приложении отвечает класс представления CTestArtView. Именно объект класса представления знает, когда нужно себя перерисовать. Для того, чтобы в классе представления можно было управлять объектом m_Drawing, который умеет себя нарисовать с помощью своего метода Draw(CDC* pDC) , добавим в класс документа функцию-член, возвращающую указатель на этот объект m_Drawing.

  • Выделите в панели Class View класс CTestArtDoc
  • Через контекстное меню вызовите мастер добавления функций, который заполните так

  • Созданную мастером заготовку функции отредактируйте так

    Функция доступа к объекту m_Drawing
    // Возвращает указатель на объект рисования
    MyModArt* CTestArtDoc::GetDrawing(void)
    {
      return &m_Drawing;
    }

    Чтобы добавить возможность отображения рисунка в наше приложение, нужно в функции OnDraw() класса представления получить указатель на объект с рисунком, затем вызвать через этот указатель функцию Draw() объекта m_Drawing. Вспомним, что координаты области рисования сохранены в объекте ранее в функции OnNewDocument() класса документа и там же выполнена генерация рисунка.

  • Найдите в файле TestArtView.cpp реализацию функции OnDraw() класса представления и отредактируйте ее так
    Функция OnDraw() в файле TestArtView.cpp
    void CTestArtView::OnDraw(CDC* pDC)
    {
      CTestArtDoc* pDoc = GetDocument();
      ASSERT_VALID(pDoc);
      if (!pDoc)
        return;
      
      // TODO: add draw code for native data here
      
      // Получить указатель на объект рисунка
      MyModArt *pDrawing = pDoc->GetDrawing();
      // Вывести рисунок
      pDrawing->Draw(pDC);
    }
  • Не забудьте раскомментировать аргумент pDC функции OnDraw()
  • С помощью проводника по файлам найдите в каталоге Debug или Release DLL -приложения файл ModArtDll.dll, созданный ранее, и скопируйте его в каталог Debug или Release данного проекта тестового приложения туда, где будет храниться исполнимый файл теста
  • Постройте проект и убедитесь, что все работает

Экран тестового приложения должен примерно выглядеть так


  • Оформите диалоговое окно About со своими атрибутами и смените иконку приложения. Не забудьте, при этом, прежде русифицировать ресурс диалогового окна

Александр Даниленко
Александр Даниленко
Стоит Windows 8 Pro, Visual Studio 2010 Express Edition .