<?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; OpenDocumentFile</title>
	<atom:link href="http://www.programmfc.ru/tag/opendocumentfile/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>Класс 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>Метод CMDIChildWnd::LoadFrame</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cmdichildwndloadframe.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cmdichildwndloadframe.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:48:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CMDIChildWnd]]></category>
		<category><![CDATA[OpenDocumentFile]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cmdichildwndloadframe.html</guid>
		<description><![CDATA[Я надеюсь, что читатель помнит о том, что пока при создании шаблона нашего документа указатель на информацию времени исполнения класса окна представления равен нулю. Следова­тельно, пока мы можем на некоторое время оставить вопрос о создании окна представления и вернуться в метод CMDIChildWnd::LoadFrame().
Из текста метода CMDIChildWnd::LoadFrame() кроме сказанно­го выше становится понятным и назначение начальной подстроки строкового [...]]]></description>
			<content:encoded><![CDATA[<p>Я надеюсь, что читатель помнит о том, что пока при создании шаблона нашего документа указатель на информацию времени исполнения класса окна представления равен нулю. Следова­тельно, пока мы можем на некоторое время оставить вопрос о создании окна представления и вернуться в метод CMDIChildWnd::LoadFrame().</p>
<p>Из текста метода CMDIChildWnd::LoadFrame() кроме сказанно­го выше становится понятным и назначение начальной подстроки строкового ресурса &#8211; эта подстрока определяет заголовок созда­ваемого окна фрейма.</p>
<p>Теперь, когда мы знаем все о том, как происходит создание нового документа и создание нового фрейма, нам придется вернуться к методу ь CMultiDocTemplate::OpenDocumentFile() и продолжить его рассмотрение на имя откры­ваемого файла. Текст этого метода, приведенный ниже, можно най­ти в файле doccore.cpp:</p>
<p><b>BOOL CDocument::OnOpenDocument(LPCTSTR IpszPathName) {</b></p>
<p><b>if (IsModifiedO )</b></p>
<p><b>TRACEO(&quot;Warning: OnOpenDocument replaces an unsaved</b></p>
<p><b>document.\n&quot;) ;</b></p>
<p><b>CFileException fe;</b></p>
<p><b>CFile* pFile = GetFile(IpszPathName,</b></p>
<p><b>CFile::modeRead|CFile::shareDenyWrite,</b></p>
<p><b>&amp;fe) ; if (pFile == NULL) {</b></p>
<p><b>ReportSaveLoadException(IpszPathName,</b></p>
<p><b>return FALSE;</b></p>
<p><b>DeleteContents ();</b></p>
<p><b>&amp;fe, FALSE,</b></p>
<p><b>AFX_IDP FAILED TO_OPEN_DOC);</b></p>
<p><b>SetModifiedFlag(); // dirty during de-serialize</b></p>
<p><b>CArchive loadArchive(pFile,</b></p>
<p><b>CArchive::load | CArchive:rbNoFlushOnDelete); loadArchive.m_pDocument = this; loadArchive.m_bForceFlat = FALSE; TRY {</b></p>
<p><b>CWaitCursor wait;</b></p>
<p><b>if (pFile-&gt;GetLength() != </b>0)</p>
<p><b>Serialize(loadArchive);</b> <b>// load me</b></p>
<p><b>loadArchive.Close(); ReleaseFile(pFile, FALSE);</b></p>
<p>}</p>
<p><b>CATCH_ALL(e) {</b></p>
<p><b>ReleaseFile(pFile, TRUE);</b></p>
<p><b>DeleteContents(); // remove failed contents</b></p>
<p><b>TRY {</b></p>
<p><b>ReportSaveLoadException(IpszPathName, e, FALSE,</b></p>
<p><b>AFX_IDP_FAILED_TO_OPEN_DOC);</b></p>
<p>}</p>
<p><b>END_TRY</b></p>
<p><b>DELETE_EXCEPTION(e); return FALSE;</b></p>
<p>}</p>
<p><b>END_CATCH_ALL</b></p>
<p><b>SetModifiedFlag(FALSE);</b> <b>// start off with unmodified</b></p>
<p><b>return TRUE;</b></p>
<p>}</p>
<p>Я прошу читателя уделить этому методу ОСОБОЕ внимание. Немного опережая события, скажу, что именно здесь мы уви­дим, в какой момент из файла получается документ, какой ме­тод необходимо переопределить, чтобы всю рутинную работу возложить на MFC.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cmdichildwndloadframe.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>Стандартное диалоговое окно для открытия файлов</title>
		<link>http://www.programmfc.ru/uncategorized/%d1%81%d1%82%d0%b0%d0%bd%d0%b4%d0%b0%d1%80%d1%82%d0%bd%d0%be%d0%b5-%d0%b4%d0%b8%d0%b0%d0%bb%d0%be%d0%b3%d0%be%d0%b2%d0%be%d0%b5-%d0%be%d0%ba%d0%bd%d0%be-%d0%b4%d0%bb%d1%8f-%d0%be%d1%82%d0%ba%d1%80.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d1%81%d1%82%d0%b0%d0%bd%d0%b4%d0%b0%d1%80%d1%82%d0%bd%d0%be%d0%b5-%d0%b4%d0%b8%d0%b0%d0%bb%d0%be%d0%b3%d0%be%d0%b2%d0%be%d0%b5-%d0%be%d0%ba%d0%bd%d0%be-%d0%b4%d0%bb%d1%8f-%d0%be%d1%82%d0%ba%d1%80.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:42:51 +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/%d1%81%d1%82%d0%b0%d0%bd%d0%b4%d0%b0%d1%80%d1%82%d0%bd%d0%be%d0%b5-%d0%b4%d0%b8%d0%b0%d0%bb%d0%be%d0%b3%d0%be%d0%b2%d0%be%d0%b5-%d0%be%d0%ba%d0%bd%d0%be-%d0%b4%d0%bb%d1%8f-%d0%be%d1%82%d0%ba%d1%80.html</guid>
		<description><![CDATA[Итак, мы прошли уже достаточно большой путь. Самое главное, поняли, что необходимо делать в начале работы в рамках архитек­туры «документ/представление». Мы разобрались, какие ресурсы нам необходимо подготовить, создали шаблон документа, подго­товили к отображению окно выбора файла. Теперь нам необходи­мо выяснить, что происходит в ходе открытия файла.
CDocument* CDocManager::OpenDocumentFile(LPCTSTR IpszFileName) {
// find the highest confidence
POSITION pos = [...]]]></description>
			<content:encoded><![CDATA[<p>Итак, мы прошли уже достаточно большой путь. Самое главное, поняли, что необходимо делать в начале работы в рамках архитек­туры «документ/представление». Мы разобрались, какие ресурсы нам необходимо подготовить, создали шаблон документа, подго­товили к отображению окно выбора файла. Теперь нам необходи­мо выяснить, что происходит в ходе открытия файла.</p>
<p><b>CDocument* CDocManager::OpenDocumentFile(LPCTSTR IpszFileName) {</b></p>
<p><b>// find the highest confidence</b></p>
<p><b>POSITION pos = m_templateList.GetHeadPosition (); CDocTemplate:Confidence bestMatch =</b></p>
<p><b>CDocTemplate::noAttempt;</b></p>
<p><b>CDocTemplate* pBestTemplate = NULL; CDocument* pOpenDocument = NULL;</b></p>
<p><b>TCHAR szPath[_MAX_PATH];</b></p>
<p><b>ASSERT(lstrlen(IpszFileName) &lt; _countof(szPath)) ;</b></p>
<p><b>TCHAR szTemp[_MAX_PATH];</b></p>
<p><b>if (IpszFileName[0] == </b><i><sup>y</sup></i><i>V&quot; )</i></p>
<p><b>++lpszFileName;     <br />lstrcpyn(szTemp, IpszFileName, _MAX_^ATH);      <br />LPTSTR IpszLast = _tcsrchr(szTemp,</b> <b>) ;</b></p>
<p><b>if (IpszLast != NULL)</b></p>
<p><b>*lpszLast = 0; AfxFullPath(szPath, szTemp); TCHAR szLinkName[_MAX_PATH]; if (AfxResolveShortcut(AfxGetMainWnd(),</b></p>
<p><b>szPath,</b></p>
<p><b>szLinkName,</b></p>
<p><b>_MAX_PATH)) lstrcpy(szPath, szLinkName);</b></p>
<p><b>while (pos != NULL) {</b></p>
<p><b>CDocTemplate* pTemplate =</b></p>
<p><b>(CDocTemplate*)m_templateList.GetNext(pos) ; ASSERT_KINDOF(CDocTemplate, pTemplate);</b></p>
<p><b>CDocTemplate::Confidence match;</b></p>
<p><b>ASSERT(pOpenDocument == NULL);</b></p>
<p><b>match = pTemplate-&gt;MatchDocType(szPath,</b></p>
<p><b>pOpenDocument);</b></p>
<p><b>if (match &gt; bestMatch) {</b></p>
<p><b>bestMatch = match; pBestTemplate = pTemplate;</b></p>
<p>}</p>
<p><b>if (match == CDocTemplate::yesAlreadyOpen)     <br />break;</b> <b>// stop here</b></p>
<p>}</p>
<p><b>if (pOpenDocument != NULL) {</b></p>
<p><b>POSITION pos = pOpenDocument-&gt;GetFirstViewPosition() ; if (pos != NULL)</b></p>
<p><b><i>{</i></b></p>
<p><b>CView* pView = pOpenDocument-&gt;GetNextView(pos);</b></p>
<p><b>// get first one</b></p>
<p><b>ASSERT_VALID(pView);</b></p>
<p><b>CFrameWnd* pFrame = pView-&gt;GetParentFrame(); if (pFrame != NULL)</b></p>
<p><b>pFrame-&gt;ActivateFrame(); else</b></p>
<p><b>TRACEO(&quot;Error: Can not find a frame for document</b></p>
<p><b>to activate.\n&quot;);</b></p>
<p><b>CFrameWnd* pAppFrame;</b></p>
<p><b>if (pFrame != (pAppFrame =</b></p>
<p><b>(CFrameWnd*)AfxGetApp()-&gt;m_pMainWnd))</b></p>
<p>{</p>
<p><b>ASSERT_KINDOF(CFrameWnd, pAppFrame); pAppFrame-&gt;ActivateFrame();</b></p>
<p>}</p>
<p>}</p>
<p><b>else {</b></p>
<p><b>TRACEO(&quot;Error: Can not find a view for document</b></p>
<p><b>to activate An&quot;) ;</b></p>
<p>}</p>
<p><b>return pOpenDocument;</b></p>
<p><b>if (pBestTemplate == NULL) {</b></p>
<p><b>AfxMessageBox(AFX_IDP_FAILED_TO_OPEN_DOC) . return NULL;</b></p>
<p><b>return pBestTemplate-&gt;OpenDocumentFile(szPath);</b></p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d1%81%d1%82%d0%b0%d0%bd%d0%b4%d0%b0%d1%80%d1%82%d0%bd%d0%be%d0%b5-%d0%b4%d0%b8%d0%b0%d0%bb%d0%be%d0%b3%d0%be%d0%b2%d0%be%d0%b5-%d0%be%d0%ba%d0%bd%d0%be-%d0%b4%d0%bb%d1%8f-%d0%be%d1%82%d0%ba%d1%80.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Метод CWinApp::OnFileOpen</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cwinapponfileopen.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cwinapponfileopen.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:40:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CWinApp]]></category>
		<category><![CDATA[DoPromptFileName]]></category>
		<category><![CDATA[OnFileOpen]]></category>
		<category><![CDATA[OpenDocumentFile]]></category>
		<category><![CDATA[Метод CWinApp]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cwinapponfileopen.html</guid>
		<description><![CDATA[Но взглянем на это окно повнимательнее. В основном меня все в нем устраивает, за исключением того, что мне предлагается осу­ществить выбор из всех имеющихся файлов. А если я хочу, чтобы мне был показаны только файлы с расширением «ехе» или «txt»? Могу ли я каким-нибудь образом изменить фильтр? А на этот во­прос ответить не так просто, [...]]]></description>
			<content:encoded><![CDATA[<p>Но взглянем на это окно повнимательнее. В основном меня все в нем устраивает, за исключением того, что мне предлагается осу­ществить выбор из всех имеющихся файлов. А если я хочу, чтобы мне был показаны только файлы с расширением «ехе» или «txt»? Могу ли я каким-нибудь образом изменить фильтр? А на этот во­прос ответить не так просто, как на первый. Здесь ответ не лежит на поверхности. Что ж, делать нечего, придется опять разбираться с исходным текстом MFC.</p>
<p>Поставим точку прерывания на методе CWinApp::OnFileOpen() в файле appdlg.cpp и запустим программу на выполнение. Стоп! Выполнение программы приостановилось. Исходный текст мето­да, на котором мы остановились, приведен ниже:</p>
<p>docmgr.cpp берем исходный код</p>
<p>метода CDocManager::OnFileOpen():</p>
<p><b>void CDocManager::OnFileOpen() {</b></p>
<p><b>// prompt the user (with all document templates) CString newName;</b></p>
<p><b>if (!DoPromptFileName(newName,</b></p>
<p><b>AFX_IDS_OPENFILE, OFN_HIDEREADONLY | FN_FILEMUS TEX1ST,</b></p>
<p><b>TRUE, NULL))</b></p>
<p><b>return; // open cancelled</b></p>
<p><b>AfxGetApp()-&gt;OpenDocumentFile(newName)/</b></p>
<p><b>// if returns NULL, the userhas already been alerted</b></p>
<p>CDocManager::OnFileOpen ]</p>
<p>Здесь же явно видно, что процесс открытия файла J разделен на два этапа. Этап</p>
<p>первый &#8211; вызов метода DoPromptFileNameO (забегая вперед, скажу, что именно эта функция обеспечивает подготов­ку и выдачу диалогового окна для выбора файла). Этап второй -непосредственно открытие файла и преобразование его в доку­мент. Наверное, логично будет, если мы изложение материала так же разделим на две части. В первой части мы должны рассмот­реть, каким образом формируется стандартное диалоговое окно для выбора открываемого файла. Кроме этого, мы должны опре­делить, каким образом мы можем повлиять на процесс формиро­вания этого окна. Во второй части нам необходимо понять, что про­исходит после того, как имя открываемого файла определено. Дру­гими словами, нам нужно понять, как из файла рождается доку­мент. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cwinapponfileopen.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
