<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Программирование на языке MFC &#187; CDocTemplate</title>
	<atom:link href="http://www.programmfc.ru/tag/cdoctemplate/feed" rel="self" type="application/rss+xml" />
	<link>http://www.programmfc.ru</link>
	<description>Мой второй блог в серии программирования</description>
	<lastBuildDate>Mon, 08 Feb 2010 19:34:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Объекты класса CDocMan­ager</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%be%d0%b1%d1%8a%d0%b5%d0%ba%d1%82%d1%8b-%d0%ba%d0%bb%d0%b0%d1%81%d1%81%d0%b0-cdocmanager.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%be%d0%b1%d1%8a%d0%b5%d0%ba%d1%82%d1%8b-%d0%ba%d0%bb%d0%b0%d1%81%d1%81%d0%b0-cdocmanager.html#comments</comments>
		<pubDate>Mon, 08 Feb 2010 19:34:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[Работа с файлами]]></category>
		<category><![CDATA[CDocTemplate]]></category>
		<category><![CDATA[CWinApp]]></category>
		<category><![CDATA[Объекты класса CDocMan­ager]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%be%d0%b1%d1%8a%d0%b5%d0%ba%d1%82%d1%8b-%d0%ba%d0%bb%d0%b0%d1%81%d1%81%d0%b0-cdocmanager.html</guid>
		<description><![CDATA[Что мы можем здесь увидеть? То, что в описании этого класса присутствует поле rnJTemplateList класса CPtrList, только подтвер­ждает нашу догадку о том, что de facto объекты класса CDocMan­ager являются списками указателей на какие-то шаблоны. Для того чтобы убедиться, что наша догадка верна, достаточно взглянуть на исходный код методов GetFirstDocTemplatePosition() и GetNext-DocTemplate(), который находится в файле [...]]]></description>
			<content:encoded><![CDATA[<p>Что мы можем здесь увидеть? То, что в описании этого класса присутствует поле rnJTemplateList класса CPtrList, только подтвер­ждает нашу догадку о том, что de facto объекты класса CDocMan­ager являются списками указателей на какие-то шаблоны. Для того чтобы убедиться, что наша догадка верна, достаточно взглянуть на исходный код методов GetFirstDocTemplatePosition() и GetNext-DocTemplate(), который находится в файле docmgr.cpp:</p>
<p><b>POSITION CDocManager::GetFirstDocTemplatePosition() const {</b></p>
<p><b>return m_templateList.GetHeadPosition() ;</b></p>
<p>}</p>
<p><b>CDocTemplate* CDocManager::GetNextDocTemplate(</b></p>
<p><b>POSITIONS pos) const</b></p>
<p>{</p>
<p><b>return (CDocTemplate*)m_templateList.GetNext(pos) ;</b></p>
<p>Теперь возникает вопрос о том, что за шаблоны включаются в список. Позвольте, уважаемый читатель, высказать предположе­ние о том, что этими шаблонами являются шаблоны ДОКУМЕН­ТОВ, с которыми работает данное приложение. Я не буду сейчас останавливаться на том, что такое шаблон документа. Это станет ясно из дальнейшего изложения.</p>
<p>Сейчас нам необходимо научиться создавать объект этого класса. Естественно, что для создания объекта мы восполь­зуемся конструктором. Раз конструктор класса CDocManager параметров не имеет, то создание объекта этого класса за­труднений не вызовет. Но каким-то образом нам необходимо передать нашему приложению информацию о том, с документа­ми каких типов (шаблонов) он будет иметь дело! Вспомним, что у класса CWinApp для добавления шаблона в список есть метод AddDocTemplate(), который, фактически является вызовом одно­именного метода класса CDocManager. Наверное, именно этим методом и следует воспользоваться при добавлении шаблона документа!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%be%d0%b1%d1%8a%d0%b5%d0%ba%d1%82%d1%8b-%d0%ba%d0%bb%d0%b0%d1%81%d1%81%d0%b0-cdocmanager.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Класс CDocManager</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%ba%d0%bb%d0%b0%d1%81%d1%81-cdocmanager.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%ba%d0%bb%d0%b0%d1%81%d1%81-cdocmanager.html#comments</comments>
		<pubDate>Mon, 08 Feb 2010 19:34:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[Работа с файлами]]></category>
		<category><![CDATA[CDocTemplate]]></category>
		<category><![CDATA[CWinApp]]></category>
		<category><![CDATA[DoPromptFileName]]></category>
		<category><![CDATA[OnFileOpen]]></category>
		<category><![CDATA[OpenDocumentFile]]></category>
		<category><![CDATA[Класс CDocManager]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%ba%d0%bb%d0%b0%d1%81%d1%81-cdocmanager.html</guid>
		<description><![CDATA[Наверное, из описания класса CWinApp мы не сумеем извлечь еще какую-то информацию о классе CDocManager. Настало время взглянуть на описание этого класса. Думаю, нет необходимости описывать всю внутреннюю реализацию этого класса. Достаточно будет, если мы рассмотрим назначение наиболее часто используе­мых полей и методов.
Класс CDocManager в файле afxwin.h описан следующим образом:
class CDocManager : public CObject {
DECLARE_DYNAMIC(CDocManager) [...]]]></description>
			<content:encoded><![CDATA[<p>Наверное, из описания класса CWinApp мы не сумеем извлечь еще какую-то информацию о классе CDocManager. Настало время взглянуть на описание этого класса. Думаю, нет необходимости описывать всю внутреннюю реализацию этого класса. Достаточно будет, если мы рассмотрим назначение наиболее часто используе­мых полей и методов.</p>
<p>Класс CDocManager в файле afxwin.h описан следующим образом:</p>
<p><b>class CDocManager : public CObject {</b></p>
<p><b>DECLARE_DYNAMIC(CDocManager) public:</b></p>
<p><b>// Constructor CDocManager();</b></p>
<p><b>//Document functions</b></p>
<p><b>virtual void AddDocTemplate(CDocTemplate* pTemplate); virtual POSITION GetFirstDocTemplatePosition() const; virtual CDocTemplate* GetNextDocTemplate(</b></p>
<p><b>POSITIONS pos) const; virtual void RegisterShellFileTypes(BOOL bCompat); void UnregisterShellFileTypes();</b></p>
<p><b>virtual CDocument* OpenDocumentFile(LPCTSTR IpszFileName);</b></p>
<p><b>// open named file</b></p>
<p><b>virtual BOOL SaveAllModified(); // save before exit virtual void CloseAllDocuments(BOOL bEndSession);</b></p>
<p><b>// close documents before exiting virtual int GetOpenDocumentCount();</b></p>
<p><b>// helper for standard commdlg dialogs virtual BOOL DoPromptFileName(CString&amp; fileName</b></p>
<p><b>UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate);</b></p>
<p><b>//Commands</b></p>
<p><b>// Advanced: process async DDE request</b></p>
<p><b>virtual BOOL OnDDECommand(LPTSTR IpszCommand); virtual void OnFileNew(); virtual void OnFileOpen();</b></p>
<p><b>// Implementation protected:</b></p>
<p><b>CPtrList m_templateList;</b></p>
<p><b>int GetDocumentCount(); // helper to count number</b></p>
<p><b>// of total documents</b></p>
<p><b>public:</b></p>
<p><b>static CPtrList* pStaticList;</b></p>
<p><b>// for static CDocTemplate objects static BOOL bStaticInit;</b></p>
<p><b>// TRUE during static initialization static CDocManager* pStaticDocManager;</b></p>
<p><b>// for static CDocTemplate objects</b></p>
<p><b>public:</b></p>
<p><b>virtual -CDocManager(); #ifdef _DEBUG</b></p>
<p><b>virtual void AssertValid() const;</b></p>
<p><b>virtual void Dump(CDumpContext&amp; dc) const; #endif };</b></p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%ba%d0%bb%d0%b0%d1%81%d1%81-cdocmanager.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Отображение документа</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%be%d1%82%d0%be%d0%b1%d1%80%d0%b0%d0%b6%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b4%d0%be%d0%ba%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d0%b0.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%be%d1%82%d0%be%d0%b1%d1%80%d0%b0%d0%b6%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b4%d0%be%d0%ba%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d0%b0.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:49:44 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CDocTemplate]]></category>
		<category><![CDATA[CMDIChildWnd]]></category>
		<category><![CDATA[lnitlnstance]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%be%d1%82%d0%be%d0%b1%d1%80%d0%b0%d0%b6%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b4%d0%be%d0%ba%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d0%b0.html</guid>
		<description><![CDATA[Во-первых, для того чтобы рассмотреть вопрос отображения доку­мента, нам необходимо вспомнить, что у нас до сих пор указатель на информацию времени исполнения окна представления нашей программы равен NULL. В связи с этим необходимо описать класс окна представления..Следрвательно, наша программа немного из­менилась. Сразу после описания класса документа я добавил опи­сание класса окна представления:
class CDocView : public [...]]]></description>
			<content:encoded><![CDATA[<p>Во-первых, для того чтобы рассмотреть вопрос отображения доку­мента, нам необходимо вспомнить, что у нас до сих пор указатель на информацию времени исполнения окна представления нашей программы равен NULL. В связи с этим необходимо описать класс окна представления..Следрвательно, наша программа немного из­менилась. Сразу после описания класса документа я добавил опи­сание класса окна представления:</p>
<p><b>class CDocView : public CView {</b></p>
<p><b>DECLARE_DYNCREATE ( CDocView ) public:</b></p>
<p><b>CDocView();</b></p>
<p><b>virtual -CDocView();</b></p>
<p><b>&gt;;</b></p>
<p><b>IMPLEMENT_DYNCREATE( CDocView, CView )</b></p>
<p><b>CDocView::CDocView()</b></p>
<p>{</p>
<p>}</p>
<p><b>CDocView::-CDocView()</b></p>
<p>{</p>
<p>}</p>
<p>Кроме этого, я изменил метод lnitlnstance() класса CDocViewl:</p>
<p><b>BOOL CDocViewlApp::Initlnstance() {</b></p>
<p><b>#ifdef _AFXDLL</b></p>
<p><b>Enable3dControls(); #else</b></p>
<p><b>Enable3dControlsStatic(); #endif</b></p>
<p><b>LoadStdProfileSettings(); CDocTemplate* pDocTemplate;</b></p>
<p><b>pDocTemplate = new CMultiDocTemplate( IDR_DOCUMENT,</b></p>
<p><b>RUNTIME__CLASS ( CDoc ) , RUNTIME_CLASS( CMDIChildWnd ), RUNTIME_CLASS( CDocView ) ) ; AddDocTemplate( pDocTemplate ); CMainFrame* pMainFrame = new CMainFrame; pMainFrame-&gt;LoadFrame( IDR_RESOURCE ); m_pMainWnd = pMainFrame; pMainFrame-&gt;ShowWindow(m_nCmdShow ); pMainFrame-&gt;UpdateWindow();</b></p>
<p><b>return TRUE;</b></p>
<p>}</p>
<p>Когда я постарался откомпилировать эту программу, я получил сообщение о том, что у класса, наследуемого от CView, не опреде­лен метод OnDraw(). Ну, конечно же! Откуда же наш произвольный класс окна представления будет знать, каким образом ему необхо­димо перерисовываться? Давайте опять постараемся рассуждать логически. Какое сообщение получает окно, когда ему нужно пе­рерисовать себя? Правильно, WM_PAINT. Но для обработки со­общения WM_PAINT объекты MFC используют метод OnPaintQ.</p>
<p>Не является исключением и объекты класса CView и унаследо­ванных от него. Исходный код этого метода находится в файле viewcore.cpp:</p>
<p><b>void CView::OnPaint() {</b></p>
<p><b>// standard paint routine CPaintDC dc(this); OnPrepareDC(&amp;dc); OnDraw(&amp;dc);</b></p>
<p>}</p>
<p>Очевидно, что перерисовка осуществляется методом OnDraw(). Взглянем на исходный код этого метода, который также находится в файле viewcore.cpp:</p>
<p><b>void CView::OnDraw(CDC*)</b></p>
<p>{</p>
<p>}</p>
<p>To, что этот метод не делает ничего, подтверждает нашу догад­ку о том, что нам нужно переписать именно этот метод. Что ж опи­сание нашего класса CDocView придется немного изменить. Те­перь оно будет выглядеть так:</p>
<p><b>class CDocView : public CView {</b></p>
<p><b>DE</b><b>С</b><b>LARE_DYNCREATE ( CDocView ) public:</b></p>
<p><b>CDocView();</b></p>
<p><b>virtual ~CDocView(); void OnDraw( CDC* pDC );</b></p>
<p><b>};</b></p>
<p>Естественно, нам придется переопределить и добавить в про­грамму метод OnDravtr(). Пока этот метод нас не очень интересует, поэтому оставим его пустым:</p>
<p><b>void CDocView::OnDraw( CDC* pDC )</b></p>
<p>{</p>
<p>}</p>
<p>Наверное, отсюда можно сделать вывод, что класс CView пре­доставляет только базовые возможности для отображения данных. Надеюсь, у нас еще будет шанс разобраться с этим.</p>
<p>Любознательный читатель уже, наверное, приготовил мне во­прос: да, конечно, все что рассказывается, это верно, но каким же образом создается окно представления и как оно относится к окну фрейма и документу?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%be%d1%82%d0%be%d0%b1%d1%80%d0%b0%d0%b6%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b4%d0%be%d0%ba%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d0%b0.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Метод Serialize</title>
		<link>http://www.programmfc.ru/prilozheniya/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-serialize-3.html</link>
		<comments>http://www.programmfc.ru/prilozheniya/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-serialize-3.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:49:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Приложения]]></category>
		<category><![CDATA[CDocTemplate]]></category>
		<category><![CDATA[CMDIChildWnd]]></category>
		<category><![CDATA[CWinApp]]></category>
		<category><![CDATA[OnFileOpen]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-serialize-3.html</guid>
		<description><![CDATA[Документ, естественно, рождается из файла, поэтому первым делом метод, вызывая GetFile(), открывает файл, имя которого, как я уже говорил, он получил в качестве аргумента. Затем начинается самое интересное. На основе файла создается объект класса САг-chive, т. е. АРХИВ. В архитектуре «документ/представление» счи­тается, что программист должен иметь возможность легко сохра­нять созданные в памяти структуры данных в [...]]]></description>
			<content:encoded><![CDATA[<p>Документ, естественно, рождается из файла, поэтому первым делом метод, вызывая GetFile(), открывает файл, имя которого, как я уже говорил, он получил в качестве аргумента. Затем начинается самое интересное. На основе файла создается объект класса САг-chive, т. е. АРХИВ. В архитектуре «документ/представление» счи­тается, что программист должен иметь возможность легко сохра­нять созданные в памяти структуры данных в дисковом файле, после чего он должен иметь возможность вновь считать их из фай­ла. Архив позволяет программисту читать и записывать в файл не просто некоторые объемы информации, а ОБЪЕКТЫ всевозмож­ных типов! Именно поэтому его использование в большинстве слу­чаев представляется оправданным. И дальше вызывается метод Serialize(), который работает уже не с файлом, а с архивом! По умолчанию этот метод не делает ничего. Естественно, откуда про­грамме знать, что и как программисту захотелось сохранить в ар­хиве? А для программиста здесь раздолье! Можно проверить фор­мат открытого файла, определить, при необходимости, его струк­туру, выполнить все мыслимые и немыслимые действия. Для того чтобы продемонстрировать работу метода Serialize(), давайте по­пробуем открыть файл в нашей программе и считать его в буфер. Внесем небольшие изменения в наш класс документа &#8211; добавим два поля, в которые запишем, во-первых, размер файла, а второй будет являться указателем на буфер, в который мы будем читать файл. После внесенных изменений наша программа выглядит сле­дующим образом:</p>
<p><b>#include &quot;stdafx.h&quot; #include &lt;afxcview.h&gt; #include &quot;resource.h&quot;</b></p>
<p><b>// Объявляем класс приложения, его поля и методы.</b></p>
<p><b>class CDoc : public CDocument {</b></p>
<p><b>DECLARE_DYNCREATE( CDoc ) int nFileLength; void* pMyFile; public: CDocO ;</b></p>
<p><b>void Serialize ( CArchive &amp;ar ); virtual -CDoc();</b></p>
<p><b>}/</b></p>
<p><b>• IMPLEMENT_DYNCREATE( CDoc, CDocument )</b></p>
<p><b>CDoc::CDoc()</b></p>
<p>{</p>
<p>}</p>
<p><b>CDoc::-CDoc()</b></p>
<p>{</p>
<p>}</p>
<p><b>void CDoc::Serialize( CArchive &amp;ar ) {</b></p>
<p><b>if( ar.IsStoring() )</b></p>
<p>{</p>
<p>}</p>
<p><b>else {</b></p>
<p><b>// </b><b>Определяем</b><b> </b><b>длину</b><b> </b><b>файла</b><b>.</b></p>
<p><b>nFileLength = ar.GetFile()-&gt;GetLength();&#8217;</b></p>
<p><b>TRACE( _T( &quot;File length = %d.\n&quot;), nFileLength&#8217; );</b></p>
<p><b>// Выделяем буфер в памяти, в который будем считывать файл. pMyFile = new chart nFileLength ];</b></p>
<p><b>// Считываем файл в буфер.</b></p>
<p><b>ar.Read( pMyFile, nFileLength ); }</b></p>
<p>}</p>
<p><b>class CDocViewlApp : public CWinApp {</b></p>
<p><b>public:</b></p>
<p><b>CDocViewlApp(); protected:</b></p>
<p><b>afx_msg void OnFileOpen(); virtual BOOL Inifrlnstance(); DEC LARE_ME S S AGE_MA P()</b></p>
<p>};</p>
<p><b>CDocViewlApp::CDocViewlApp()</b></p>
<p>{</p>
<p>}</p>
<p><b>void CDocViewlApp::OnFileOpen()</b></p>
<p>{</p>
<p>}</p>
<p><b>class CMainFrame : public CMDIFrameWnd {</b></p>
<p><b>DECLARE_DYNAMIC( CMainFrame ); public:</b></p>
<p><b>CMainFrame();</b></p>
<p><b>&gt;;</b></p>
<p><b>IMPLEMENT_DYNAMIC (CMainFrame, CMDIFrameWnd)</b></p>
<p><b>CMainFrame::CMainFrame()</b></p>
<p>{</p>
<p>}</p>
<p><b>BOOL CDocViewlApp::Initlnstance() {</b></p>
<p><b>#ifdef _AFXDLL</b></p>
<p><b>Enable3dControls(); #else</b></p>
<p><b>Enable3dControlsStatic(); #endif</b></p>
<p><b>LoadStdProfileSettings(); CDocTemplate* pDocTemplate;</b></p>
<p><b>pDocTemplate = new CMultiDocTemplate( IDR_DOCUMENT,</b></p>
<p><b>RUNTIME_CLASS( CDoc ) , RUNTIME_CLASS( CMDIChildWnd ), NULL );</b></p>
<p><b>AddDocTemplate( pDocTemplate ); CMainFrame* pMainFrame = new CMainFrame; pMainFrame-&gt;LoadFrame ( IDR__RESOURCE ) ; m_pMainWnd = pMainFrame; pMainFrame-&gt;ShowWindow(m_nCmdShow ); pMainFrame-&gt;UpdateWindow();</b></p>
<p><b>return TRUE;</b></p>
<p>}</p>
<p><b>BEGIN_MESSAGE_MAP( CDocViewlApp, CWinApp )</b></p>
<p><b>ON_COMMAND( ID_FILE_OPEN, CWinApp::OnFileOpen ) END_MESSAGE_MAP()</b></p>
<p><b>CDocViewlApp theApp;</b></p>
<p>Если мы запустим нашу программу на выполнение (внутри сре­ды разработки) и откроем какой-нибудь файл, то увидим, что на отладочном мониторе появилось сообщение о размере открытого файла. Любознательный читатель может проверить, произойдет ли считывание содержимого файла в буфер. Я абсолютно уверен, что в обычных условиях файл будет считан в буфер без каких-либо проблем.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/prilozheniya/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-serialize-3.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Струк&#173;тура типа CCreateContext</title>
		<link>http://www.programmfc.ru/uncategorized/%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d1%83%d1%80%d0%b0-%d1%82%d0%b8%d0%bf%d0%b0-ccreatecontext.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d1%83%d1%80%d0%b0-%d1%82%d0%b8%d0%bf%d0%b0-ccreatecontext.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:45:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CDocTemplate]]></category>
		<category><![CDATA[CMDIChildWnd]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d1%83%d1%80%d0%b0-%d1%82%d0%b8%d0%bf%d0%b0-ccreatecontext.html</guid>
		<description><![CDATA[Пока мы видим, что сразу после проверки того, что указатель на документ и идентификатор ресурсов ненулевые, создается струк­тура типа CCreateContext. Описание этой структуры находится в файле afxext.h:
struct CCreateContext // Creation information structure // All fields are optional and may be NULL
{
// for creating.,new views CRuntimeClass* m_pNewViewClass;
// runtime class of view to create or NULL CDocument* [...]]]></description>
			<content:encoded><![CDATA[<p>Пока мы видим, что сразу после проверки того, что указатель на документ и идентификатор ресурсов ненулевые, создается струк­тура типа CCreateContext. Описание этой структуры находится в файле afxext.h:</p>
<p><b>struct CCreateContext // Creation information structure // All fields are optional and may be NULL</b></p>
<p>{</p>
<p><b>// for creating.,new views CRuntimeClass* m_pNewViewClass;</b></p>
<p><b>// runtime class of view to create or NULL CDocument* m_pCurrentDoc;</b></p>
<p><b>// for creating MDI children (CMDIChildWnd::LoadFrame) CDocTemplate* m_pNewDocTemplate;</b></p>
<p><b>// for sharing view/frame state from the // original view/frame</b></p>
<p><b>CView* m_pLastView; CFrameWnd* m_pCurrentFrame;</b></p>
<p><b>// Implementation CCreateContext();</b></p>
<p>};</p>
<p>В поля этой структуры записываются указатели на документ, шаб­лон документа, а также указатели на фрейм, который будет создан, и на окно представления документа. Обратим внимание на этот факт, дело в том, что эти данные будут использованы в дальнейшем.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d1%83%d1%80%d0%b0-%d1%82%d0%b8%d0%bf%d0%b0-ccreatecontext.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Текст метода CDocView1App::lnitlnstance</title>
		<link>http://www.programmfc.ru/uncategorized/%d1%82%d0%b5%d0%ba%d1%81%d1%82-%d0%bc%d0%b5%d1%82%d0%be%d0%b4%d0%b0-cdocview1applnitlnstance.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d1%82%d0%b5%d0%ba%d1%81%d1%82-%d0%bc%d0%b5%d1%82%d0%be%d0%b4%d0%b0-cdocview1applnitlnstance.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:45:32 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CDocTemplate]]></category>
		<category><![CDATA[CMDIChildWnd]]></category>
		<category><![CDATA[DoPromptFileName]]></category>
		<category><![CDATA[lnitlnstance]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d1%82%d0%b5%d0%ba%d1%81%d1%82-%d0%bc%d0%b5%d1%82%d0%be%d0%b4%d0%b0-cdocview1applnitlnstance.html</guid>
		<description><![CDATA[На что необходимо обратить внимание? К этому моменту мы еще не представляем характера взаимодействия между докумен­том и фреймом. Поэтому просто предположим, что каким-то обра­зом наш документ будет отображаться в рамках фрейма. Давайте поразмыслим, уважаемый читатель. Мы пишем программу, кото­рая будет работать с многодокументным интерфейсом. Наша про­грамма должна отображать данные в одном из дочерних окон мно­годокументного [...]]]></description>
			<content:encoded><![CDATA[<p>На что необходимо обратить внимание? К этому моменту мы еще не представляем характера взаимодействия между докумен­том и фреймом. Поэтому просто предположим, что каким-то обра­зом наш документ будет отображаться в рамках фрейма. Давайте поразмыслим, уважаемый читатель. Мы пишем программу, кото­рая будет работать с многодокументным интерфейсом. Наша про­грамма должна отображать данные в одном из дочерних окон мно­годокументного интерфейса. Следовательно, логично будет в ка­честве фрейма использовать окно класса CMDIChildWnd. Давайте так и поступим, уважаемый читатель. Итак, ниже я привожу текст метода CDocView1App::lnitlnstance() нашей программы:</p>
<p><b>BOOL CDocViewlApp::Initlnstance () {</b></p>
<p><b>#ifdef _AFXDLL</b></p>
<p><b>Enable3dControls(); #else</b></p>
<p><b>Enable3dControlsStatic(); #endif</b></p>
<p><b>LoadStdProfileSettings(); CDocTemplate* pDocTemplate;</b></p>
<p><b>pDocTemplate = new CMultiDocTemplate( IDR_DOCUMENT,</b></p>
<p><b>RUNTIME_CLASS( CDoc ),<sup>% </sup>RUNTIME_CLASS( CMDIChildWnd ),</b></p>
<p><b>NULL );</b></p>
<p><b>AddDocTemplate( pDocTemplate ); CMainFrame* pMainFrame = new CMainFrame; pMainFrame-&gt;LoadFrame( IDR_RESOURCE ); m_pMainWnd = pMainFrame; pMainFrame-&gt;ShowWindow(m_nCmdShow ); pMainFrame-&gt;UpdateWindow();</b></p>
<p><b>return TRUE;</b></p>
<p>}</p>
<p>создается фрейм этого документа. Нетрудно догадаться, что соз­дание фрейма происходит при вызове метода CDocTemplate:: CreateNewFrame():</p>
<p><b>CFrameWnd* CDocTemplate::CreateNewFrame(CDocument* pDoc,</b></p>
<p><b>CFrameWnd* pother)</b></p>
<p>{</p>
<p><b>if (pDoc != NULL)</b></p>
<p><b>ASSERT_VALID(pDoc); // create a frame wired to the specified document</b></p>
<p><b>ASSERT(m_nIDResource != 0); // must have a resource. ID</b></p>
<p><b>// to load from</b></p>
<p><b>CCreateContext context;</b></p>
<p><b>context,m_pCurrentFrame = pother;</b></p>
<p><b>context.m_pCurrentDoc = pDoc;</b></p>
<p><b>context,m_pNewViewClass = m_pViewClass;</b></p>
<p><b>context.m_pNewDocTemplate = this;</b></p>
<p><b>if (m_pFrameClass == NULL) &#8216; {</b></p>
<p><b>TRACEO(&quot;Error: you must override</b></p>
<p><b>CDocTemplate::CreateNewFrame.\n&quot;) ;</b></p>
<p><b>ASSERT(FALSE); return NULL;</b></p>
<p>}</p>
<p><b>CFrameWnd* pFrame =</b></p>
<p><b>(CFrameWnd*)m_pFrameClass-&gt;CreateObject() ; if (pFrame == NULL) {</b></p>
<p><b>TRACE1(&quot;Warning: Dynamic create of frame %hs failed.\n&quot;,</b></p>
<p><b>m_pFrameClass-&gt;m_lpszClassName);</b></p>
<p><b>return NULL;</b></p>
<p>}</p>
<p><b>ASSERT_KINDOF(CFrameWnd, pFrame);</b></p>
<p><b>if (context.m_pNewViewClass == NULL)</b></p>
<p><b>TRACEO(&quot;Warning: creating frame with no default</b></p>
<p><b>view.\n&quot;);</b></p>
<p><b>// create new from resource</b></p>
<p><b>if (!pFrame-&gt;LoadFrame(m_nIDResource,</b></p>
<p><b>WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, // default frame styles</b></p>
<p><b>NULL, &amp;context))</b></p>
<p>{</p>
<p><b>TRACEO(&quot;Warning: CDocTemplate couldn&#8217;t create</b></p>
<p><b>a frame.\n&quot;); // frame will be deleted in PostNcDestroy cleanup return NULL;</b></p>
<p>}</p>
<p><b>// it worked ! return pFrame;</b></p>
<p>}</p>
<p>Мне бы хотелось обратить внимание читателя на то, что в каче­стве аргументов методу передаются указатель на документ и ука­затель (пока нулевой), в который будет записан указатель на соз­данный фрейм. Мы уже однажды (при рассмотрении метода DoPromptFileName()) замечали, что методу передаются указате­ли, которые с первого взгляда совершенно не нужны для работы метода. Кажется, здесь тот же случай &#8211; ну зачем, скажите, пожа­луйста, при создании фрейма знать указатель на документ? То, что буквально в первых строках метода осуществляется проверка того, не равен ли идентификатор ресурсов нулю, говорит о том, что, вероятнее всего, при создании фрейма опять будут использо­ваться ресурсы. Но, как говорится, поживем &#8211; увидим.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d1%82%d0%b5%d0%ba%d1%81%d1%82-%d0%bc%d0%b5%d1%82%d0%be%d0%b4%d0%b0-cdocview1applnitlnstance.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Промежуточные итоги</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%bf%d1%80%d0%be%d0%bc%d0%b5%d0%b6%d1%83%d1%82%d0%be%d1%87%d0%bd%d1%8b%d0%b5-%d0%b8%d1%82%d0%be%d0%b3%d0%b8.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%bf%d1%80%d0%be%d0%bc%d0%b5%d0%b6%d1%83%d1%82%d0%be%d1%87%d0%bd%d1%8b%d0%b5-%d0%b8%d1%82%d0%be%d0%b3%d0%b8.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:44:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CDocTemplate]]></category>
		<category><![CDATA[OpenDocumentFile]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%bf%d1%80%d0%be%d0%bc%d0%b5%d0%b6%d1%83%d1%82%d0%be%d1%87%d0%bd%d1%8b%d0%b5-%d0%b8%d1%82%d0%be%d0%b3%d0%b8.html</guid>
		<description><![CDATA[Итак, подведем промежуточные итоги. К настоящему времени мы выяснили, что необходимо сделать для того, чтобы MFC нача­ла работать с приложением в соответствии с требованиями архи­тектуры «документ/представление», выяснили, как определить, какой файл мы будем открывать, создали пустой документ. Однако обратите внимание, что до настоящего момента мы не можем ни­коим образом увидеть тот документ, который мы только [...]]]></description>
			<content:encoded><![CDATA[<p>Итак, подведем промежуточные итоги. К настоящему времени мы выяснили, что необходимо сделать для того, чтобы MFC нача­ла работать с приложением в соответствии с требованиями архи­тектуры «документ/представление», выяснили, как определить, какой файл мы будем открывать, создали пустой документ. Однако обратите внимание, что до настоящего момента мы не можем ни­коим образом увидеть тот документ, который мы только что созда­ли. Нам просто негде визуализировать наш документ! Для того что­бы увидеть результаты нашей работы, нам необходимо срочно соз­дать окно представления. Следовательно, нам необходимо вернуть­ся к коду метода CMultiDocTemplate::OpenDocumentFile() и посмот­реть, что же происходит после того, как новый документ был соз­дан, каким образом создается окно, в котором будет отображаться содержимое нашего документа.</p>
<p>Вернувшись, мы видим, что после создания нового документа программа пытается создать фрейм для нашего документа. Кажет­ся, нас сейчас ждет очередная неприятность&#8230; Так и есть. Мы полу­чили очередное сообщение об ошибке.</p>
<p>Посмотрев внимательнее, мы заметим, что попутно нам было выдано и отладочное сообщение о необходимости переопределить метод CDocTemplate::CreateNewFrame «Еггог: you must override CDocTemplate::CreateNewFrame.». Сейчас, наверное, уже нет не­обходимости разбираться, что произошло. Наверное, читатель уже догадался. Да, дело именно в том, что при определении шаблона документа мы указатель на информацию времени выполнения фрейма нашего документа оставили равным NULL! Что ж, придет­ся внести еще небольшие изменения в нашу программу.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%bf%d1%80%d0%be%d0%bc%d0%b5%d0%b6%d1%83%d1%82%d0%be%d1%87%d0%bd%d1%8b%d0%b5-%d0%b8%d1%82%d0%be%d0%b3%d0%b8.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Изменения в метод Initlnstance</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%b8%d0%b7%d0%bc%d0%b5%d0%bd%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b2-%d0%bc%d0%b5%d1%82%d0%be%d0%b4-initlnstance.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%b8%d0%b7%d0%bc%d0%b5%d0%bd%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b2-%d0%bc%d0%b5%d1%82%d0%be%d0%b4-initlnstance.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:44:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CDocTemplate]]></category>
		<category><![CDATA[CWinApp]]></category>
		<category><![CDATA[OnFileOpen]]></category>
		<category><![CDATA[OpenDocumentFile]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%b8%d0%b7%d0%bc%d0%b5%d0%bd%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b2-%d0%bc%d0%b5%d1%82%d0%be%d0%b4-initlnstance.html</guid>
		<description><![CDATA[Вносим необходимые изменения в метод InitlnstanceQ нашего приложения:
BOOL CDocViewlApp::Initlnstance() {
fifdef _AFXDLL
Enable3dControls(); #else
Enable3dControlsStatic(); #endif
.»
LoadStdProfileSettings(); CDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate( IDR_DOCUMENT,
RUNTIME_CLASS(CDoc), NULL, NULL ); AddDocTemplate( pDocTemplate ); CMainFrame* pMainFrame = new CMainFrame; pMainFrame-&#62;LoadFrame( IDR_RESOURCE ); m_pMainWnd = pMainFrame; pMainFrame-&#62;ShowWindow(m_nCmdShow );
pMainFrame-&#62;UpdateWindow(); return TRUE;
}
Снова компилируем программу, запускаем на выполнение. ..И б-лагополучно минуем то место, на котором в прошлый раз [...]]]></description>
			<content:encoded><![CDATA[<p>Вносим необходимые изменения в метод InitlnstanceQ нашего приложения:</p>
<p><b>BOOL CDocViewlApp::Initlnstance() {</b></p>
<p><b>fifdef _AFXDLL</b></p>
<p><b>Enable3dControls(); #else</b></p>
<p><b>Enable3dControlsStatic(); #endif</b></p>
<p><b>.»</b></p>
<p><b>LoadStdProfileSettings(); CDocTemplate* pDocTemplate;</b></p>
<p><b>pDocTemplate = new CMultiDocTemplate( IDR_DOCUMENT,</b></p>
<p><b>RUNTIME_CLASS(CDoc), NULL, NULL ); AddDocTemplate( pDocTemplate ); CMainFrame* pMainFrame = new CMainFrame; pMainFrame-&gt;LoadFrame( IDR_RESOURCE ); m_pMainWnd = pMainFrame; pMainFrame-&gt;ShowWindow(m_nCmdShow );</b></p>
<p><b>pMainFrame-&gt;UpdateWindow(); return TRUE;</b></p>
<p>}</p>
<p>Снова компилируем программу, запускаем на выполнение. ..И б-лагополучно минуем то место, на котором в прошлый раз у нас было выдано сообщение об ошибке. Однако нам необходимо по­нять, что происходит при создании документа, т. е. что происходит при работе метода CDocTemplate::CreateNewDocument().</p>
<p><b>CObject* CRuntimeClass::CreateObject() {</b></p>
<p><b>if (m_pfnCreateObject == NULL) {</b></p>
<p><b>TRACE(_T(&quot;Error: Trying to create object which is not &quot;) _T(&quot;DECLARE_DYNCREATE \nor DECLARE_SERIAL: %hs.\n&quot;), m_lpszClassName); return NULL;</b></p>
<p>}</p>
<p><b>CObject* pObject = NULL;</b></p>
<p><b>TRY</b></p>
<p>{</p>
<p><b>pObject = (*m_pfnCreateObject) () ;</b></p>
<p>}</p>
<p><b>END_TRY</b></p>
<p><b>return pObject;</b>(CWJnApp::OnFJIeOpen ) Во-вторых, при помощи метода    <br /><s>S</s> <i>. </i>CMultiDocTemplate::AddDocu-</p>
<p><u>Ц</u><u>CDocManager::OnFileOpen J</u> <sub>men</sub>t() (файл docmulti.cpp)</p>
<p>UcWinAppriOpenDocumentFile) <sup>только</sup> <sup>что</sup> созданный</p>
<p><s>N</s> <i><u><sup>J</sup></u></i> документ добавля-</p>
<p>L-<u>[ CDocManager::OpenDocumentFile ]</u> ется в список</p>
<p>CMultiDocTemplate::OpenDocumentFjle] Документов   <br />— <u>—&#8217;</u> шаблона:</p>
<p>CDocTemplate::CreateNewDocum^n?)</p>
<p><u>^CMultiDocTemplate::AddDocument]</u></p>
<p><b>void CMultiDocTemplate::AddDocument(CDocument* pDoc) {</b></p>
<p><b>ASSERT_VALID(pDoc);</b></p>
<p><b>CDocTemplate::AddDocument(pDoc);</b></p>
<p><b>ASSERT(m_docList.Find(pDoc, NULL) == NULL);</b></p>
<p><b>// must not be in list</b></p>
<p><b>m_docList.AddTail(pDoc);</b></p>
<p><b>}</b></p>
<p>CWinA<sub>PP</sub>::OnFileOpen <i>) </i><sup>A</sup> <sup>этот</sup> <i><sup>мет0</sup>* </i>Фактически представ-    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; <sup>J</sup><i> </i>ляет собой вызов одноименного</p>
<p><i>ч</i></p>
<p><u>CDocManager::OnFileOpen ]</u> метода базового класса</p>
<p><u>CWinApp::OpenPocumentFilQ</u> <sup>(</sup><sup>фаЙЛ</sup> <sup>doctem</sup>P<sup>lc</sup>PP)<sup>:</sup></p>
<p>^-<u>{CDocManager^OpenDocumentFile&quot;)</u></p>
<p><b>L</b><u>^CMultiDocTemplate::OpenDocumentFile] </u>CDocTemplate::CreateNewDocument] CMultiDocTemplate::AddDocument] L^CDocTemplate::AddDocument ]</p>
<p><b>void CDocTemplate::AddDocument(CDocument* pDoc) {</b></p>
<p><b>ASSERT_VALID(pDoc);</b></p>
<p><b>ASSERT(pDoc-&gt;m_pDocTemplate == NULL); // no template attached yet pDoc-&gt;m_pDocTemplate = this;</b></p>
<p>Исходя из текстов этих методов, можно заметить, что не только у шаблона документа есть список документов, открытых на основе данного шаблона, но и у каждого документа есть указатель на тот шаблон, при помощи которого он был открыт. Этакая своеобраз­ная обратная связь!</p>
<p>Итак, что происходит при создании нового документа, мы выяс­нили. Фактически создается пустой документ, на него делается ссылка в шаблоне, а документ, в свою очередь, запоминает указа­тель на шаблон.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%b8%d0%b7%d0%bc%d0%b5%d0%bd%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b2-%d0%bc%d0%b5%d1%82%d0%be%d0%b4-initlnstance.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Метод CDocManager::OpenDocumentFile</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cdocmanageropendocumentfile.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cdocmanageropendocumentfile.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:44:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CDocTemplate]]></category>
		<category><![CDATA[OpenDocumentFile]]></category>
		<category><![CDATA[Метод CDocManager]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cdocmanageropendocumentfile.html</guid>
		<description><![CDATA[Итак, метод CDocTemplate::MatchDocType() используется для того, чтобы проверить, совпадает ли расширение открываемого файла с указанным в шаблоне документа. Зафиксировав этот факт, мы можем вернуться к методу CDocManager::OpenDocumentFile().
CDocument* CMultiDocTemplate::OpenDocumentFile(
LPCTSTR IpszPathName, BOOL bMakeVisible)
{
CDocument* pDocument = CreateNewDocument();
if (pDocument == NULL)
{
TRACEO(&#34;CDocTemplate::CreateNewDocument
returned NULL.\n&#34;); AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC); return NULL;
}
ASSERT_VALID(pDocument);
BOOL bAutoDelete = pDocument-&#62;m_bAutoDelete; pDocument-&#62;m_bAutoDelete = FALSE;
// don&#8217;t destroy if something goes wrong CFrameWnd* pFrame [...]]]></description>
			<content:encoded><![CDATA[<p>Итак, метод CDocTemplate::MatchDocType() используется для того, чтобы проверить, совпадает ли расширение открываемого файла с указанным в шаблоне документа. Зафиксировав этот факт, мы можем вернуться к методу CDocManager::OpenDocumentFile().</p>
<p><b>CDocument* CMultiDocTemplate::OpenDocumentFile(</b></p>
<p><b>LPCTSTR IpszPathName, BOOL bMakeVisible)</b></p>
<p>{</p>
<p><b>CDocument* pDocument = CreateNewDocument();</b></p>
<p><b>if (pDocument == NULL)</b></p>
<p>{</p>
<p><b>TRACEO(&quot;CDocTemplate::CreateNewDocument</b></p>
<p><b>returned NULL.\n&quot;); AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC); return NULL;</b></p>
<p>}</p>
<p><b>ASSERT_VALID(pDocument);</b></p>
<p><b>BOOL bAutoDelete = pDocument-&gt;m_bAutoDelete; pDocument-&gt;m_bAutoDelete = FALSE;</b></p>
<p><b>// don&#8217;t destroy if something goes wrong CFrameWnd* pFrame = CreateNewFrame(pDocument, NULL); pDocument-&gt;m_bAutoDelete = bAutoDelete; if (pFrame == NULL)</b></p>
<p><b>{</b></p>
<p><b>Af xMessageBox (AFX_IDP_FAILED_TO_CREATE_DOC) ;</b></p>
<p><b>delete pDocument;</b> <b>// explicit delete on error</b></p>
<p><b>return NULL;</b></p>
<p><b>}</b></p>
<p><b>ASSERT_VALID(pFrame);</b></p>
<p><b>if (IpszPathName == NULL) {</b></p>
<p><b>// create a new document &#8211; with default document name SetDefaultTitle(pDocument);</b></p>
<p><b>// avoid creating temporary compound file when // starting up invisible</b></p>
<p><b>if (IbMakeVisible)</b></p>
<p><b>pDocument-&gt;m_bEmbedded = TRUE;</b></p>
<p><b>if (!pDocument-&gt;OnNewDocument ())</b></p>
<p><b>{</b></p>
<p><b>// user has be alerted to what failed in OnNewDocument</b></p>
<p><b>TRACEO(&quot;CDocument::OnNewDocument returned FALSE An&quot;); pFrame-&gt;DestroyWindow(); return NULL;</b></p>
<p>}</p>
<p><b>// it worked, now bump untitled count m_nUntitledCount++;</b></p>
<p>}</p>
<p><b>else {</b></p>
<p><b>// open an existing document CWaitCursor wait;</b></p>
<p><b>if (!pDocument-&gt;OnOpenDocument(IpszPathName)) {</b></p>
<p><b>// user has be alerted to what failed in OnOpenDocument TRACEO(&quot;CDocument::OnOpenDocument returned FALSE An&quot;); pFrame-&gt;DestroyWindow (); return NULL;</b></p>
<p>}</p>
<p><b>pDocument-&gt;SetPathName(IpszPathName);</b></p>
<p>}</p>
<p><b>InitialUpdateFrame(pFrame, pDocument, bMakeVisible); return pDocument;</b></p>
<p>В качестве единственного аргумента используется имя откры­ваемого файла.</p>
<p>Во-первых, мы получили отладочное сообщение о -том, что нам необходимо переопределить метод CreateNewDocu-ment(): «Еггог: you must override CDocTemplate::CreateNew-Document.» Во-вторых, мы получаем сообщение об ошибке.</p>
<p>Что же могло случиться? Заглянем в исходный код метода CDocTemplate::CreateNewDocument():</p>
<p><b>CDocument* CDocTemplate::CreateNewDocument() {</b></p>
<p><b>// default implementation constructs one from CRuntimeClass if (m_pDocClass == NULL) {</b></p>
<p><b>TRACEO(&quot;Error: you must override</b></p>
<p><b>CDocTemplate::CreateNewDocument.\n&quot;) ;</b></p>
<p><b>ASSERT(FALSE); return NULL;</b></p>
<p><b>}</b></p>
<p><b>CDocument* pDocument =</b></p>
<p><b>(CDocument*)m_pDocClass-&gt;CreateObject() ; if (pDocument == NULL) {</b></p>
<p><b>TRACE1(&quot;Warning: Dynamic create of document type</b></p>
<p><b>%hs failed.\n&quot;, m_pDocClass-&gt;m_lpszClassName) ; return NULL;</b></p>
<p><b>}</b></p>
<p><b>ASSERT_KINDOF(CDocument, pDocument); AddDocument(pDocument); return pDocument;</b></p>
<p>Конечно! Мы же в нашей программе оставили указатель на ин­формацию времени исполнения объекта класса CDocument, равную NULL! А здесь первым делом осуществляется проверка, не равен ли нулю этот указатель! Что ж, делать нечего. Для того чтобы мы могли хоть немного продвинуться вперед, изменим нашу программу, доба­вив в начало ее описание класса нашего документа:</p>
<p><b>class CDoc : public CDocument {</b></p>
<p><b>DECLARE_DYNCREATE( CDoc ) public:</b></p>
<p><b>CDoc () ; virtual -CDoc(); &gt;;</b></p>
<p><b>IMPLEMENT_DYNCREATE( CDoc, CDocument )</b></p>
<p><b>CDoc::CDoc()</b></p>
<p>{</p>
<p>}</p>
<p><b>CDoc::~CDoc()</b></p>
<p>{</p>
<p>}</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cdocmanageropendocumentfile.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Функция СDocTemplate::MatchDocType</title>
		<link>http://www.programmfc.ru/uncategorized/%d1%84%d1%83%d0%bd%d0%ba%d1%86%d0%b8%d1%8f-%d1%81doctemplatematchdoctype.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d1%84%d1%83%d0%bd%d0%ba%d1%86%d0%b8%d1%8f-%d1%81doctemplatematchdoctype.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:43:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CDocTemplate]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d1%84%d1%83%d0%bd%d0%ba%d1%86%d0%b8%d1%8f-%d1%81doctemplatematchdoctype.html</guid>
		<description><![CDATA[Невооруженным глазом видно, что в начале функции &#8216;CDocTemplate::MatchDocType] производятся всевоз можные подготовительные действия, а также проверяется, не является ли выбран­ный нами файл ссылкой на другой файл. С точки зрения архитек­туры «документ/представление» все это не очень интересно. Ин­тересное начинается с момента начала перебора списка шабло­нов. Обратите внимание, уважаемый читатель, на то, что для каж­дого шаблона в [...]]]></description>
			<content:encoded><![CDATA[<p>Невооруженным глазом видно, что в начале функции &#8216;CDocTemplate::MatchDocType] производятся всевоз можные подготовительные действия, а также проверяется, не является ли выбран­ный нами файл ссылкой на другой файл. С точки зрения архитек­туры «документ/представление» все это не очень интересно. Ин­тересное начинается с момента начала перебора списка шабло­нов. Обратите внимание, уважаемый читатель, на то, что для каж­дого шаблона в списке шаблонов вызывается метод CDocTemplate::MatchDocType(). Этот метод определяет, насколько расширение открываемого файла соответствует указанному в шаб­лонах. В качестве аргументов этому методу передаются имя фай­ла, который мы хотим открыть, и переменная типа &quot;указатель на документ&quot;, которая равна NULL. Ниже я привожу исходный текст этого метода. Его можно найти в файле docmgr.cpp:</p>
<p><b>CDocTemplate:Confidence</b></p>
<p><b>CDocTemplate::MatchDocType(LPCTSTR IpszPathName,</b></p>
<p><b>CDocument*&amp; rpDocMatch)</b></p>
<p>{</p>
<p><b>ASSERT(IpszPathName != NULL); rpDocMatch = NULL;</b></p>
<p><b>// go through all documents</b></p>
<p><b>POSITION pos = GetFirstDocPosition();</b></p>
<p><b>while (pos != NULL)</b></p>
<p>{</p>
<p><b>CDocument* pDoc = GetNextDoc(pos);</b></p>
<p><b>if (AfxComparePath(pDoc-&gt;GetPathName(), IpszPathName)) {</b></p>
<p><b>// already open</b></p>
<p><b>rpDocMatch = pDoc; return yesAlreadyOpen;</b></p>
<p>}</p>
<p>}</p>
<p><b>// see if it matches our default suffix CString strFilterExt; if (GetDocString(strFilterExt,</b></p>
<p><b>CDocTemplate::filterExt) &amp;&amp; !strFilterExt.IsEmpty())</b></p>
<p>{</p>
<p><b>// see if extension matches</b></p>
<p><b>ASSERT(strFilterExt[0] == <sup>4</sup>.&#8217;);</b></p>
<p><b>LPCTSTR IpszDot = _tcsrchr(IpszPathName, &#8216;.&#8217;);</b></p>
<p><b>if (IpszDot != NULL &amp;&amp;</b></p>
<p><b>lstrcmpi(IpszDot, strFilterExt) == 0) return yesAttemptNative; // extension matches,</b></p>
<p><b>// looks like ours</b></p>
<p>}</p>
<p><b>// otherwise we will guess it may work return yesAttemptForeign;</b></p>
<p>}</p>
<p>Обратите внимание на следующие обстоятельства. Если файл с именем, совпадающим с первым аргументом метода, уже открыт в соответствии с текущим шаблоном, то указатель на открытый документ сохраняется в указателе, переданном в качестве второго документа. Другими словами, создается новая ССЫЛКА на откры­тый ранее документ, при этом вторая копия документа не создает­ся. В этом случае метод возвращает значение yesAlreadyOpen.</p>
<p>Если файл ранее не был открыт в соответствии с текущим шабло­ном, то выбирается подстрока, содержащая расширение файла (помните, читатель, описание метода CDocTemplate::GetDocString()?), из переданной шаблону строки ресурсов. Если эта подстрока сов­падает с расширением открываемого файла, то метод возвращает значение yesAttemptNative. Указатель на документ, переданный в качестве второго аргумента, при этом не изменяется и остается равным NULL.</p>
<p>И наконец, если расширение открываемого файла не соответ­ствует расширению, записанному в шаблоне, то метод возвраща­ет значение yesAttemptForeign. При этом указатель, переданный в качестве второго аргумента, также остается равным NULL.</p>
<p>Любознательный читатель, вероятно, тут же задаст мне вопрос. Как же так, ведь в перечислении CDocTemplate: Confidence исполь­зуются еще три значения, noAttempt, maybeAttemptForeign и may-beAttemptNative? А в каких случаях возвращаются эти значения? Здесь я могу только догадываться. Возможно, программисту по­требуется иногда делать предположение о том, что открываемый файл соответствует текущему шаблону вне зависимости от рас­ширения. Например, если шаблон файла предусматривает расши­рение «arj», а пользователь выбрал файл с расширением «aDD» (где «DD» означает две любые цифры), то, наверное, программист сможет, переопределив метод CDocTemplate::MatchDocType(), вер­нуть значение maybeAttemptNative. С другой стороны, если поль­зователь в этом случае выбрал файл с расширением, скажем, «txt», то программист может сделать предположение о том, что откры­ваемый файл не соответствует шаблону, и вернуть значение тау-beAttemptForeign. Наверное, возможны еще какие-то случае, когда программисту потребуется использовать значение noAttempt.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d1%84%d1%83%d0%bd%d0%ba%d1%86%d0%b8%d1%8f-%d1%81doctemplatematchdoctype.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
