<?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; CMDIChildWnd</title>
	<atom:link href="http://www.programmfc.ru/tag/cmdichildwnd/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>Класс CMDIChildWnd</title>
		<link>http://www.programmfc.ru/prilozheniya/%d0%ba%d0%bb%d0%b0%d1%81%d1%81-cmdichildwnd.html</link>
		<comments>http://www.programmfc.ru/prilozheniya/%d0%ba%d0%bb%d0%b0%d1%81%d1%81-cmdichildwnd.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:52:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Приложения]]></category>
		<category><![CDATA[CMDIChildWnd]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%ba%d0%bb%d0%b0%d1%81%d1%81-cmdichildwnd.html</guid>
		<description><![CDATA[Мне бы хотелось, чтобы вы вспомнили, что происходит при по­лучении окном класса CMDIChildWnd сообщения WM_CREATE. Во время работы этого метода вызываются еще много других мето­дов, в том числе CFrameWnd::CreateView(). Именно при работе этого метода и происходит вызов метода CreateObject() для объекта клас­са окна представления. Естественно, метод CreateObject() вызы­вает конструктор объекта окна представления. И, разумеется, вы­зываются [...]]]></description>
			<content:encoded><![CDATA[<p>Мне бы хотелось, чтобы вы вспомнили, что происходит при по­лучении окном класса CMDIChildWnd сообщения WM_CREATE. Во время работы этого метода вызываются еще много других мето­дов, в том числе CFrameWnd::CreateView(). Именно при работе этого метода и происходит вызов метода CreateObject() для объекта клас­са окна представления. Естественно, метод CreateObject() вызы­вает конструктор объекта окна представления. И, разумеется, вы­зываются строго по порядку конструкторы классов, от которых унас­ледован наш объект. Если мы в качестве окна приложения исполь­зуем объект класса CEditView, то первым вызывается конструктор CEditView::CEditView(). Исходный код этого конструктора находит­ся в файде viewedit.cpp:</p>
<p><b>// pass a NULL style because dwStyleDefault stays for // backward compatibility</b></p>
<p><b>CEditView::CEditView() : CCtrlView(_T(&quot;EDIT&quot;), NULL) </b><b><i></i></b></p>
<p><b>m_nTabStops = 8*4; // default 8 character positions m_hPrinterFont = NULL; m_hMirrorFont = NULL; m_pShadowBuffer = NULL; m_nShadowSize = 4);</b></p>
<p>}</p>
<p>Перед тем, как отработает этот конструктор, управление будет передано конструктору класса CCtrlView.</p>
<p>Исходный текст конструктора класса CCtrlView можно найти в файле viewcore.cpp:</p>
<p><b>CCtrlView::CCtrlView(LPCTSTR IpszClass, DWORD dwStyle) {</b></p>
<p><b>m_strClass = IpszClass;</b></p>
<p><b>m_dwDefaultStyle = dwStyle;</b></p>
<p>}</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/prilozheniya/%d0%ba%d0%bb%d0%b0%d1%81%d1%81-cmdichildwnd.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Структура типа 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-2.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-2.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:51:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Первая программа на MFC]]></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-2.html</guid>
		<description><![CDATA[Обратите внимание, читатель, что указатель на структуру типа CCreateContext (в нее чуть раньше мы записали наши указатели на документ,шаблон документа, а также указатели на фрейм и на окно представления документа) записывается сначала в поле lpCreateParams структуры cs типа CREATESTRUCT, а потом в поле IParam структу­ры mcs типа MDICREATESTRUCT Указатель на структуру mcs по­сылается окну типа [...]]]></description>
			<content:encoded><![CDATA[<p>Обратите внимание, читатель, что указатель на структуру типа CCreateContext (в нее чуть раньше мы записали наши указатели на документ,шаблон документа, а также указатели на фрейм и на окно представления документа) записывается сначала в поле lpCreateParams структуры cs типа CREATESTRUCT, а потом в поле IParam структу­ры mcs типа MDICREATESTRUCT Указатель на структуру mcs по­сылается окну типа MDICLIENT посредством сообщения WM_MDICREATE. Что же происходит дальше? После получения этого сообщения создается дочернее окно MDI, которое будет иг­рать роль окна фрейма. Естественно, при своем создании оно по­лучает сообщение WM_CREATE, на что реагирует вызовом мето­да CMDIChildWnd::OnCreate():</p>
<p><b>int CMDIChildWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) {</b></p>
<p><b>// call base class with IParam context (not MDI one) MDICREATESTRUCT* lpmcs;</b></p>
<p><b>lpmcs = (MDICREATESTRUCT*)lpCreateStruct-&gt;lpCreateParams; CCreateContext* pContext = (CCreateContext*)lpmcs-&gt;lParam;</b></p>
<p><b>return OnCreateHelper(lpCreateStruct, pContext);</b></p>
<p>Из переданной окну структуры типа CREATESTRUCT выбирает­ся указатель на CCreateContext, после чего указатели на структуры типов CREATESTRUCT и CCreateStruct передаются методу CFrameWnd::OnCreateHelper:</p>
<p><b>int CFrameWnd::OnCreateHelper(LPCREATESTRUCT lpcs.</b></p>
<p><b>CCreateContext* pContext)</b></p>
<p><b>if (CWnd::OnCreate(lpcs) == -1) return -1;</b></p>
<p><b>// create special children first</b></p>
<p><b>if (!OnCreateClie*nt (lpcs, pContext) ) {</b></p>
<p><b>TRACEO(&quot;Failed to create client pane/view for frame.\n&quot;) ; return -1;</b></p>
<p>}</p>
<p><b>// post message for initial message string</b></p>
<p><b>PostMessage(WM_SETMESSAGESTRING, AFX__IDS_IDLEMESSAGE);</b></p>
<p><b>// make sure the child windows have been properly sized RecalcLayout();</b></p>
<p><b>return 0; // create ok</b></p>
<p><b>}</b></p>
<p><b>BOOL CFrameWnd::OnCreateClient(LPCREATESTRUCT,</b></p>
<p><b>CCreateContext* pContext)</b></p>
<p>{</p>
<p><b>// default create client will create a view if asked for it if (pContext != NULL &amp;&amp; pContext-&gt;m_pNewViewClass != NULL) {</b></p>
<p><b>if (CreateView (pContext, AFX_IDW_PANE_FIRST) == NULL) return FALSE;</b></p>
<p>}</p>
<p><b>return TRUE;</b></p>
<p>}</p>
<p><b>CWnd* CFrameWnd::CreateView(CCreateContext* pContext,</b></p>
<p><b>UINT nID)</b></p>
<p>{</p>
<p><b>ASSERT(m_hWnd != NULL); ASSERT(::IsWindow(m_hWnd)); ASSERT(pContext != NULL);</b></p>
<p><b>ASSERT(pContext-&gt;m_pNewViewClass != NULL);</b></p>
<p><b>// Note: can be a CWnd with PostNcDestroy self cleanup CWnd* pView =</b></p>
<p><b>(CWnd*)pContext-&gt;m_pNewViewClass-&gt;CreateObject() ; if (pView == NULL) {</b></p>
<p><b>TRACE1(&quot;Warning: Dynamic create of view type</b></p>
<p><b>%hs failed.\n&quot;,</b></p>
<p><b>pContext-&gt;m_pNewViewClass-&gt;m_lpszClassName) ; return NULL;</b></p>
<p><b>ASSERT_KINDOF(CWnd, pView);</b></p>
<p><b>// views are always created with a border! if (!pView-&gt;Create(NULL, NULL,</b></p>
<p><b>AFX_WS_DEFAULT_VIEW, CRect(0,0,0, 0), this, nID,</b></p>
<p><b>pContext))</b></p>
<p>{</p>
<p><b>TRACEO(&quot;Warning: could not create view for frame.\n&quot;);     <br />return NULL;</b> <b>// can&#8217;t continue without a view</b></p>
<p>}</p>
<p><b>if (afxData.bWin4 &amp;&amp; (pView-&gt;GetExStyle () &amp;</b></p>
<p><b>WS_EX_CLIENTEDGE))</b></p>
<p>{</p>
<p><b>// remove the 3d style from the frame, since the view is // providing it.</b></p>
<p><b>// make sure to recalc the non-client area</b></p>
<p><b>ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_FRAMECHANGED);</b></p>
<p>}</p>
<p><b>return pView;</b></p>
<p>}</p>
<p>Смотрите внимательно, читатель! Сначала создается объект (представление) того класса, который мы указали при создании шаблона документа. После этого создается непосредственно окно представления. При этом видно, родительским окном объ­является окно фрейма! Так что же получается? MFC решило за программиста одну из достаточно часто встречавшихся задач -расположение дочернего окна поверх клиентской области роди­тельского окна. Теперь программисту нет необходимости само­му создавать дочернее окно и отслеживать изменения размеров родительского окна &#8211; эти задачи решает за него MFC. Единст­венное, что в этом случае требуется от программиста, так это написать приложение в соответствии с требованиями архитек­туры «документ/представление»!</p>
<p>Осталось понять одну «мелочь» &#8211; как осуществляется отобра­жение данных документа в окне представления.</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-2.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Исходный код метода CMDIChildWnd::LoadFrame</title>
		<link>http://www.programmfc.ru/vozmozhnosti-mfc/%d0%b8%d1%81%d1%85%d0%be%d0%b4%d0%bd%d1%8b%d0%b9-%d0%ba%d0%be%d0%b4-%d0%bc%d0%b5%d1%82%d0%be%d0%b4%d0%b0-cmdichildwndloadframe.html</link>
		<comments>http://www.programmfc.ru/vozmozhnosti-mfc/%d0%b8%d1%81%d1%85%d0%be%d0%b4%d0%bd%d1%8b%d0%b9-%d0%ba%d0%be%d0%b4-%d0%bc%d0%b5%d1%82%d0%be%d0%b4%d0%b0-cmdichildwndloadframe.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:50:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Возможности MFC]]></category>
		<category><![CDATA[CMDIChildWnd]]></category>
		<category><![CDATA[PreCreateWindow]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%b8%d1%81%d1%85%d0%be%d0%b4%d0%bd%d1%8b%d0%b9-%d0%ba%d0%be%d0%b4-%d0%bc%d0%b5%d1%82%d0%be%d0%b4%d0%b0-cmdichildwndloadframe.html</guid>
		<description><![CDATA[Читатель, взгляните, пожалуйста, на исходный код метода CMDIChildWnd::LoadFrame(). В нем вы увидите следующий опе­ратор:
if (!Create(GetlconWndClass(dwDefaultStyle, nIDResource), strTitle, dwDefaultStyle, rectDefault,
(CMDIFrameWnd*) pParentWnd, pContext)) &#8230;
BOOL CMDIChildWnd::Create(LPCTSTR IpszClassName,
LPCTSTR IpszWindowName, DWORD dwStyle, const RECT&#38; rect, CMDIFrameWnd* pParentWnd, CCreateContext* pContext)
{
if (pParentWnd == NULL) {
CWnd* pMainWnd = AfxGetThread()-&#62;m_pMainWnd; ASSERT(pMainWnd != NULL); ASSERT_KINDOF(CMDIFrameWnd, pMainWnd); pParentWnd = (CMDIFrameWnd*)pMainWnd;
ASSERT(::IsWindow(pParentWnd-&#62;m_hWndMDIClient));
// insure correct window positioning pParentWnd-&#62;RecalcLayout();
// first [...]]]></description>
			<content:encoded><![CDATA[<p>Читатель, взгляните, пожалуйста, на исходный код метода CMDIChildWnd::LoadFrame(). В нем вы увидите следующий опе­ратор:</p>
<p><b>if (!Create(GetlconWndClass(dwDefaultStyle, nIDResource), strTitle, dwDefaultStyle, rectDefault,</b></p>
<p><b>(CMDIFrameWnd*) pParentWnd, pContext)) &#8230;</b></p>
<p><b>BOOL CMDIChildWnd::Create(LPCTSTR IpszClassName,</b></p>
<p><b>LPCTSTR IpszWindowName, DWORD dwStyle, const RECT&amp; rect, CMDIFrameWnd* pParentWnd, CCreateContext* pContext)</b></p>
<p>{</p>
<p><b>if (pParentWnd == NULL) {</b></p>
<p><b>CWnd* pMainWnd = AfxGetThread()-&gt;m_pMainWnd; ASSERT(pMainWnd != NULL); ASSERT_KINDOF(CMDIFrameWnd, pMainWnd); pParentWnd = (CMDIFrameWnd*)pMainWnd;</b></p>
<p><b>ASSERT(::IsWindow(pParentWnd-&gt;m_hWndMDIClient));</b></p>
<p><b>// insure correct window positioning pParentWnd-&gt;RecalcLayout();</b></p>
<p><b>// first copy into a CREATESTRUCT for PreCreate CREATESTRUCT cs; cs.dwExStyle = OL; cs.IpszClass = IpszClassName; cs.lpszName = IpszWindowName; cs.style = dwStyle; cs.x = rect.left; cs.y = rect.top; cs.cx = rect.right &#8211; rect.left; cs.cy = rect.bottom &#8211; rect.top; cs.hwndParent = pParentWnd-&gt;m_hWnd; cs.hMenu = NULL;</b></p>
<p><b>cs.hlnstance = AfxGetlnstanceHandle(); cs.lpCreateParams = (LPVOID)pContext;</b></p>
<p><b>if (!PreCreateWindow(cs)) {</b></p>
<p><b>PostNcDestroy(); return FALSE;</b></p>
<p>}</p>
<p><b>// extended style must be zero for MDI Children // (except under Win4)</b></p>
<p><b>ASSERT(afxData.bWin4 || cs.dwExStyle == 0);</b></p>
<p><b>ASSERT(cs.hwndParent == pParentWnd-&gt;m_hWnd); // must not change</b></p>
<p><b>// now copy into a MDICREATESTRUCT for real create MDICREATESTRUCT mcs; mcs.szClass = cs :*lpszClass; mcs.szTitle = cs.lpszName; mcs.hOwner = cs.hlnstance;</b></p>
<p><b>mcs.x = cs.x; mcs.</b><b>у</b><b> = cs.y; mcs.cx = cs.cx; mcs.cy = cs.cy;</b></p>
<p><b>mcs.style = cs.style &amp; -(WS_MAXIMIZE | WS_VISIBLE); mcs.lParam = (LONG)cs.lpCreateParams;</b></p>
<p><b>// create the window through the MDICLIENT window AfxHookWindowCreate(this); HWND hWnd =</b></p>
<p><b>(HWND)::SendMessage(pParentWnd-&gt;m_hWndMDIClient, WM_MDICREATE, </b>0,</p>
<p><b>(LPARAM)&amp;mcs); if (!AfxUnhookWindowCreate()) PostNcDestroy(); // cleanup if MDICREATE fails too soon</b></p>
<p><b>if (hWnd ~ NULL) return FALSE;</b></p>
<p><b>// special handling of visibility (always created invisible) if (cs.style &amp; WS_VISIBLE) {</b></p>
<p><b>// place the window on top in z-order before showing it ::BringWindowToTop(hWnd);</b></p>
<p><b>// show it as specified</b></p>
<p><b>if (cs.style &amp; WS_MINIMIZE)</b></p>
<p><b>ShowWindow(SW_SHOWMINIMIZED); else if (cs.style &amp; WS_MAXIMIZE)</b></p>
<p><b>ShowWindow(SW_SHOWMAXIMIZED) ; else</b></p>
<p><b>ShowWindow(SW_SHOWNORMAL);</b></p>
<p><b>// make sure it is active (visibility == activation) pParentWnd-&gt;MDIActivate(this);</b></p>
<p><b>// refresh MDI Window menu</b></p>
<p><b>::SendMessage(pParentWnd-&gt;m_hWndMDIClient, WM_MDIREFRESHMENU, </b>0, 0) ; }</p>
<p><b>ASSERT(hWnd == m_hWnd); return TRUE;</b></p>
<p>}</p>
<p>fCMDIChJldWnd::OnCreate) </p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/vozmozhnosti-mfc/%d0%b8%d1%81%d1%85%d0%be%d0%b4%d0%bd%d1%8b%d0%b9-%d0%ba%d0%be%d0%b4-%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>Отображение документа</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>Метод 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>Вызов метода 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>
	</channel>
</rss>
