Программирование под Windows с использованием MFC


Основа архитектуры «документ\представление»

  • Создание различных типов документов
  • Шаблоны однодокументных приложений
  • Шаблоны многодокументных приложений
  • Место объекта-приложения в архитектуре "документ/представление"
  • Роль фреймов в архитектуре "документ/представление"
  • Создание каркаса приложения на базе архитектуры "документ/представление"

Каждое приложение, написанное для Windows, имеет одно главное окно, которое состоит из двух компонентов — фрейма и клиентской (рабочей) области. Оно может быть как стандартным окном Windows (например, при построении SDI- и MDI-приложений), так и обычным блоком диалога. В любом случае внутри главного окна приложение предоставляет пользователю всю необходимую для работы информацию, представляющую собой не только данные, т. е. текст, рисунки и т. п., но и элементы интерфейса — меню, полосы прокрутки, панели инструментов, строка состояния и т. д. Каждый из этих элементов (по крайней мере, для приложений, созданных с использованием библиотеки MFC) является объектом, в состав которого входят функции, определяющие его поведение, т. е. взаимодействие как с другими объектами, так и с данными. Любые действия пользователя во время выполнения приложения вызывают генерацию сообщений, содержащих в себе информацию о том, что конкретно сделал пользователь. Все объекты приложения обладают способностью реагировать на те или иные сообщения. Во многих случаях эта способность заложена в библиотеке MFC, а для других реализуются специальные обработчики. Повторю — все перечисленные свойства характерны (с той или иной степенью полноты) для каждого Windows-приложения.

Оставим в стороне приложения, базирующиеся на блоках диалога, и сосредоточимся на тех, которые в качестве своего главного окна имеют стандартное окно Windows. Основным для таких окон является объект, созданный на базе класса CFrameWnd (для SDI-приложений) или CMDlFmmeWnd (для

MDI-приложений). То, что делалось до сих пор, заключалось в создании некоторых необходимых оконных объектов и самостоятельной организации взаимодействия между ними. Мы полностью (более того — сознательно) игнорировали такое мощное средство, заложенное разработчиками в библиотеку MFC, как архитектура "документ/представление" (document/view).

Что же включают в себя эти понятия? В самом общем случае, под документом фирма Microsoft понимает те данные, с которыми работает приложение. Это может быть все что угодно, — "простой" текст, картинка и т. п. Отображение этих данных на экране осуществляется в так называемом фрейме документа. Разработчики библиотеки MFC создали для фреймов специальные классы окон — представления, которые отображают данные документа и управляют взаимодействием пользователя с ними. Другими словами, способ хранения данных в памяти или на диске никоим образом не влияет на их внешнее представление пользователю.

Рассматриваемая архитектура основывается на создании соответствующих фреймов документов, содержащих специальные окна — представления. Кроме того, фрейм осуществляет координацию взаимодействия между документами различных типов и их представлениями, направляя им команды и получая от них извещения. Маршруты, по которым осуществляется передача сообщений, подробно описаны нами в части 4 данного руководства.

Архитектура "документ/представление" разделяет между собой данные-документы и их изображения. Каждый документ представлен в виде объекта, который обеспечивает пространство для хранения данных в памяти и отвечает за такие операции, как запись и чтение документа с диска. Очевидно, что большая часть таких операций выполняется самим приложением, а не классами библиотеки MFC. Кроме того, для каждого используемого представления также создается отдельный объект, который представляет собой экранное окно, отвечающее за взаимодействие с пользователем и соответствующим объектом документа, печать и т. д. Совместную работу перечисленных объектов координирует фрейм, который в большинстве случаев является главным окном приложения.

Пример приложения:


Когда запускается приложение под Windows, пользователь взаимодействует с документами посредством их изображений во фреймах. Фреймы документов имеют два основных компонента: собственно фрейм и его содержимое. Для них библиотека MFC использует два различных класса. Класс фрейма управляет непосредственно фреймом, а класс представления — его содержимым. При этом окно представления является дочерним по отношению к фрейму, т. е. размещается в его рабочей области. Сам фрейм документа может быть окном SDI-приложения или дочерним окном MDI-приложения.

<>

Взаимосвязь между фреймом, документом и представлением

Работа с основными компонентами фрейма документа осуществляется также по-разному. За взаимодействие пользователя непосредственно с фреймом (изменение размеров, перемещение и т. д.) полностью отвечает сама система Windows. Управление же содержимым фрейма, т. е. представлениями, ложится на плечи разработчика.

Для координации создания и взаимодействия трех основных объектов рассматриваемой архитектуры в библиотеке MFC используются специальные классы шаблонов документов, которые создаются и управляются объектом "приложение".

Таким образом, архитектура "документ/представление" охватывает следующие основные классы:

  • CWinApp — класс для создания единственного объекта — приложения;
  • CFrameWnd — класс для создания главного окна однодокументного приложения и базовый для классов CMDIFrameWnd и CMDIChildWnd, которые отвечают за работу многодокументного приложения;
  • CDocTemplate — базовый абстрактный класс для создания шаблонов документов; при работе с однодокументным приложением используется производный от него класс CSingleDocTemplate, а для многодокументных — класс CMultiDocTemplate,
  • CDocument — класс для создания собственно документа;
  • CView — базовый класс, который совместно со своими производными классами — CCtiiView, CEditView, CListView, CTreeView и CScrollView — отвечает за отображение данных документа и за взаимодействие с пользователем; для этих же целей можно использовать класс CSplitterWnd.

// MainFrm.h : interface of the CMainFrame class

#pragma once

 

class CMainFrame : public CFrameWnd

{

 

protected: // create from serialization only

CMainFrame();

DECLARE_DYNCREATE(CMainFrame)

 

// Attributes

public:

// Operations

public:

// Overrides

public:

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

// Implementation

public:

virtual ~CMainFrame();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

 

protected: // control bar embedded members

CStatusBar m_wndStatusBar;

CToolBar m_wndToolBar;

 

// Generated message map functions

protected:

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

DECLARE_MESSAGE_MAP()

};


// mfc2Doc.h : interface of the Cmfc2Doc class

 

#pragma once

 

class Cmfc2Doc : public CDocument

{

protected: // create from serialization only

Cmfc2Doc();

DECLARE_DYNCREATE(Cmfc2Doc)

 

// Attributes

public:

 

// Operations

public:

 

// Overrides

public:

virtual BOOL OnNewDocument();

virtual void Serialize(CArchive& ar);

 

// Implementation

public:

virtual ~Cmfc2Doc();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

 

protected:

 

// Generated message map functions

protected:

DECLARE_MESSAGE_MAP()

};

 


// mfc2View.h : interface of the Cmfc2View class

//

 

 

#pragma once

 

 

class Cmfc2View : public CView

{

protected: // create from serialization only

Cmfc2View();

DECLARE_DYNCREATE(Cmfc2View)

 

// Attributes

public:

Cmfc2Doc* GetDocument() const;

 

// Operations

public:

 

// Overrides

public:

virtual void OnDraw(CDC* pDC); // overridden to draw this view

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

protected:

 

// Implementation

public:

virtual ~Cmfc2View();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

 

protected:

 

// Generated message map functions

protected:

DECLARE_MESSAGE_MAP()

};

 

#ifndef _DEBUG // debug version in mfc2View.cpp

inline Cmfc2Doc* Cmfc2View::GetDocument() const

{ return reinterpret_cast<Cmfc2Doc*>(m_pDocument); }

#endif

 

 


// MainFrm.h : interface of the CMainFrame class

//

 

 

#pragma once

 

class CMainFrame : public CFrameWnd

{

 

protected: // create from serialization only

CMainFrame();

DECLARE_DYNCREATE(CMainFrame)

 

// Attributes

public:

 

// Operations

public:

 

// Overrides

public:

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

 

// Implementation

public:

virtual ~CMainFrame();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

 

protected: // control bar embedded members

CStatusBar m_wndStatusBar;

CToolBar m_wndToolBar;

 

// Generated message map functions

protected:

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

DECLARE_MESSAGE_MAP()

};

 

 


// MainFrm.cpp : implementation of the CMainFrame class

#include "stdafx.h"

#include "mfc2.h"

#include "MainFrm.h"

 

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

 

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

ON_WM_CREATE()

END_MESSAGE_MAP()

 

static UINT indicators[] =

{

ID_SEPARATOR, // status line indicator

ID_INDICATOR_CAPS,

ID_INDICATOR_NUM,

ID_INDICATOR_SCRL,

};

 

// CMainFrame construction/destruction

CMainFrame::CMainFrame()

{

// TODO: add member initialization code here

}

CMainFrame::~CMainFrame()

{

}

 

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CFrameWnd::OnCreate(lpCreateStruct) == -1)

return -1;

 

if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))

{

TRACE0("Failed to create toolbar\n");

return -1; // fail to create

}

if (!m_wndStatusBar.Create(this) ||

!m_wndStatusBar.SetIndicators(indicators,

sizeof(indicators)/sizeof(UINT)))

{

TRACE0("Failed to create status bar\n");

return -1; // fail to create

}

// TODO: Delete these three lines if you don't want the toolbar to be dockable

m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);

EnableDocking(CBRS_ALIGN_ANY);

DockControlBar(&m_wndToolBar);

return 0;

}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

{

if( !CFrameWnd::PreCreateWindow(cs) )

return FALSE;

// TODO: Modify the Window class or styles here by modifying

// the CREATESTRUCT cs

 

return TRUE;

}


// mfc2Doc.cpp : implementation of the Cmfc2Doc class

//

 

#include "stdafx.h"

#include "mfc2.h"

 

#include "mfc2Doc.h"

// Cmfc2Doc

 

IMPLEMENT_DYNCREATE(Cmfc2Doc, CDocument)

 

BEGIN_MESSAGE_MAP(Cmfc2Doc, CDocument)

END_MESSAGE_MAP()

 

// Cmfc2Doc construction/destruction

Cmfc2Doc::Cmfc2Doc()

{

// TODO: add one-time construction code here

}

 

Cmfc2Doc::~Cmfc2Doc()

{

}

 

BOOL Cmfc2Doc::OnNewDocument()

{

if (!CDocument::OnNewDocument())

return FALSE;

 

// TODO: add reinitialization code here

// (SDI documents will reuse this document)

 

return TRUE;

}

// Cmfc2Doc serialization

void Cmfc2Doc::Serialize(CArchive& ar)

{

if (ar.IsStoring())

{ // TODO: add storing code here

}

else

{ // TODO: add loading code here

}

}


// mfc2View.cpp : implementation of the Cmfc2View class

//

 

#include "stdafx.h"

#include "mfc2.h"

 

#include "mfc2Doc.h"

#include "mfc2View.h"

 

IMPLEMENT_DYNCREATE(Cmfc2View, CView)

 

BEGIN_MESSAGE_MAP(Cmfc2View, CView)

END_MESSAGE_MAP()

 

// Cmfc2View construction/destruction

 

Cmfc2View::Cmfc2View()

{// TODO: add construction code here

}

 

Cmfc2View::~Cmfc2View()

{ }

 

BOOL Cmfc2View::PreCreateWindow(CREATESTRUCT& cs)

{

// TODO: Modify the Window class or styles here by modifying

// the CREATESTRUCT cs

return CView::PreCreateWindow(cs);

}

// Cmfc2View drawing

void Cmfc2View::OnDraw(CDC* /*pDC*/)

{

Cmfc2Doc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

if (!pDoc)

return;

 

// TODO: add draw code for native data here

}

 


// mfc2.cpp : Defines the class behaviors for the application.

#include "stdafx.h"

#include "mfc2.h"

#include "MainFrm.h"

#include "mfc2Doc.h"

#include "mfc2View.h"

// Cmfc2App

BEGIN_MESSAGE_MAP(Cmfc2App, CWinApp)

ON_COMMAND(ID_APP_ABOUT, &Cmfc2App::OnAppAbout)

// Standard file based document commands

ON_COMMAND(ID_FILE_NEW, &CWinApp::OnFileNew)

ON_COMMAND(ID_FILE_OPEN, &CWinApp::OnFileOpen)

END_MESSAGE_MAP()

 

// Cmfc2App construction

Cmfc2App::Cmfc2App()

{ // TODO: add construction code here,

}

// The one and only Cmfc2App object

Cmfc2App theApp;

 

BOOL Cmfc2App::InitInstance()

{

CWinApp::InitInstance();

 

SetRegistryKey(_T("Local AppWizard-Generated Applications"));

LoadStdProfileSettings(4); // Load standard INI file options (including MRU)

// Register the application's document templates. Document templates

// serve as the connection between documents, frame windows and views

CSingleDocTemplate* pDocTemplate;

pDocTemplate = new CSingleDocTemplate(

IDR_MAINFRAME,

RUNTIME_CLASS(Cmfc2Doc),

RUNTIME_CLASS(CMainFrame), // main SDI frame window

RUNTIME_CLASS(Cmfc2View));

if (!pDocTemplate)

return FALSE;

AddDocTemplate(pDocTemplate);

 

// Enable DDE Execute open

EnableShellOpen();

RegisterShellFileTypes(TRUE);

 

// Parse command line for standard shell commands, DDE, file open

CCommandLineInfo cmdInfo;

ParseCommandLine(cmdInfo);

 

// Dispatch commands specified on the command line. Will return FALSE if

// app was launched with /RegServer, /Register, /Unregserver or /Unregister.

if (!ProcessShellCommand(cmdInfo))

return FALSE;

 

// The one and only window has been initialized, so show and update it

m_pMainWnd->ShowWindow(SW_SHOW);

m_pMainWnd->UpdateWindow();

// call DragAcceptFiles only if there's a suffix

// In an SDI app, this should occur after ProcessShellCommand

// Enable drag/drop open

m_pMainWnd->DragAcceptFiles();

return TRUE;

}

 

// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog

{

public:

CAboutDlg();

// Dialog Data

enum { IDD = IDD_ABOUTBOX };

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

// Implementation

protected:

DECLARE_MESSAGE_MAP()

};

 

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

}

 

void CAboutDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

}

 

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

END_MESSAGE_MAP()

 

// App command to run the dialog

void Cmfc2App::OnAppAbout()

{

CAboutDlg aboutDlg;

aboutDlg.DoModal();

}

 


Интерфейс многодокументного приложения:

 

Приложение может поддерживать произвольное число типов документов. Единственное, что для этого нужно сделать — это создать и "зарегистрировать" во время инициализации объекта-приложения (при выполнении функции Initlnstance) необходимое число шаблонов документов. Причем для каждого типа документа, с которым предполагается работа, используется свой шаблон. Например, если приложение поддерживает документы двух разных типов — табличные и текстовые, то оно должно создать для них два разных шаблона.

В библиотеке классов MFC для работы с шаблонами документов реализованы специальный класс — CDocTemplate и два производных от него — CSingleDocTemplate и CMultiDocTemplate. Рассмотрим возможности, которые в них заложены.

Создание различных типов документов

Базовым классом для создания шаблонов является CDocTemplate. Это абстрактный класс, в котором реализованы основные функциональные возможности для работы с шаблонами документов — организация и управление взаимодействием между классами трех типов:

  • Классом документа, образованного из CDocument.
  • Классом представления, который изображает данные документа. Можно создать этот класс на базе CView, CScrollView, CFormView, CEditView и т. д. (CEditView используется непосредственно для текстовых документов).
  • Классом фрейма, который содержит представление. Для SDI-приложе-ний он создается на основе CFrameWnd, а для MDI-приложений — на базе CMDIChildWnd. Базовые классы можно использовать и непосредственно.

Место классов для создания шаблонов документов в иерархии библиотеки MFC

Рассмотрим основные компоненты класса CDocTemplate. Начнем, как обычно, с конструктора, который фиксирует типы документа, фрейма и представления, доступные для работы с данным шаблоном.

CDocTemplate::CDocTemplate (

UINT nIDResource,

CRuntimeClass *pDocClass,

CRuntimeClass *pFrameClass,

CRuntimeClass *pViewClass)

Создает объект класса. В качестве аргументов используются: nIDResource — идентификатор ресурсов (меню, командные клавиши и строка описания типа шаблона документа), используемых с этим типом документов; pDocClass— указатель на объект CRuntimeClass, отвечающий за данные документа; pFrameClass — указатель на объект CRuntimeClass, характеризующий фрейм документа; pViewClass— указатель на объект CRuntimeClass, отвечающий за представление документа. Эти объекты должны быть уже определены к моменту создания объекта "шаблон документа". Память под этот объект следует распределять динамически, а полученный указатель передать в качестве параметра в функцию CWinApp::AddDocTemplate.

virtual void CDocTemplate::AddDocument (CDocument *pDoc),

virtual void CDocTemplater:RemoveDocument (CDocument *pDoc)

Добавляет (удаляет) документ, на который указывает pDoc, в список документов, ассоциированных с этим шаблоном. В производных классах CSingleDocTemplate и CMultiDocTemplate эти функции переопределены.

virtual void CDocTemplate::LoadTemplate ()

Загружает ресурсы для данного шаблона документа. Обычно вызывается библиотекой MFC во время создания объекта и практически не требует прямого вызова. Исключение составляет случай, когда объект класса создается на глобальном уровне. В этом случае во время выполнения функции CWinApp:: AddDocTemplate необходим явный вызов LoadTemplate.

Ресурсами, используемыми документами этого типа, могут быть меню, командные клавиши и единственный строковый ресурс. Рассмотрим более подробно структуру строки описания типа.

// Строка описания типа шаблона документа

STRINGTABLE PRELOAD

DISCARDABLE BEGIN

IDR_NOTETYPE "\nNotenNotenNote Files (*.tnd)\n.tnd\nNote.Document\nNote Document"

END

Как видите, строка состоит из семи подстрок (первая — пустая), разделенных символом "n", которые содержат дополнительную информацию о типе документа:

  • Заголовок главного окна SDI-приложения (Main frame caption). He используется для MDI-приложений (обратите внимание, что в приведенном примере это поле отсутствует).
  • Имя файла, присваиваемое новому документу по умолчанию (Doc type name) — Note. Если эта подстрока отсутствует, то используется имя Unfitted или его аналог для локализованных версий Windows (Без Имени — для русской версии).
  • Имя типа документа (File new name (OLE short name)) — Note. Если в приложении определено больше одного шаблона, то при создании нового документа на экране отображается блок диалога для выбора типа создаваемого документа.
  • Описание типа документа и его фильтра (Filter name) — Note Files (*.tnd). Эта строка отображается в списке типов документов стандартных блоков диалога Open (Открыть) и Save As (Сохранить как).
  • Расширение, используемое для документов этого типа (File extension) — .tnd.
  • Идентификатор типа документа, хранящийся в реестре Windows (File type ID), — Note.Document.
  • Имя типа документа, хранящееся в реестре Windows (File new name (OLE long name)), — Note Document. Это же имя используется в качестве длинного имени объекта OLE, если в приложение включена соответствующая поддержка.

Примечание

В скобках указаны названия соответствующих полей диалога Advanced Options (Дополнительные параметры) мастера создания каркаса приложения AppWizard.

Если какая-либо из этих подстрок не включается в строку, то вместо нее обязательно используется разделяющий символ "n". Заключительный символ "n" в строке является необязательным.

Доступ к этой информации осуществляется с помощью функции

virtual BOOL CDocTemplate::GetDocString (

CStringS rString,

enum DocStringlndex index)

Позволяет получить определенную подстроку, описывающую тип документа, которая хранится в шаблоне и получена из соответствующей строки файла ресурсов приложения. Найденная подстрока записывается в rString. Параметр index определяет индекс подстроки, информацию о котором необходимо получить. Он может принимать одно из следующих значений:

CDocTemplate::windowTitle

Имя, отображаемое в заголовке главного окна приложения; представлено только в шаблоне документа для SDI-приложений

CDocTemplate::docName

Основа имени документа; имя нового документа этого типа складывается из основы, к которой добавляется число; если значение не определено, то по умолчанию используется Untitled (для русской версии Windows — Без Имени)

CDocTemplate::fileNewName

Имя типа документа; если значение не определено, то этот тип документа недоступен при выполнении команды FileNew (ФайлСоздать)

CDocTemplate::filterNewName

Описание типа документа и нейтрального символа для фильтра, сопоставляемого с документами этого типа. Данная строка изображается в списке типов файлов в блоке диалога File Open (Открытие файла); если значение не определено, то этот тип документа недоступен при выполнении команды FileOpen (Файл/Открыть)

CDocTemplate::filterExt

Расширение документов этого типа; еслизначение не определено, то данный тип документа недоступен при выполнении команды FileOpen (Файл/Открыть)

CDocTemplate::regFileTypeld

Идентификатор типа документа, хранящийся в реестре Windows. Эта строка предназначена только для внутреннего использования; если не определена, то тип документа не может быть зарегистрирован в File Manager (Диспечер файлов)

CDocTemplate::regFileTypeName

Имя типа документа, хранящегося в регистрационной базе данных; эта строка может быть отображена в блоках диалога приложения, вызываемых для доступа к регистрационной базе данных

Кроме того, в классе CDocTemptate объявлены еще четыре "чистые" функции: GetFirstDocPosition, GetNextDoc, OpenFileName и SetDefaultTitle. Наличие этих функций превращает CDocTemplate в абстрактный класс и, следовательно, его нельзя использовать непосредственно. Обычно приложения используют один из двух производных от него классов, предоставляемых библиотекой MFC: CSingleDocTemplate — для SDI- и CMultiDocTemplate — для MDI-приложений.

Примечание

Если по каким-либо причинам может потребоваться интерфейс, который фундаментально отличается от SDI и MDI, то можно образовать свой класс непосредственно из CDocTemplate.

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

Если шаблон поддерживает несколько типов файлов, то, используя функцию MatchDocType для каждого шаблона, можно определить, какие шаблоны документов подходят для данного файла, и выбрать тот, который нужен:

virtual Confidence CDocTemplate::MatchDocType (

LPCTSTR IpszPathName,

CDocument *&rpDocMatch)

Служит для определения типа шаблона документа, используемого для открытия файла. Параметры: IpszPathName — полное имя файла; rpDocMatch — указатель на уже открытый документ, если файл, определенный в IpszPathName, открыт. Функция возвращает значение, определенное в перечислении Confidence:

enum Confidence {

noAttempt,

maybeAttemptForeign,

maybeAttemptNative,

yesbeAttemptForeign,

yesbeAttemptNative,

yesAlreadyOpen

};

Если файл, определенный в параметре IpszPathName, уже открыт, то функция возвращает CDocTemplate::yesAlreadyOpen и копирует объект CDocument файла в объект rpDocMatch. Если файл еще не открыт, но расширение имени в IpszPathName совпадает со значением, определенным в CDocTemplate::filterExt, то функция возвращает CDocTemplate::yesAttemptNative и устанавливает rpDocMatch в NULL. В остальных случаях функция возвращает значение CDocTemplate:: yesAttemptForeign. Другие члены перечисления можно использовать при переопределении этой функции.

virtual CDocument* CDocTemplate::CreateNewDocument ()

Создает новый документ, тип которого определяется текущим шаблоном. Функция возвращает указатель на вновь созданный документ или NULL в случае ошибки.

CDocTemplate — абстрактный класс, и на его основе объекты шаблонов не создаются. Его основная роль заключается в обеспечении шаблонов основными свойствами, а для создания конкретных объектов в библиотеке MFC реализованы два другие класса — СSingleDoTemplate и CMultiDocTemplate, которые специально адаптированы для работы соответственно в SDI- и MDI-приложениях.

Шаблоны однодокументных приложений

Для создания шаблона однодокументного интерфейса в библиотеке MFC реализован класс СSingleDocTemplate. Как вы помните, в SDI-приложениях главный фрейм является одновременно и фреймом документа, другими cловами — в каждый конкретный момент времени может быть открыт только один документ. Обычно SDI-приложения поддерживают один тип документа (хотя это и не является обязательным условием), т. е. они содержат только один объект класса CSingleDocTemplate.

Объекты этого класса обрабатываются внутри библиотеки MFC. В своей защищенной части класс содержит член, в котором хранится указатель на документ, присоединенный к шаблону:

class CSingleDocTemplate : public CDocTemplate

{

...

protected:

CDocument *m_pOnlyDoc;

...

}

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

virtual POSITION CDocTemplate::GetFirstDocPosition () .

Возвращает позицию первого документа из списка документов, ассоциированных с данным шаблоном, или NULL, если список пуст. Она переопределена в обоих производных классах— CSingleDocTemplate и CMultiDocTemplate. Если возникло желание создать свой класс на базе CDocTemplate, то эту функцию следует в нем переопределить.

virtual CDocument* CDocTemplate::GetNextDoc (POSITION SrPos)

Возвращает указатель на объект-документ из общего списка документов, ассоциированных с шаблоном, который хранится непосредственно за документом, заданным его позицией в списке (параметр rPos). Позиция полученного документа записывается в rPos. Если возвращен указатель на последний элемент списка, то в параметр rPos функция записывает NULL. Для получения указателя на первый документ списка необходимо вызвать эту функцию до GetFirstDocPosition. При использовании в качестве параметра rPos недопустимого значения библиотека MFC генерирует исключение.

virtual CDocument* CDocTemplate::OpenDocumentFile (

LPCTSTR IpszPathName,

BOOL bMakeVisible = TRUE)

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

virtual void CDocTemplate;.:SetDefaultTitle (CDocument *pDoc)

Загружает заголовок документа, используемый по умолчанию и определенный в строке ресурса, и выводит его в полосу заголовка фрейма документа.

Кроме перечисленных "чистых" функций, в классе переопределены также функции базового класса AddDocument и RemoveDocument.



Дата добавления: 2017-01-26; просмотров: 2213;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.099 сек.