<?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; Архитектура</title>
	<atom:link href="http://www.programmfc.ru/category/arxitektura/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%ba%d0%b0%d0%ba-%d0%be%d1%88%d0%b8%d0%b1%d0%ba%d0%b0-%d0%bf%d1%80%d0%b8%d0%b2%d0%b5%d0%bb%d0%b0-%d0%bc%d0%b5%d0%bd%d1%8f-%d0%ba-%d0%bf%d0%be%d0%bd%d0%b8%d0%bc%d0%b0%d0%bd%d0%b8%d1%8e-%d1%82%d0%be.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%ba%d0%b0%d0%ba-%d0%be%d1%88%d0%b8%d0%b1%d0%ba%d0%b0-%d0%bf%d1%80%d0%b8%d0%b2%d0%b5%d0%bb%d0%b0-%d0%bc%d0%b5%d0%bd%d1%8f-%d0%ba-%d0%bf%d0%be%d0%bd%d0%b8%d0%bc%d0%b0%d0%bd%d0%b8%d1%8e-%d1%82%d0%be.html#comments</comments>
		<pubDate>Mon, 08 Feb 2010 19:33:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[Работа с файлами]]></category>
		<category><![CDATA[CWinApp]]></category>
		<category><![CDATA[OnFileOpen]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%ba%d0%b0%d0%ba-%d0%be%d1%88%d0%b8%d0%b1%d0%ba%d0%b0-%d0%bf%d1%80%d0%b8%d0%b2%d0%b5%d0%bb%d0%b0-%d0%bc%d0%b5%d0%bd%d1%8f-%d0%ba-%d0%bf%d0%be%d0%bd%d0%b8%d0%bc%d0%b0%d0%bd%d0%b8%d1%8e-%d1%82%d0%be.html</guid>
		<description><![CDATA[

Значит, либо я сделал что-то не так, либо в программе не опре­делил какие-то данные. Второй вариант, конечно, более вероя­тен. Для того чтобы убедиться в этом, давайте, уважаемый чи­татель, посмотрим на то место, в котором была обнаружена ошибка. Как оказалось, на этом месте находится исходный текст метода OnFileOpenQ класса CWinApp. Ниже приведен текст это­го метода:
void CWinApp::OnFileOpen() [...]]]></description>
			<content:encoded><![CDATA[<p><b></b></p>
<p><b></b></p>
<p>Значит, либо я сделал что-то не так, либо в программе не опре­делил какие-то данные. Второй вариант, конечно, более вероя­тен. Для того чтобы убедиться в этом, давайте, уважаемый чи­татель, посмотрим на то место, в котором была обнаружена ошибка. Как оказалось, на этом месте находится исходный текст метода OnFileOpenQ класса CWinApp. Ниже приведен текст это­го метода:</p>
<p><b>void CWinApp::OnFileOpen() {</b></p>
<p><b>ASSERT(m_pDocManager != NULL); m_pDocManager-&gt;OnFileOpen();</b></p>
<p>}</p>
<p>Помните, я говорил, что имеющий уши да услышит? Во-первых, судя по наименованию переменных, используемых в приведенном выше тексте метода, MFC по умолчанию считает, что наше прило­жение построено в соответствии с идеологией «Документ/представ­ление»! Другими словами, именно эта идеология считается при­оритетной при работе с MFC! Значит, именно ЭТОЙ идеологии в MFC отводится очень важная роль. Возможно, подумал я, что понимание одного из ключевых моментов MFC приблизит меня к по­ниманию идеологии всей библиотеки в целом! Но оставим «лири­ческое отступление» и продолжим нашу работу.</p>
<p>Во-вторых, здесь MFC сама подсказывает нам причину ошибки в программе! Из приведенного выше текста метода мы можем сделать три важных заключения. Заключение первое состоит в том, что у класса CWinApp есть член m_pDocManager, кото­рый, судя по его названию, является указателем на какой-то ме­неджер документов. Заключение второе &#8211; вероятнее всего, имен­но этот менеджер документов и отвечает за управление доку­ментами в приложении. И наконец, заключение третье. Очевид­но, что единственной причиной, которая может привести к выда­че приведенного выше сообщения об ошибке, является равен­ство нулю указателя на менеджер документов. Следовательно, причина этой ошибки состоит в том, что мы просто-напросто не создали менеджер документов!</p>
<p>А что следует из этих заключений? Из этих заключений следует один очень важный вывод.</p>
<p>Тсли наше приложение не обрабатывает команду ID_FILE_OPEN и обработку производит метод CWinApp::OnFileOpen, то перед вызовом этого метода дол­жен быть создан объект класса CDocManager и указатель на этот объект должен быть присвоен полю CWinApp::m_pDocManager.</p>
<p>К сожалению, искать информацию о менеджере документов в MSDN совершенно бесполезно. И в описании членов класса CWi­nApp мы также не найдем и упоминания об m_pDocManager. При­дется опять смотреть исходные коды MFC&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%ba%d0%b0%d0%ba-%d0%be%d1%88%d0%b8%d0%b1%d0%ba%d0%b0-%d0%bf%d1%80%d0%b8%d0%b2%d0%b5%d0%bb%d0%b0-%d0%bc%d0%b5%d0%bd%d1%8f-%d0%ba-%d0%bf%d0%be%d0%bd%d0%b8%d0%bc%d0%b0%d0%bd%d0%b8%d1%8e-%d1%82%d0%be.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ме­тод CFrameWnd::PreCreateWindow</title>
		<link>http://www.programmfc.ru/arxitektura/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cframewndprecreatewindow.html</link>
		<comments>http://www.programmfc.ru/arxitektura/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cframewndprecreatewindow.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:47:37 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[PreCreateWindow]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cframewndprecreatewindow.html</guid>
		<description><![CDATA[Уважаемый читатель, обратите, пожалуйста, внимание, на тот факт, что сразу после создания структуры cs типа CREATESTRUCT все поля этой структуры обнуляются, в том числе обнуляется и поле IpszClass. В таком случае возникает законный вопрос &#8211; какого же класса окно будет создано? Ответ на этот вопрос можно найти в ме­тоде CFrameWnd::PreCreateWindow():

BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT&#38; cs)
{
if (cs.IpszClass == NULL) [...]]]></description>
			<content:encoded><![CDATA[<p>Уважаемый читатель, обратите, пожалуйста, внимание, на тот факт, что сразу после создания структуры cs типа CREATESTRUCT все поля этой структуры обнуляются, в том числе обнуляется и поле IpszClass. В таком случае возникает законный вопрос &#8211; какого же класса окно будет создано? Ответ на этот вопрос можно найти в ме­тоде CFrameWnd::PreCreateWindow():</p>
<p style="text-align: center;"><img class="aligncenter" src="http://www.programmfc.ru/image/6.jpg" alt="Пример" width="371" height="278" /></p>
<p><strong>BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT&amp; cs)</strong></p>
<p><strong>{</strong></p>
<p><strong>if (cs.IpszClass == NULL) {</strong></p>
<p><strong>VERIFY (Af xDef erRegisterClass (AFX_WNDFRAMEORVIEW_REG) ) ; cs.IpszClass = _afxWndFrameOrView; // COLOR_WINDOW background }</strong></p>
<p><strong>if ((cs.style &amp; FWS_ADDTOTITLE) &amp;&amp; afxData.bWin4) cs.style |= FWS_PREFIXTITLE;</strong></p>
<p><strong>if (afxData.bWin4)</strong></p>
<p><strong>cs.dwExStyle |= WS_EX_CLIENTEDGE;</strong></p>
<p><strong>return TRUE;</strong></p>
<p>}</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/arxitektura/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cframewndprecreatewindow.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Вызов метода CMDIChildWnd::LoadFrame</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%b2%d1%8b%d0%b7%d0%be%d0%b2-%d0%bc%d0%b5%d1%82%d0%be%d0%b4%d0%b0-cmdichildwndloadframe.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%b2%d1%8b%d0%b7%d0%be%d0%b2-%d0%bc%d0%b5%d1%82%d0%be%d0%b4%d0%b0-cmdichildwndloadframe.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:47:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CMDIChildWnd]]></category>
		<category><![CDATA[PreCreateWindow]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%b2%d1%8b%d0%b7%d0%be%d0%b2-%d0%bc%d0%b5%d1%82%d0%be%d0%b4%d0%b0-cmdichildwndloadframe.html</guid>
		<description><![CDATA[Для только что созданного объекта осуществляется вызов метода CMDIChildWnd::LoadFrame(). При этом в качестве аргументов ме­тоду передаются пресловутый идентификатор ресурсов, набор сти­лей окна (не объекта, а окна!), которое будет создано, указатель на родительское окно и, наконец, указатель на структуру типа Ccreate-Context, которую мы рассмотрели чуть раньше. Здесь стоит заме­тить, что по умолчанию стилями окна являются WSJDVERLAPPED-WINDOW [...]]]></description>
			<content:encoded><![CDATA[<p>Для только что созданного объекта осуществляется вызов метода CMDIChildWnd::LoadFrame(). При этом в качестве аргументов ме­тоду передаются пресловутый идентификатор ресурсов, набор сти­лей окна (не объекта, а окна!), которое будет создано, указатель на родительское окно и, наконец, указатель на структуру типа Ccreate-Context, которую мы рассмотрели чуть раньше. Здесь стоит заме­тить, что по умолчанию стилями окна являются WSJDVERLAPPED-WINDOW и FWS_ADDTOTITLE. Исходный текст этого метода на­ходится в файле winmdi.cpp:</p>
<p style="text-align: center;"><img class="aligncenter" src="http://www.programmfc.ru/image/2.jpg" alt="Пример" width="299" height="306" /></p>
<p><strong>BOOL CMDIChildWnd::LoadFrame(UINT nIDResource,</strong></p>
<p><strong>DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext)</strong></p>
<p>{</p>
<p><strong>// only do this once</strong></p>
<p><strong>ASSERT_VALID_IDR(nIDResource) ;</strong></p>
<p><strong>ASSERT(m_nIDHelp == 0 || m_nIDHelp == nIDResource);<br />
ASSERT(m_hMenuShared == NULL);</strong> <strong>// only do once<br />
m_nIDHelp = nIDResource;</strong></p>
<p><strong>// ID for help context (+HID_BASE_RESOURCE)</strong></p>
<p><strong>// parent must be MDI Frame (or NULL for default)</strong></p>
<p><strong>ASSERT(pParentWnd == NULL ||</strong></p>
<p><strong>pParentWnd-&gt;IsKindOf(RUNTIME_CLASS(CMDIFrameWnd))); // will be a child of MDIClient</strong></p>
<p><strong>ASSERT(!(dwDefaultStyle &amp; WS_POPUP));</strong></p>
<p><strong>dwDefaultStyle |= WS_CHILD;</strong></p>
<p><strong>// if available &#8211; get MDI child menus from doc template<br />
ASSERT(m_hMenuShared == NULL);</strong> <strong>// only do once</strong></p>
<p><strong>CMultiDocTemplate* pTemplate; if (pContext != NULL &amp;&amp;</strong></p>
<p><strong>(pTemplate = (CMultiDocTemplate*)pContext-&gt;</strong></p>
<p><strong>m_pNewDocTemplate) != NULL)</strong></p>
<p>{</p>
<p><strong>ASSERT_KINDOF(CMultiDocTemplate, pTemplate); // get shared menu from doc template</strong></p>
<p><strong>m_hMenuShared = pTemplate-&gt;m_hMenuShared; m_hAccelTable = pTemplate-&gt;m_hAccelTable;</strong></p>
<p>}</p>
<p><strong>else {</strong></p>
<p><strong>TRACEO(&#8220;Warning: no shared menu/acceltable for MDI Child</strong></p>
<p><strong>window.\n&#8221;);</strong></p>
<p><strong>// if this happens, programmer must load these manually }</strong></p>
<p><strong>CString strFullString, strTitle;</strong></p>
<p><strong>if (strFullString.LoadString(nIDResource))</strong></p>
<p><strong>AfxExtractSubString(strTitle, strFullString, 0); // first sub-string</strong></p>
<p><strong>ASSERT(m_hWnd == NULL);</strong></p>
<p><strong>if (!Create(GetlconWndClass(dwDefaultStyle, nIDResource), strTitle, dwDefaultStyle, rectDefault,</strong></p>
<p><strong>(CMDIFrameWnd*)pParentWnd, pContext))</strong></p>
<p>{</p>
<p><strong>return FALSE; // will self destruct on failure normally</strong></p>
<p><strong>// it worked ! return TRUE;</strong></p>
<p>}</p>
<p>Что мы можем увидеть в тексте этого модуля? Многое. Здесь даны ответы на еще несколько вопросов, которые мы напрямую не задавали, но которые, как говорится, висели в воздухе. Например, что еще, кроме меню, акселераторов и строки, может входить в состав передаваемых шаблону документа ресурсов? Каково назна­чение оставшихся подстрок строкового ресурса? Из текста модуля очевидно, что, во-первых, то, что в состав ресурсов, переданных шаблону документа, могут входить не только меню, акселераторы и строка, но и ресурсы помощи. Во-вторых, меню, которое мы соз­дали, является меню окна фрейма! Для нас это очень важно, ибо, наконец, мы поняли, что за меню мы должны создавать при созда­нии шаблона документа. Именно к окну фрейма и относятся аксе­лераторы, которые мы можем создать одновременно с меню.</p>
<p>Этот метод непосредственно создает окно фрей­ма. Но до того момента, пока окно фрейма будет создано, проис­ходит еще несколько интересных вещей. Например, перед вызо­вом метода Create() вызывается метод CFrameWnd::GetlconWnd-Class(). В качестве аргументов этому методу передаются стиль окна и опять-таки идентификатор ресурсов. Текст этой функции нахо­дится в файле winfrm.cpp:</p>
<p><strong>LPCTSTR CFrameWnd::GetlconWndClass(DWORD dwDefaultStyle,</strong></p>
<p><strong>UINT nIDResource)</strong></p>
<p><strong><em>{</em></strong></p>
<p><strong>ASSERT_VALID_IDR(nIDResource); HINSTANCE hlnst =</strong></p>
<p><strong>AfxFindResourceHandle(MAKEINTRESOURCE(nIDResource),</strong></p>
<p><strong>RT_GROUP_ICON); HICON hlcon = ::LoadIcon(hlnst,</strong></p>
<p><strong>MAKEINTRESOURCE(nIDResource));</strong></p>
<p><strong>if (hlcon != NULL) {</strong></p>
<p><strong>CREATESTRUCT cs;</strong></p>
<p><strong>memset(&amp;cs, 0, sizeof(CREATESTRUCT));</strong></p>
<p><strong>cs.style = dwDefaultStyle;</strong></p>
<p><strong>PreCreateWindow(cs); // will fill IpszClassName with default WNDCLASS name // ignore instance handle from PreCreateWindow.</strong></p>
<p><strong>WNDCLASS wndcls;</strong></p>
<p><strong>if (cs.IpszClass != NULL &amp;&amp;</strong></p>
<p><strong>GetClassInfo(AfxGetlnstanceHandle(), cs.IpszClass,</strong></p>
<p><strong>&amp;wndcls) &amp;&amp; wndcls.hlcon != hlcon)</strong></p>
<p>{</p>
<p><strong>// register a very similar WNDCLASS</strong></p>
<p><strong>return AfxRegisterWndClass(wndcls.style,</strong></p>
<p><strong>wndcls.hCursor, wndcls.hbrBackground, hlcon);</strong></p>
<p>}</p>
<p><strong>}</strong></p>
<p><strong>return NULL;</strong> <strong>// just use the default</strong></p>
<p>}</p>
<p>Так&#8230; Оказывается, в состав ресурсов, передаваемых шаблону документа, может входить и иконка, которая будет использоваться при отображении окна фрейма! Функция пытается загрузить икон­ку из ресурсов, и, если иконка не загрузилась, то ничего не проис­ходит и метод Create() использует данные, принятые по умолча­нию, загрузилась, Если же иконка загрузилась нормально, то MFC, естественно, регистрирует класс окна, которому принадлежит икон­ка. После этого вызывается метод PreCreateWindow(), который мы можем использовать для того, чтобы произвести какие-то дейст­вия ДО создания окна.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%b2%d1%8b%d0%b7%d0%be%d0%b2-%d0%bc%d0%b5%d1%82%d0%be%d0%b4%d0%b0-cmdichildwndloadframe.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>
	</channel>
</rss>
