ДОКУМЕНТЫ И ОТОБРАЖЕНИЯ C++

Работа добавлена: 2018-06-01






6

ДОКУМЕНТЫ И ОТОБРАЖЕНИЯ

Для реализацииSDI иMDI приложений вVisual C++ используется ме-;анизм документ-отображение. Это позволяет отображать один документ шличными способами.

Основные возможности внутреннего представления документа реализу-отся классомCDocument.Как правило, для открытия и сохранения документа используются командыOpen иSave менюFile.

Основные возможности отображения содержания документа, а также шзбражения любой графической информации реализуются классомCView.Объекты этого класса мы будем называть отображениями.

Одному документу может быть сопоставлено несколько различных объ-:ктов отображения.

Будем говорить, что отображение пристыковывается или сопоставляется (окументу. Отображение представляет вид документа на экране и является «которой средой, взаимосвязывающей документ и пользователя. Объект отображение воспроизводит вид документа на экране и интерпретирует (ействия пользователя как операции над документом.

В свою очередь, объект отображение также привязан к объекту окну-эамке. На рис. 6.1 изображена взаимосвязь объектов документ->отображе--ше- >окно-рамка.

Рис. 6.1. Взаимосвязь объектов документ->отображение->окно-рамка

Объект отображение используется не только для представления документов на экране. Этот объект представляет документ как для печати, так и для предварительного просмотра печатаемого документа.

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

Операции по изменению данных реализуются классами документа. Объект отображение только вызывает этот интерфейс для доступа и обновления данных.

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

Visual C++ поддерживает реализацию командNew иOpen менюFile. Создание нового документа и сопоставленного ему отображения и окна-рамки выполняется различными объектами: объектом приложение, шаблоном документа, созданным документом и созданным окном-рамкой. Следующая таблица иллюстрирует, какими объектами создаются шаблон документа, документ, окно-рамка и отображение.

Создающий объект

Создаваемый объект

Приложение(Application object)

Шаблон документа

Шаблон документа(Document template)

Документ

Шаблон документа(Document template)

Окно-рамка

Окно-рамка(Frame window)

Отображение(View)

Использование документов и отображений

Управление данными

Для реализации управления данными документа первоначально следует выполнить такие действия:

1.                                    Объявить производный класс отCDocumentдля каждого типа документов;

2.                               Добавить переменные класса для хранения данных;

3.                                    Переопределить в производном классе документа методSerializeклассаCDocument.МетодSerializeреализует чтение и запись данных документа с диска;

4.                                   Если необходимо, можно дополнительно переопределить другие методыбазового  класса,  такие,  какOnNewDocument,OnOpenDocumentиDeleteContents.

Переменные класса для хранения данных документа

Данные документа хранятся в переменных класса. Конкретная реализация хранения данных зависит от создаваемого приложения. БиблиотекаMFC содержит ряд классов, инкапсулирующих работу с различными наборами данных. Это такие классы, какCString,CRect,CPoint,CSize,dime,CObList,CByteArray,CStringlist,CMapWordToPrtи др.

Для выполнения операций над элементами данных в класс документаi можно добавлять требуемые методы.

При создании объекта отображение формируется указатель на документ,] используемый отображением для доступа к объекту документ (его методам и переменным). Этот указатель может быть получен объектом отображения вызовом методаGetDocumentклассаCView.

Отметим, что если необходимо реализовать прямой доступ к данным или использовать члены класса документа, не имеющие модификаторадосЯтупаpublic, то следует реализовать класс отображения как дружественный (friend) классу документа.

Классы отображений

Для вывода данных на различные графические устройства используются

клабсы отображений. Базовым классом всех таких классов являетсяCView.БиблиотекаMFC предоставляет следующий набор производных классов

от класса отображенияCView:

CScroUView- для автоматической прокрутки и масштабирования отображения;

CFormView- для отображения форм, содержащих элементы управления. ОбъектCFormView создается из ресурса диалога-шаблона (dialog-template);

CRecordViewиCDaoRecordView- для отображения форм, содержащих эле-jl менты управления, связанные с полями объектаCRecordset илиCDaoRecordset, отображающими таблицы баз данных;

CCtrlView- базовый класс для классовCEditView,CTreeView,CListView,

CEditView иCRichEditView. Эти классы позволяют использовать ар- | хитектуру документ/отображение для некоторых элементов управленияWindows;

CEditView- для отображения, реализующего свойства окна редактирования. Объект классаCEditView реализует работу простого текстового редактора.

CListView- для отображения, содержащего объектCListCtrl;

CRichEditView- для отображения, содержащего объектCRichEditCtrl. Этотj класс отображения реализует свойства окна редактирования и позво-j ляет управлять форматированием текста;

CTreeView- для отображения, содержащего объектCTreeCtrl.

Реализация графического вывода данных через классы отображений

Объект классаCViewпредставляет собой прямоугольную область экрана, в которую производится вывод данных в графическом режиме. При перемещении окна или при временном перекрытии его другим окном необходимо восстановить на экране содержимое, расположенное в области объектаCView.Для того чтобы перерисовать окно (когда область отображения становится недостоверной),Windows посылает приложению, владеющему этим окном, сообщениеWM_PAINT.МетодOnPaintкласса отображения создает контекст устройства классаCPaintDCи вызывает методOnDrawпроизводного класса отображения, передавая ему в качестве параметра контекст устройства. Следовательно, для того чтобы при перемещении и перекрытии окон не возникало ошибок визуального отображения содержимого окна, программист должен переопределить методOnDrawклассаCView,обрабатывающий соответствующее сообщение. Дополнительно могут быть переопределены такие методы классаCView,какOnlnitialUpdate,OnUpdate,OnPreparePrinting.

Пример:

voidCMyView::OnDraw(CDC*pDC )         // Переопределение методаOnDraw

(

CMyDoc*pDoc =GetDocumentO;

CStringstrl =pDoc->GetData(); - // МетодGetData следует определитьCRectrect;

GetClientRect( &rect);

pDC->SetTextAIign( TA_BASELINE | TA_CENTER ); pDC->TextOnt( 2, 2, strl, strl.GetLength()); //Выводстроки }

Реализация интерфейса пользователя через классы отображений

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

•                                             обработку сообщенийWindows от мыши и от клавиатуры;

•                                            обработку выполнения пунктов меню, нажатия кнопок инструментария и клавиш-акселераторов.

Реализация интерфейса пользователя может включать в себя обработку некоторых стандартных пунктов меню, таких, какEdit |Copy,Edit |Cut иEdit|Paste. Для работы с буфером промежуточного хранения следует использовать соответствующие методы классаCWnd.

MFC поддерживает реализацию трех типов интерфейса для отображения! одного документа посредством нескольких отображений: •   Отображение объектов одного класса: каждый в отдельном окне документа (поддержка командыWindowINew):

• Отображение объектов одного класса в одном разделенном окне доку-J мента (поддержка командыWindow |Split). Создается несколько объектов отображения одного класса:

•   Отображение объектов различных классов в одном окне документа:

Поддержка работы с разделенным окном реализована в классеCSplitterWnd. Разделенным окном является обычное окно, разбитое на не-| сколько панелей (окон) и содержащее один и тот же документ.

Цикл жизни документа (а совместно с ним и окна-рамки и отображения) вMDI-приложении состоит из следующих этапов:

1.                                   Вызов конструктора документа.

2.                                Для каждого нового документа вызов методаOnNewDocument илиOnOpenDocument.

3.                                   Отображение и обработка документа.

4.                                   Удаление данных вызовом методаDeleteContents.

5.                                    Вызов деструктора документа.

Цикл жизни документа (а совместно с ним и окна-рамки и отображения) вSDI-приложении отличается тем, что вызов конструктора происходит только один раз при первоначальном создании документа; аналогичен и вызов деструктора. А для каждого нового (но не первоначально) создаваемого или открываемого документа выполняются только этапы 2, 3 и 4.

Для использования архитектуры документ-отображение при создании приложения следует: •   создать ресурсы, описываемые в шаблоне документа; •   создать объект приложение (класса, производного отCWinApp); •  создать: •   объекты документы, •   объекты отображения, •   объекты окна-рамки; •  в методеInitlnstance класса приложения создать и зарегистрировать объекты шаблона документа (методыCSingleDocTemplate,CMultiDocTemplate,AddDocTemplate); •   создать   и   отобразить   главное   окно   приложения   (классCFrameWnd, методыLoadFrame,ShowWindow,UpdateWindow).

Более подробно вопросы создания приложений сSDI иMDI интерфейсом будут рассмотрены в гл. 7.

КлассCview

КлассCView реализует основные возможности для работы с отображениями. Отображения пристыковываются к документу и реализуют интерфейс между документом и пользователем: объект отображение выводит документ на экран или на принтер и интерпретирует действия пользователя как операции над документом.

Отношения между классом отображения, классом окна-рамки и классом Документа устанавливаются объектомCDocTemplate. Вызов конструктора нового отображения и сопоставление его документу выполняются при открытии пользователем нового окна и разделении существующего окна.

Один объект отображение может быть сопоставлен только одному документу, однако один документ может иметь несколько сопоставленных ему отображений.

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

сохранение. Документ предоставляет отображению необходимую информаЗ

цию о данных посредством вызова объектом отображение методов доку|

мента.

Для внесения изменений в данные отображение, как правило, вызывает

методCDocument::UpdateAHViews,  который инициирует вызов методо!

OnUpdateдля всех других отображений. По умолчанию реализация метод!

OnUpdate определяет всю клиентскую область как недостоверную. Этот ме|

тод может быть переопределен.

►Длятого чтобы использовать класс отображенийCview,следует:

1.                                   Объявить производный класс отCview;

2.                                   Реализовать методOnDraw,выполняющий отображение экрана или вы| вод на печать.

Для обработки сообщений от линейки прокрутки можно использовать:I

методы CWnd::OnHScrollи CWnd::OnVScroll;

•                                              классCScrollView.

Члены класса СView

CView();

Конструктор объектаCView.Конструктор вызывается при создании нового окна-рамки или разделении существующего окна. Для инициализаций отображения сопоставленного документу следует вызвать методOnlnitialUpdate.

BOOLDoPreparePrinting(CPrintlnfo*plnfo);

Этот метод вызывается из переопределяемого методаOnPreparePrintingдля отображения диалогового окнаPrint и создания контекста устройства! принтера.

CDocument*GetDocument()const;

Метод возвращает указатель на объект документ сопоставленный данному отображению, илиNULL,если отображение не пристыковано ни к какому документу.

Этот указатель можно использовать для вызова методов класса документа.virtualvoidOnInitiaIUpdate();

Метод вызывается сразу после сопоставления отображения документу, но до первого вывода отображения. По умолчанию реализация этого метода] вызывает методOnUpdateс нулевыми значениями параметров(lHint=0,\ рНШ=NULL).Для выполнения собственных действий при инициализаций! документа следует переопределить этот метод.

virtual BOOL CView::OnScroll( UINTnScrollCode,UINTnPos,BOOLbDoScroll=TRUE);

Метод вызывается с параметромbDoScroll=TRUEв том случае, если отображение получает сообщение от линейки прокрутки. Программист должен переопределить этот метод, описав необходимые действия.

Параметры:

nScrollCode- код линейки прокрутки, состоящий их двух частей: в младшем байте указывается, как выполнять прокрутку по горизонтали, в старшем байте - по вертикали. Код линейки прокрутки как по горизонтали, так и по вертикали может указываться следующими значениями:SB_BOTTOM,SB_LINEDOWN,SBJLINEUP,SB_PAGEDOWN,SB_PAGEUP,SBJTHUMBTRACK,SB_TOP.

nPos -указывает значение текущей позиции для прокрутки, определяемой значениемSBJTHUMBTRACK.

bDoScroll -при значенииTRUEпрокрутку отображения следует выполнить, при значенииFALSE- прокрутка не выполняется.virtualvoidOnActivateView(BOOLbActivate,CView*pActivateView,CView*pDeactiveView);

Метод вызывается при активизации или деактивизации отображения. По умолчанию реализация этой функции состоит в установке фокуса на активизируемое отображение.

Параметры:

bActivate -указывает, активизируется или деактивизируется отображение.pActivateView- активизируемый объект отображение.pDeactiveView -деактивизируемый объект отображение.virtualvoidOnActivateFrame(UINTnState,CFrameWnd*pFrameWnd);

Метод вызывается при активизации или деактивизации окна-рамки, содержащего отображение.

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

Параметры:

nState -указывает на активизацию или деактивизацию окна-рамки и определяется одним из следующих значений:WA_INACTIVE- окно деактивизируется;

WA_ACTIVE- окно активизируется любым способом, кроме щелчка мыши;WA_CLICKACTTVE- окно активизируется по щелчку мыши.PFrameWnd-указатель на активизируемое окно.

virtual void OnDraw( CDC*pDC) =0;

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

Параметры:

pDC- указатель на контекст устройства, используемый для перерисонки изображения.

Для того чтобы определить перерисовываемую область, можно вызвать методRectVisibleконтекста устройства. МетодIsPrinting контекста устройства определяет направление вывода: на экран или на принтер.virtualvoidOnUpdate(CView*pSender,LPARAMIHint,CObject*pHint);

Вызов этого метода инициируется при изменении отображения документа. Этот метод вызывается методомCDocuraent::UpdateAllViews и методомOnlnitialUpdate.По умолчанию реализация этого метода отмечает всю клиентскую область как недостоверную и инициирует сообщениеWM_PAINT.

Параметры:

pSender- указатель на отображение.

IHint- содержит информацию об изменениях.

pHint- указатель на объект, хранящий информацию об изменениях.

КлассCformView

КлассCFormViewявляется базовым классом, используемым для отображений, содержащих элементы управления. Он поддерживает работу с оконными формами и с их прокруткой (используя возможности классаCScroIlView).

Создание отображенияCFormViewаналогично созданию диалогового окна. ■ Для того чтобы использовать отображениеCFormView,следует выполнить,-некоторые действия: 1. Разработать в редакторе диалога шаблон диалогового окна и установить

для него следующие атрибуты:

•                                              на панелиStyle выбратьChild(WS_CHILDвкл.);

•                                              на панелиBorder выбратьNone(WS_BORDERоткл.);

•                                              снять флажокVisible(WSJVISIBLEоткл.);

снятьфлажок Titlebar(WS_CAPTIONоткл.).

2.                                   Создать класс отображения. Для этого, находясь в редакторе ресурсов с открытым шаблоном диалогового окна, следует вызватьClassWizard и, щелкнув на командной кнопкеAddClass, выбрать в качестве классаCFormView.ClassWizard создаст производный отCFormViewкласс и сопоставит ему разрабатываемый шаблон диалогового окна.

3.                                  Переопределить методOnUpdate.

Этот метод определен в классеCViewи вызывается для обновления отображения окна формы1. При использованииDDX-методов можно вызвать методCWnd::UpdateData(FALSE)для обновления элементов управления, расположенных в окне формы. МетодOnlnitialUpdateвызывается при первичной инициализации отображения. В классеCFormViewэтот метод переопределен таким образом, что он выполняет вызовDDX-методов, устанавливающих первоначальное значение элементов управления.

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

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

5.                                   При необходимости переопределить методOnPrint.

По умолчанию классCFormViewне поддерживает функции печати документа и предварительного просмотра.

6.                                  Сопоставьте класс отображения с классом документа и окном-рамкой, используя шаблон документа.

Отметим, что для использования отображения окна формы можно не переопределять методCView::OnDraw.

Если окно формы содержит такие элементы управления, какCSliderCtrlилиCSpinButtonCtrl,то в обработчиках сообщений окна для сообщенийWMJHSCROLLиWM_VSCROLLдолжны быть переключатели вызовов в зависимости от типа объекта, инициировавшего сообщение.

Пример:

void CMyFormView::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)

{ if ( pScrollBar->IsKindOf( RUNTIME_CLASS( CScrollBar ))) { CFormView::OnHScroll( nSBCode, nPos, pScrollBar); - -} else if ( pScrollBar->IsKindOf( RUNTIME_CLASS( CSliderCtrl))) { CWnd::OnHScroll( nSBCode, nPos, pScrollBar );    } else if ( pScrollBar->IsKindOf( RUNTIME_CLASS( CSpinButtonCtrl))) { CWnd::OnHScroll( nSBCode, nPos, pScrollBar ); } }

Отображение для окна формы поддерживает работу в логической систе-1ме координат только в режиме МММГЕХТ.

Классы шаблонов документов

КлассCdocTemplate

КлассCDocTemplateявляется абстрактным классом, предоставляющим основные возможности для работы с шаблонами документов. Как правило,шаблоныдокумента создаются и регистрируются во время инициализации объекта приложения (в переопределяемом методе инициализацииCWinApp::InitInstance для производного класса приложения).

Шаблон документа определяет отношение между тремя типами классов:

классом документа,наследуемым отCdocument;

классом отображения,выполняющим показ данных для указанного класса документа. Класс отображения может быть наследован от классовCView,CScrollView,CFormView,CEditView (классCEditView может быть использован и напрямую);

классом окна-рамки,содержащим отображение. ДляSDI-приложений этот класс наследуется от базового классаCFrameWnd, а дляMDI-приложений - от базового классаCMDIChildWnd. Однако если в приложении не требуется переопределять поведение объекта окно-рамка, то может быть создан объект окно-рамка непосредственно базового класса, без объявления производных классов.

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

Шаблон документа содержит следующую информацию: .  Указатели на три объекта классаCRuntimeClassдля объектов документа, отображения и окна-рамки, которые должны быть созданы перед созданием шаблона. Эти объекты классаCRuntimeClass указываются при создании шаблона документа.

ID ресурсов, используемых для каждого типа документа (например, ресурсы меню, пиктограммы, таблицы акселераторов).

•                                               Информационную строку, содержащую дополнительные данные о типе документа, включая имя типа документа (например,Document), расширение имени файла, а также некоторые другие данные, которые могут быть использованы для поддержкиOLE, для реализации некоторого интерфейса пользователя, для стандартных средств управления файламиWindows. Если приложение являетсяOLE-контейнером и/или сервером, то шаблон документа также определяетID ресурса меню, используемого при редактированииOLE-объекта на месте. ДляOLE-сервера может быть определено иID ресурса инструментальной панели. Эти дополнительныеOLE ресурсы устанавливаются вызовом методовSetContainerlnfoилиSetServerlnfo.

КлассCDocTemplate является абстрактным классом, а следовательно, не может использоваться непосредственно для создания объектов. Обычно для создания шаблонов используются его производные классыCSingleDocTemplateиCMuItiDocTemplate.Однако можно создать и свой собственный производный класс шаблона документа.

Членыкласса

CDocTemplate (UINTnIDResource,CRuntimeClass*pDocClass,CRuntimeClass*pFrameClass,CRuntimeClass*pViewClass);КонструкторобъектаCDocTemplate.

Параметры:

nIDResource- указываетID ресурсов, используемых для данного типа документа. Это - меню, пиктограмма, таблица акселераторов, информационная строка.

Информационная строка состоит из семи подстрок, разделенных символом \п.

Пример:

IIMYCALC.RCSTRINGTABLEPRELOADDISCARDABLEBEGIN            // Строка, содержащая 7 подстрок (первая подстрока пустая)IDR_SHEETTYPE"\nSheet\nWorksheet\nWorksheets (*.myc)\n.myc\nMyCalcSheet\nMyCalcWorksheet"END

pDocClass  -указатель   на   объектCRuntimeClass   класса  документа.pFrameClass- указатель на объектCRuntimeClass класса окна-рамки.pViewClass -указатель на объектCRuntimeClass класса отображения.

Этот метод следует использовать для динамического выделения памяти для объекта. Указатель на созданный объект следует использовать при вызове методаCWinApp::AddDocTemplate.

Пример:

CSingleDocTemplate* pDocTemplate; pDocTempIate=new CSingleDocTemplate(IDR MAINFRAME, RUNTIME_CLASS(CAppDoc_Derived), RUNTIME CLASS(CMainFrame), RUNTIME_CLASS(CAppView_Derived)); 1 AddDocTemplate (pDocTemplate);

void SetContainerInfo( UINTnIDOlelnPlaceContainer);

Этотметодпозволяетзадатьидентификатор (ID)ресурсов,используемыхдлявстраиваемых OLE-объектов.Как правило, этот метод вызывается в методе инициализацииCWinApp::InitInstance.

void SetServerInfo( UINTnIDOleEmbedding,UINTnIDOlelnPlaceServer= 0,CRuntimeClass*pOleFrameClass=NULL, CRuntimeClass*pOleViewClass =NULL);

Этот метод позволяет задать идентификатор (ID) ресурсов, используемых приложением-сервером при активизацииOLE-объектов.

virtual void AddDocument( CDocument*pDoc);virtual void RemoveDocument( CDocument*pDoc);

Эти методы позволяют добавить/удалить указанный параметромpDocдокумент к данному шаблону документа. С одним шаблоном документа может быть ассоциирован список документов. Переход между элементами списка может выполняться циклически по позиции документа в списке. В классахCMultiDocTemplate иCSingleDocTemplate эти методы переопределены.

virtualvoidLoadTemplate();

Метод вызывается средой выполнения для загрузки ресурсов шаблона документов.

virtualPOSITIONGetFirstDocPosition( )const=0;

Этот метод может использоваться для получения позиции первого документа из списка документов, ассоциированных с шаблоном документа. Метод возвращает значениеPOSITION илиNULL, если список пуст.

Для получения указателя на следующий документ списка следует использовать методCDocTemplate::GetNextDoc со значением параметраPOSITION, возвращаемого данным методом.

Это "чистый" метод, и следовательно, он обязательно должен быть переопределен в производном классе.virtualCDocument*GetNextDoc(POSITION&rPos)const=0;

Метод возвращает указатель на следующий документ списка документов, ассоциированных с данным шаблоном документа, а затем устанавливает значениеrPosна следующий элемент списка. Если возвращаемый элемент последний в списке, то новое значение параметраrPosустанавливается равнымNULL.

virtual BOOL GetDocString(CString&rString,enum DocStringlndexindex) const;

Этот метод позволяет получить указанную подстроку, описывающую тип документа.Параметры:

rString- ссылка на объектCString, в который будет занесена найденная подстрока.

index- индекс искомый подстроки. Он может быть указан одним из следующих значений:

CDocTemplate::windowTitle - заголовок главного окна приложения (напримерMicrosoftWord). Только дляSDI-приложений;CDocTemplate::docName- имя документа по умолчанию (например,Document). Действительное имя документа формируется из указанного имени плюс порядковый номер документа. Если имя документа не указано, то по умолчанию используется значениеUntitled.CDocTemplate::fileNewName- имя типа данного документа. Для приложений, поддерживающих более одного типа документов, эта строка отображается при создании файла (например, в диалоге, вызываемом выполнением пункта менюFile |New). Если значение этой строки не определено, то данный тип недоступен из менюFile |New;CDocTemplate::filterName- описание типа документа и маски для фильтра подходящих документов данного типа (например,Worddocument (*.doc)). Если значение этой строки не определено, то данный тип недоступен из менюFile | Open;

CDocTempIate::fflterExt- расширение для документов данного типа

(например, .doc). Если значение этой строки не определено, то данный тип недоступен из менюFile |Open;

CDocTempIate::regFileTypeId- идентификатор типа документа, хранимый в реестреWindows;

CDocTemplate::regFileTypeName- имя типа документа, хранимое в регистрационной базе данных.

CFrameWnd* CreateOIeFrame( CWnd*pParentWnd,CDocument*pDoc,BOOLb Create View);

Создает окно-рамку дляOLE-объекта. Если значениеbCreateViewравно нулю, то создается пустая рамка.Параметры:

pParentWnd -указатель на родительское окно-рамку.

pDoc- указатель на документ, на который будет ссылаться новыйOLE-объект.

bCreateView -определяет, будет ли одновременно создано отображение.

virtual Confidence MatchDocType( LPCTSTRipszPathName,CDocument*&rpDocMatch);

virtual Confidence MatchDocType( LPCTSTRIpszPathName,DWORDdwFileType,CDocument*&rpDocMatch);

Эти методы используются для определения типа шаблона документа, используемого для открытия файла. Также для приложений, поддерживающих несколько типов файлов эти методы позволяют установить какой шаблон документа применим для данного файла, для этого следует вызвать методMatchDocType последовательно для каждого шаблона.

Эти методы возвращают значение, определяемое перечислениемConfidence:

enumConfidence (noAttempt,

maybeAttemptForeign,// Расширение имени файла не совпадает

raaybeAttemptNative,   // Файл не открыт, но расширение имени файла // совпадает

yesAttemptForeign,

yesAttemptNative,

yesAlreadyOpen//Файлужеоткрыт

};Параметры:

IpszPathName -полное  имя  файла,  для  которого определяется тип.rpDocMatch -указатель на документ, если указанный файл уже открыт.

virtualCDocument*CreateNewDocument();

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

Метод возвращает указатель на новый созданный документ илиNULL в случае возникновения ошибки.

virtual CFrameWnd* CreateNewFrame (CDocument*pDoc,CFrameWnd*pOther);

Этот метод использует объектыCRuntimeClass, передавая их конструктору для создания нового окна рамки с пристыкованными к нему документом и отображением.

ПараметррOtherуказывает окно-рамку, используемое как основа, но может быть равнымNULL.

virtual void InitialUpdateFrarae( CFrameWnd*pFrame,CDocument*pDoc,BOOLbMakeVisible=TRUE);

После создания окна-рамки методомCreateNewFrame вызов данного метода позволяет выполнить обновление, вызвав методOnlnitialUpdate, и сделать созданное окно видимым и активным.

Параметры:

pFrame -указатель на окно-рамку.pDoc- указатель на документ илиNULL.

bMakeVisible- флажок, определяющий, следует ли сделать созданное окно видимым и активным.virtualBOOLSaveAllModified();

Метод сохраняет все документы данного шаблона документа, которые были изменены.virtualvoidCIoseAllDocuments(BOOLbEndSession);

Метод закрывает все открытые документы. По умолчанию реализация этого методы вызывает методCDocument: :DeleteContents для удаления содержания документа и затем закрывает окна-рамки для всех отображений сопоставленных документу. Обычно метод используется для обработки командыFile |Exit.

Параметры:

bEndSession-определяет, следует ли завершать сеанс работы (TRUE - завершить).

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

virtual CDocument*OpenDocumentFile(LPCTSTRipszPathName,BOOLbMakeVisible=TRUE) = 0;

Метод позволяет открыть файл с указанным именем. Если параметрIpszPathNameравенNULL, то создается новый файл: тип создаваемого файла определяется данным шаблоном документа.

virtual voidSetDefaultTitle(CDocument*pDocument) = 0;

Метод загружает заголовок окна документа, используемый по умолчанию, и отображает его. Заголовок окна по умолчанию можно получить по индексуCDocTemplate::docName из методаCDocTemplate::GetDocString.

КлассCSingleDocTemplate

КлассCSingleDocTemplateопределяет шаблон документа дляSDI-приложений: одновременно может быть открыт только один документ; до-! кумент отображается в главном окне. Как правило,SDI-приложения поддерживают только один тип документа и соответственно имеют только один объектCSingleDocTemplate.

CSingIeDocTemplate( UINTnIDResource,CRuntimeClass*pDocClass,CRuntimeCIass*pFrameClass,CRuntimeClass*pViewClass);Конструкторобъекта CSingleDocTemplate.

КлассCMultiDocTemplate

КлассCMultiDocTemplateопределяет шаблон документа дляMDI-приложений: одновременно может быть открыто несколько документов; главное окно используется как пространство, в котором можно открывать несколько окон-рамок для отображения документов.

CMuItiDocTemplate( UINTnIDResource,CRuntimeClass*pDocClass,CRuntimeClass*pFrameClass,CRuntimeCIass*pViewClass);

Конструктор классаCMultiDocTemplate.

Например:

//использование шаблона документаCMultiDocTemplate

BOOL CMyApp::InitInstance()

{

AddDocTemplate( new CMultiDocTemplate( IDR_SHEETTYPE,

RUNTIME_CLASS( CSheetDoc ),

RUNTIME_CLASS( CMDIChildWnd ),

RUNTIME_CLASS( CSheetView)));

AddDocTemplate( new CMultiDocTemplate( IDR_NOTETYPE, RUNTIME_CLASS( CNoteDoc ),

RUNTIME_CLASS( CMDIChildWnd ), RUNTIME_CLASS( CNoteView ) ) );II...}

Работа с документами

КлассCDocument

КлассCDocumentпредоставляет базисные возможности управления документами. Как правило, документ открывается по командеFile |Open (идентификаторID_FILE_OPEN) и сохраняется командойFile |Save (идентификаторID_FILE_SAVE).

КлассCDocument поддерживает набор стандартных операций над документом: создание, загрузка, сохранение.

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

Каждый документ содержит указатель на сопоставленный ему объект шаблона документа - для каждого типа документа свой шаблон документа.

Пользователи взаимодействуют с документом посредством объекта отображение (наследуемого от классаCView или его производных классов), ассоциированного с документом. Отображение представляет образ документа в окне-рамке и интерпретирует действия пользователя как операции над документом. Одному документу может быть сопоставлено несколько объектов отображений. Когда пользователь открывает окно для документа, то среда выполнения создает объект отображение и пристыковывает его к документу, а шаблон документа определяет, какой тип отображения и окна-рамки используется для отображения каждого типа документа.

Документы являются частью стандартного маршрута команд среды выполнения и поэтому получают команды от компонентов стандартного интерфейса пользователя (например, от пункта менюFile |Open). При этом они получают команды раньше активного объекта отображения. Если документ не обрабатывает данную команду, то она передается далее для обработки шаблону документа.

При изменении данных документа каким-то одним объектом отображения каждый из пристыкованных к документу объектов отображения должен также отобразить эти изменения. Для этого можно использовать методUpdateAllViews, сообщающий всем отображениям, пристыкованным к данному документу, о необходимости обновления отображения.

Для работы с документами в приложении следует:

•  создать производный класс от классаCDocumentдля каждого типа документа;

•                                             добавить переменные - члены класса для хранения данных каждого документа;

•                                              реализовать методы - члены класса, выполняющие чтение и изменение данных документа. Эти методы могут использоваться объектами отображениями для выполнения над документом;

•                                              переопределить в производном классе документа методCObject::Serialize для записи и чтения данных документа с диска.

Члены классаCDocument( );

Конструктор объекта классаCDocument.

После создания объекта для его инициализации вSDI-приложении следует переопределить методOnNewDocument.

voidAddView(CView*pView);

Метод пристыковывает отображение к данному документу и устанавливает для отображения указатель на сопоставленный ему документ . При этом он добавляет указанное отображение в список отображений, сопос-. тавленных данному документу. Этот метод вызывается средой выполнения для командFile |New,File |Open,Window |New и при разделении окна.

Параметры:

pView -указатель на добавляемое отображение.

Этот метод используется только при создании и пристыковке отображения вручную. Обычно, как правило, эти действия осуществляются средой выполнения в соответствии с шаблоном документа.   '

Приведем пример фрагмента кодаSDI-приложения, использующего два различных отображения. Синхронизация поддерживается только между активным отображениям и документом. Синхронизация с неактивным ото-j бражением выполняется в момент перевода его в активное отображение, что значительно эффективнее, чем постоянная поддержка синхронизации между данными документа и обоими отображениями.

BOOL CMainFrame::OnViewChange(UINT nCmdID)

CView*pViewAdd;     // Указатель на первое отображение

CView*pViewRemove;// Указатель на второе отображение

CDocument*pDoc =GetActiveDocument(); // Указатель на активный документ

UINT nCmdID;

nCmdID = LOWORD(GetCurrentMessage()->wParam);

if((nCmdID == ID_VIEW_VIEW1) && (m_currentView == 1)) return;//Переключениенатекущееотображение

if((nCmdID == ID_VIEW_VIEW2) && (m_currentView == 2)) return;//Переключениенатекущееотображение

if (nCmdID == ID_VIEW_VIEW2)

{// Переключение на другое отображение

if (m_pView2 ==NULL)

{ m_pViewl = GetActiveView(); m_pView2 = new CMyView2; m_pView2->Create (NULL, NULL, AFX_WS_DEFAULT_VIEW,

rectDefault, this, AFX_IDW_PANE_FIRST + 1, NULL);

} pViewAdd = m_pView2; pViewRemove = m_pViewl; m_currentView= 2;

}

else

{ pViewAdd = m_pView 1; pViewRemove = m_pView2; m_currentView= 1;} int nSwitchChildID = pViewAdd->GetDlgCtrlID();    //Получение ID pViewAdd->SetDlgCtrlID(AFX_IDW_PANE_FIRST);         //Установка ID,

//определяющегопоказнапереднемплане pViewRemove->SetDlgCtrlID(nSwitchChildID);        //Смена ID pViewAdd->ShowWindow(SW_SHOW); //Показновогоактивногоотображения pViewRemove->ShowWindow(SW_HIDE); //Скрытиенеактивногоотображения pDoc->AddView(pViewAdd);//Присоединениекдокументунового

//активногоотображения

pDoc->RemoveView(pViewRemove);  //Отсоединениенеактивногоотображения SetActive View(pViewAdd); RecalcLayout();         //Размещениенапервомпланеотображения

// с идентификаторомAFX_IDW_PANE_FIRST

}CDocTemplate*GetDocTemplate()const;

Метод возвращает указатель на шаблон документа для данного типа документа илиNULL, если шаблона документа для управления документом данного типа нет.

Приведем пример фрагмента кода, использующего указатель на шаблон документа.

CStringstrDefaultDocName;   // Имя файла, устанавливаемое по умолчаниюCStringstrBaseName;// Основа имени файла по умолчанию

CStringstrExt;// Расширение имени файла

// Эти строки являются подстроками информационной строки шаблона документаCDocTemplate*pDocTemplate =GetDocTemplate();if (!pDocTemplate->GetDocString(strBaseName,CDocTemplate:rdocName) || !pDocTemplate->GetDocString(strExt,CDocTemplate::filterExt))

{

"AfxThrowUserExceptionO;       //He предусмотрено шаблона для

// данного расширения имени файлаstrDefaultDocName =strBaseName +strExt;virtualPOSITIONGetFirstViewPosition()const;

Метод возвращает позицию первого отображения списка отображений Данного документа. Это значение передается методуGetNextView для циклического перехода между указателями на отображения из списка отображений.

Например:

POSITION pos = CDocument::GetFirstViewPosition(); //Позицияпервого

// отображенияCView*pFirstView =GetNextView(pos );     // Указатель на отображение

voidCMyDoc::OnRepaintAllViews()        // Посылка уведомлений всем {// отображениям об обновлении

POSITION pos = CDocument::GetFirstViewPosition();

while (pos != NULL)

{ CView* pView = GetNextView(pos); pView->UpdateWindow();} }

// Более простым способом достижения этого же результата является вызов // методаUpdateAllViews(NULL);

virtual CView* GetNextView( POSITION*rPosition )const;

Метод возвращает указатель на отображение, указанное параметромrPosition.При этом значениеrPositionустанавливается равным позиции следующего отображения из списка отображений для данного документа. Если полученное методом отображение последнее в списке, то значениеrPositionустанавливается равнымNULL.Пример:

POSITION pos = GetFirstViewPositionO; while (pos != NULL)

{ CView* pView = GetNextView(pos);      pView->UpdateWindow(); }const CString& GetPathName() const;

Метод возвращает строку, содержащую полный путь для файла, ассоциированного с данным документом. Если файл не был сохранен (не установлен полный путь для имени файла), то возвращается пустая строка.

virtual void SetPathName (LPCTSTRipszPathName,BOOLbAddToMRU =TRUE);

Метод устанавливает полный путь для файла, ассоциированного с данным документом.

Параметры:IpszPathName -строка, содержащая полный путь.

bAddToMRU -определяет, следует ли добавлять имя файла к списку файлов, открытых последними (MRU).

const CString& GetTitle()const;

Метод возвращает заголовок документа. Это может быть имя файла или значение, формируемое из информационной строки ресурса шаблона документа. Заголовок документа отображается как заголовок окна рамки.

virtual void SetTitle (LPCTSTRipszTitle);

Метод устанавливает новый заголовок документа.BOOLIsModified();

Метод определяет, был ли изменен документ с момента его последнего сохранения.voidRemoveView(CView*pView);

Метод отсоединяет указанное отображение от данного документа. Этот метод вызывается средой выполнения при закрытии окна-рамки или панели разделенного окна.

void SetModifiedCTag( BOOLbModified=TRUE);

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

Вызов метода с параметром, равнымFALSE, помечает документ как чистый (без изменений).

void UpdateAllViews( CView*pSender,LPARAMIHint=OL, CObject*pHint=NULL);

Этот метод вызывается отображением после изменения документа.

Параметры:

pSender -указатель на отображение, которое изменило документ, илиNULL для обновления всех отображений.IHint- содержит информацию об изменениях.pHint- указатель на объект, содержащий информацию об изменениях.

Этот метод инициирует для каждого отображения, за исключением указанного параметромpSender,вызов методовCView::OnUpdate.

virtual BOOL CanCloseFrame( CFrameWnd*pFrame);

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

virtualvoidDeleteContents();

Метод вызывается средой выполнения для удаления данных объекта документа без разрушения самого объекта. Метод может также вызываться для очистки содержимого документа с целью его повторного использования или для реализации командыEdit |ClearAll.

Реализация этого метода по умолчанию не выполняет никаких действий.

Приведем пример фрагмента кода, реализующего выполнение пункта менюEdit | Clear All.

voidCMyDoc::OnEditClearAll() {DeleteContentsO;UpdateAIlViews(NULL); }voidCMyDoc::DeleteContents() {// Переопределение метода }

virtualvoidOnChangedViewList();

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

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

virtualvoidOnCIoseDocument( );

Метод вызывается средой выполнения при закрытии документа, например как часть выполнения командыFile |Close. По умолчанию реализация этого метода вызывает методDeleteContents для удаления данных документа, а затем закрывает все окна-рамки для всех отображений пристыкованных, к данному документу.

virtualBOOLOnNewDocument();

Метод вызывается средой выполнения при создании нового документа, например как часть выполнения командыFile |New. По умолчанию реали-зация этого метода вызывает методDeleteContents для удаления данных документа, а затем помечает документ как "чистый".

Отметим, что при переопределении метода следует вызывать методOnNewDocument базового класса для выполнения стандартных действий. Как правило, переопределение метода заключается в инициализации нового документа: дляSDI-приложений это переинициализация уже существующего документа, а дляMDI-приложений - инициализация нового до-, кумента.

Приведем пример фрагмента кода, иллюстрирующего альтернативные способы инициализации объекта документа.

// Способ 1: ДляMDI-приложения самый простой и эффективный способ - это

// выполнить инициализацию документа в конструкторе класса, так как всегда

// создается новый объект документ и для командыFile |New, и для

// командыFile |Open:

CMyDoc::CMyDoc()       // Конструктор класса

{

// Код инициализации документа

}

// Способ 2: ДляSDI илиMDI приложения можно выполнить

// инициализацию документа, переопределив методOnNewDocument.

//.При этом следует быть уверенным, что инициализация документа

// выполняется эффективно посредством сериализации (во время выполнения

//команд File | Saveи File | Open).

BOOL CMyDoc::OnNewDocument()

{

if (!CDocument::OnNewDocument())

returnFALSE;

// Код инициализации документаreturnTRUE;

}

// Способ З: Если инициализация документа

// выполняется неэффективно посредством сериализации, то инициализацию

// следует выполнять в отдельном методе. Этот метод следует вызывать и из

//метода OnNewDocument,иизметода OnOpenDocument.

BOOL CMyDoc::OnNewDocument()

{

if (!CDocument::OnNewDocument())

returnFALSE;

MyInitDocument(); // Разделяемый метод инициализации документа // Код дополнительных действий, не требуемых при десериализации // документа черезFile |Open

return TRUE;'

}virtual BOOL OnOpenDocument( LPCTSTRipszPathName);

Метод вызывается средой выполнения при открытии нового документа, например как часть выполнения командыFile |Open. По умолчанию реализация этого метода открывает указанный файл, вызывает методDeleteContents, чтобы убедиться, что документ пуст, а затем вызывает методCObject::Serialize для чтения содержимого файла и в заключение помечает Документ как "чистый".

При успешной загрузке документа метод возвращает ненулевое значение. Этот "метод может быть переопределен для реализации других механизмов управления данными, без использования архива, а также для определения дополнительного кода инициализации.virtualBOOLOnSaveDocument(LPCTSTRIpszPathName);

Метод вызывается средой выполнения при сохранении документа, например как часть выполнения командFile |Save илиFile |SaveAs. По Умолчанию реализация этого метода открывает указанный файл, вызываетметодCObject::Serialize для записи данных из документа в файл и в заключение помечает документ как "чистый".

При успешном сохранении документа метод возвращает ненулевое значение.

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

Параметры:ipszPathName- указатель на полное имя сохраняемого файла.

virtual voidReportSaveLoadException(LPCTSTRIpszPathName,CException* e, BOOLbSaving,UINTnIDPDefault);

Метод вызывается средой выполнения (как правило, при броске исклю-ченняCFileException илиCArchiveException) в случае возникновения ошибки при выполнении сохранения или загрузке документа.

virtual CFile* GetFile( LPCTSTRIpszFileName,UINTnOpenFlags,CFileException*p Error);

Метод возвращает указатель на объектCFile.Параметры:

IpszFileName- строка, содержащая путь к имени файла (абсолютный или относительный).

рError- указатель на существующий объект исключение, который указывает состояние завершения операции.

nOpenFlags -флажки, указывающие режим разделения и режим доступа.virtualvoidReIeaseFile(CFile*pFile,BOOLbAbort);

Метод вызывается средой выполнения для освобождения файла, что делает его доступным для других приложений.

Параметры:

pFile -указатель на объектCFile.

bAbort- при значенииFALSE для освобождения файла вызываетсяметоЛCFile::Close а при значении - методCFile::Abort (при этом исключение не бросается).

virtualBOOLSaveModified();

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

Если документ не может быть закрыт, то метод возвращает нулевое значение.

virtual void PreCloseFrame( CFrameWnd*pFrame);

Метод вызывается средой выполнения перед разрушением указанного параметром окна-рамки. По умолчанию реализация этого метода для классаCDocument не выполняет никаких действий. Этот метод используется в производных классахCOleDocument иCRichEditDoc.

voidOnFileSendMail();

Метод посылает сообщение по электронной почте, содержащее данный документ.

В классеCOleDocument реализован методOnFileSendMail для обеспечения корректного управления составными файлами.voidOnUpdateFileSendMaiKCCmdUI*pCmdUI);

При поддержкеMAPI-интерфейса (наличия библиотекиMAPI32.DLL, установки МАР1=1 в секции [Mail] файлаWIN.INI) этот метод позволяет использовать командуID_FILE_SEND_MAIL. В противном случае команда будет удалена из меню.

Параметры:

pCmdUI -указатель на объектCCmdUI, ассоциированный с командойID_FILE_SEND_MAIL.

Сериализация данных

БиблиотекаMFC реализует модель обмена данными между документом и файлом через специальный объект, называемый архивом. Обмен данными между приложением и архивом называетсясериализацией.Для обмена данными используется методSerializeкласса документа.

При создании шаблона приложения с помощью мастераAppWizard можно добавить менюFile, содержащее пунктыOpen,Save иSaveas. Для обработки каждого из указанных пунктов менюAppWizard вставляет в программный код класса документа (производного отCDocument)переопределяемый методSerializeили для чтения состояния документа из архива, или для записи (загрузки) состояния документа в архив. Программисту остается только вставить в методSerializeкод, выполняющий запись переменных в архив и чтение переменных из архива.

ОбъектCArchiveаналогичен объектам ввода/выводаcinиcoutиз библиотекиiostream C++. ОднакоCArchiveвыполняет операции чтения и записи в двоичном формате без форматирования текста.

Напомним, что для использования средств сериализации следует включить в объявление и реализацию класса соответственно макросыDE-CLARE_SERIAL иIMPLEMENT_SERIAL.

КлассCArchive

КлассCArchiveне имеет базового класса.

ОбъектCArchiveпозволяет организовывать обмен данными между документом и файлом через промежуточный объект архив. Архив можно рассматривать как некоторый буфер, реализующий специальный механизм хранения данных. Создаваемый для документа и файла архив позволяет абстрагироваться от места расположения архива: в оперативной памяти или на диске.

Обмен данными между архивом и документом называют сериализацией1.

Перед созданием объектаCArchiveдолжен быть создан объектCFile.Затем объект архив пристыковывается к объектуCFile(или производного от него класса).

Объект архив создается при вызове командOpen,Save иSaveAs.

Члены классаCArchive

m_pDocument        Указатель сериализуемого объектаCDocumentCArchiveЯвляется конструктором класса и создает объект

CArchive

AbortЗакрывает архив без броска исключения

CloseСбрасывает незаписанные данные и выполняет отсо-

единение отCFile

FlushСбрасывает незаписанные данные из буфера архива Ц

оператор »Загружает из архива объекты и простые типы

оператор «Сохраняет в архиве объекты и простые типы

ReadЧитает байты

WriteЗаписывает байты

WriteStringЧитает одну строку текста

ReadStringЗаписывает строку текста

GetFileПолучает для данного архива указатель на объект

CFileGetObjectSchema     Вызывает методSerialize для определения версиидея

сериализованного объекта

SetObjectSchema     Устанавливает версию хранимого в архиве объектаIsLoadingОпределяет, был ли архив загружен и можно выпол-

нять запись данныхIsStoringОпределяет, был ли архив сохранен и можно ливыЯ

поднять чтение данных

IsBufferEmpty         Определяет, пуст ли буферReadObjectВызывает для загрузки объекта методSerialize

WriteObjectВызывает методSerialize для сохранения объекта

MapObjectПомещает объект в таблицу

SetStoreParamsУстанавливает размер хеш-таблицы и размер блока

таблицы

SetLoadParamsУстанавливает размер для загружаемого массива

ReadClassЧитает ссылку, сохраненную методомWriteClass

WriteClassЗаписывает вCArchive ссылку наCRuntimeClass

SerializeClassЧитает или записывает ссылку вCArchive

Функции-членыкласса

Archive (CFile*pFile,UINTnMode,intnBufSize=4096, void*lpBuf=NULL); throw (CMemoryException, CArchiveException, CFileException);

Конструктор класса.Параметры:

pFile -указатель на объектCFile,который является или источником или назначением для сохраняемых данных.

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

CArchive::Ioad- загрузка данных из архива. ОбъектCFileдолжен быть доступен на чтение;CArchive::store- сохранение данных в архиве. ОбъектCFileдолжен быть

доступен на запись;

CArchive::bNoFlushOnDelete- предотвращает автоматический вызов методаFlushпри выполнении деструктора. Отметим, что при установке данного флажка необходимо напрямую вызывать методCloseдо вызова деструктора.

nBufSize- размер в байтах внутреннего файлового буфера. По умолчанию этот размер равен 4096 байт.

ipBuf -необязательный параметр, который позволяет передать методу определенный пользователем указатель на буфер размераnBufSize.Если этот параметр не указан, то буфер размещается в динамически распределяемой области памяти, называемой также кучей. В этом случае память будет освобождена сразу при разрушении объекта. Отметим, что область памяти, указанная пользователем через данный параметр, не освобождается автоматически при разрушении объекта.

Конструктор создает объектCArchiveи определяет статус его использования: для загрузки или для сохранения объекта. Статус архива нельзя изменить после его создания. Также до закрытия архива нельзя использовать операцииCFileдля изменения его состояния.

Пример:

externchar*pFileName;CFilef;charbuf!512];if( !f.Open(pFileName,CFile::modeCreate |CFile::modeWrite )) { #ifdef_DEBUGafxDump << "Нельзя открыть файл" << "\n";exit( 1 ); #endif

} CArchive ar(&f, CArchive::store, 512, buf);

voidAbort( );

Этот метод закрывает архив, не обрабатывая исключение. Если для размещения объектаCArchiveбыл использован операторnew,то после закрытия файла этот объект следует удалить.

void Close( ); throw( CArchiveException, CFileException);

Сбрасывает оставшиеся в буфере данные, закрывает архив и отсоединяет архив от файла.

voidFlush( );throw(CFileException);

Инициирует запись (сброс) в файл оставшихся в архиве данных.CFile*GetFile( )const;

Метод возвращает указатель на используемый объект типаCFile.Отметим, что до вызова данного метода следует сбросить архив.

Пример:

extern CArchive ar; [const CFile* fp = ar.GetFileQ;

UINTGetObjectSchema();

Метод возвращает читаемую во время сериализации версию объекта. Этот метод вызывается из методаSerializeи доступен, только если в архив! выполнена загрузка. Если версия не определена, то метод возвращает зна-1 чение(UINT)-l.Пример:

ЦРеализация "версионного" объекта

IMPLEMENT_SERIAL(CMyObject,CObject,VERSIONABLE_SCHEMA|1)voidCMyObject.:Serialize(CArchive&ar)       // Переопределение методаSerialize

{if (ar.IsLoading())// Была выполнена загрузка данных в архив!

{

int nVersion=ar.GetObjectSchema();

switch(nVersion)

{case 0:

// Чтение предыдущей версии данного объекта

break;case 1:

// Чтение текущей версии

break;default:

// Получен неизвестный номер версии

break; }

}.

else

{

// Программный код для записи переменных в архив

} }BOOLIsBufferEmpty( )const;

В случае пустого буфера метод возвращает ненулевое значение, и 0 - в противном случае. Эта функция используется для объектов классаCSocketFile.

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

BOOLIsLoading( )const;

Если текущий архив используется для загрузки данных (чтения из архива), то метод возвращает ненулевое значение, и 0 - в противном случае.

Этот метод вызывается, как правило, из методаSerializeдля определения статуса архива.

Пример:

int i; extern CArchive ar; if( ar.IsLoading())ar »ц '              //Чтениеизархива else __ar << i;               //Записьвархив

BOOL IsStoring()const;

Если текущий архив используется для сохранения данных (записи в архив), то метод возвращает ненулевое значение, и 0 - в противном случае.

Этот метод вызывается, как правило, из методаSerializeдля определен] ния статуса архива.

void MapObject( const CObject*^0Z>);

Этот метод позволяет размещать в таблице объекты и в дальнейшем ис-| пользовать их для ссылки на документ. Как правило, это используется в том случае, если документ подлежит сериализации не непосредственно, а как отдельный элемент (подобъект).

Параметры:

рОЪ -указатель на сохраняемый объект.Пример:

IIФайлMyDoc.h

//Для документа следует указатьDECLARE_SERIAL иIMPLEMENT_SERIAL

class CMyDocument: public CDocument

{   CObList mJistOfSubltems;

DECLARE_SERIAL(CMyDocument)

};

//Файл MyDoc.cpp IMPLEMENT_SERIAL(CMyDocument, CObject, 1)

void CMyDocument::Serialize(CArchive& ar)

{

if (ar.IsStoringO) {

// TODO: add storing code here

// TODO: add loading code here ar.MapObject(this);

//Файл Subltem.h

class CSubltem : public CObject

public:

CSubItem(CMyDocument*pDoc)

{m_pDoc =pDoc; } // Обратный указатель на документCMyDocument*m_pDoc;WORDmi; // Другой элемент данныхvirtualvoidSerialize(CArchive&ar);

};

//Файл Subltem.cpp

void CSubItem::Serialize(CArchive& ar)

{

if (ar.IsStoringO) {

ar << m_pDoc; ar << m_i; }

else {

ar » m_pDoc; ar » rh_i; } }UINT Read( void*ipBuf,UINTnMax);throw( CFileException );

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

Параметры:

IpBuf-указатель буфера, в который производится чтение данных из архива.пМах -количество читаемых их архива байт.Пример:

extern CArchive ar; char pbuf[ 100]; UINT nr = ar.Read( pbuf, 100 );

CRuntimeClass* ReadClass (const CRuntimeClass*pClassRefRequested=NULL, UINT*pSchema=NULL, DWORD*obTag=NULL); Throw CArchiveException; Throw CNotSupportedException;

Метод возвращает указатель на структуруCRuntimeClass.Этот метод следует использовать для получения ссылки на класс, ранее сохраненный методомWriteClass.

CObject* ReadObject (const CRuntimeClass*pClass);

throw (CFileException, CArchiveException, CMemoryException);

Методчитаетизархиваданныеобъектаисоздаетобъектсоответствующеготипа,возвращаяуказательCObject.

Параметры:

РClass- указатель структурыCRuntimeClass,соответствующей читаемому объекту.

Bool ReadString(CString&rString);

LPTSTR ReadString( LPTSTRIpsz,UINTnMax);throw( CArchiveException);

При успешном чтении строки первый метод возвращает значениеTRUE,а второй - указатель на буфер, содержащий текстовые данные. В противном случае первый метод возвращает значениеFALSE,а второй -NULL(достигнут конец файла).

Параметры:

rString- ссылкаCStringна строку, содержащую результат чтения строки из файла, соединенного с объектомCArchive.

Ipsz -указатель буфера, в который будет записана читаемая строка.пМах -максимальное количество читаемых символов.voidSerializeCIass(constCRuntimeClass*pRuntimeClass);

Этот метод используется для сохранения или загрузки информации базового класса. Он читает или записывает в объектCArchive.Пример:

classCBaseClass :publicCObject {... };

class CDerivedClass : public CBaseClass { ... };

void CDerivedClass::Serialize(CArchive& ar)   //Переопределениеметода

Serialize

{

if(ar.IsStoring())

{ //Код,сохраняющийобъект

}

else

{ //Код,читающийобъект

}

ar.SerializeClass(RUNTIME_CLASS(CBaseClass)); CBaseClass:: Serialize(ar); }void SetLoadParams( UINTnGrowBy= 1024);

Этот метод следует использовать в том случае, если требуется, прочитать из архива большое количество объектов, производных от классаCObject.CArchiveиспользует для ссылок на объекты, хранимые в архиве, загружаемый массив. Данный метод позволяет увеличить размер этого массива. Отметим, что если какой-либо объект уже был загружен или были вызваны методыMapObjectилиReadObject,то использовать данный метод уже нельзя.Пример:

class CMyLargeDocument : public CDocument { ... }; void CMyLargeDocument::Serialize(CArchive& ar)

{

if (ar.IsStoringO)

ar. SetStoreParams(); else

ar. SetLoadParamsO;

if (ar.IsStoringO)

{

//Коддлясохранения CMyLargeDocument }

else {

//Коддлязагрузки CMyLargeDocument } }void SetObjectSchema( UINTnSchema);

Параметры:

nSchema -определяетсхемуобъекта.void SetStoreParams (UINTnHashSize=2053, UINTnBlockSize=128);

Этот метод используется при сохранении в архиве большого количества объектов (производных отCObject).

void Write (const void*ipBuf,UINTnMax);throw (CFileException);

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

Параметры:

IpBuf-буфер, содержащий данные, записываемые в архив.пМах- количество записываемых байт.

Пример:

extern CArchive ar; char pbuft 100]; JirWritef pbuf, 100 );

void WriteClass( const CRuntimeClass*pClassRef);

Этот метод используется для сохранения в архиве информации о классе.

void WriteObject(const CObject*pOb);throw (CFileException, CArchiveException);

Сохраняет в архиве указанныйCObject.

Параметры:

pOb- указатель на сохраняемый объект.voidWriteString (LPCTSTRIpsz);throw (CFileException);

Переписывает данные из буфера в файл, состыкованный с объектомCArchive.

Параметры:Ipsz -указатель на буфер, содержащий строку (ограниченную0-символом).\

Операторы CArchive::operator <<

friend CArchive& operator « (CArchiveAar,const CObject*pOb);throw (CArchiveException, CFileException);

CArchive& operator « (BYTEby);throw(CArchiveException, CFileException);

CArchive& operator « (WORDw);throw(CArchiveException, CFileException);

CArchive& operator « (intf);throw(CArchiveException, CFileException);

CArcliive& operator « (LONGI);throw (CArchiveException, CFileException);

CArchive& operator « (DWORDdw);throw(CArchiveException, CFileException);

CArchive& operator « (float/); throw(CArchiveException, CFileException);

CArchive& operator « (doubled);throw(CArchiveException, CFileException);

Оператор выполняет сохранение указанного объекта или данных заданного типа в архиве. Оператор возвращает ссылкуCArchive,что позволяет указывать подряд в одной строке несколько таких операторов совместно с записываемыми ими данными.Пример:

long I; int i; extern CArchive ar; if( ar.IsStoring()) ar « 1 « i;

CArchive::operator >>

friend CArchive& operator » (CArchive&ar,CObject *&pOb);throw (CArchiveException, CFileException, CMemoryException);

friend CArchive& operator » (CArchive&ar,const CObject *&pOb);throw (CArchiveException, CFileException, CMemoryException);

CArchive& operator » (BYTE&by);throw (CArchiveException, CFileException );

CArchive& operator >> (WORD&w);throw (CArchiveException, CFileException );

CArchive& operator » (int& 0; throw (CArchiveException, CFileException);

CArchive& operator » (LONG&I);throw (CArchiveException, CFileException);

CArchive& operator » (DWORD&dw);throw (CArchiveException, CFileException);

CArchive& operator » (float*f);throw (CArchiveException, CFileException);

CArchive& operator » (double&d);throw (CArchiveException, CFileException);

Загружает из архива указанный объект или данные заданного типа, напримерar »i;




Возможно эти работы будут Вам интересны.

1. Окно отображения хода генерации ключа шифрования

2. Основополагающие документы по вопросам модернизации общего и профессионального образования

3. Шишкин Василий Сергеевич ДОКУМЕНТЫ В ДОКАЗЫВАНИИ ПРИ ПРОИЗВОДСТВЕ ПО УГОЛОВНОМУ ДЕЛУ

4. -документы могут просматриваться различными типами браузеров наиболее известным из которых являетсяInternetExplo.

5. Обязанности и функции общественных организаций Документы при создании общественных объединений в России

6. Процесс подготовки учителя к уроку подразделяется на 2 периода, предварительный и непосредственный. В предварительный период учитель узучает нормативные документы