<?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; lnitlnstance</title>
	<atom:link href="http://www.programmfc.ru/tag/lnitlnstance/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>Отображение документа</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>Текст метода 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>Метод lnitlnstance</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-lnitlnstance.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-lnitlnstance.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:42:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CDocTemplate]]></category>
		<category><![CDATA[lnitlnstance]]></category>
		<category><![CDATA[Метод lnitlnstance]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-lnitlnstance.html</guid>
		<description><![CDATA[В заключение необходимо привести пример использования стро­ки ресурсов для формирования диалога открытия файла. В файл ресурсов я добавил строку
IDRJDOCUMENT &#34;\nExe-file\nExe-file\n
Executable files (*.exe)\n.exe\n\n&#34;
Мне бы хотелось, чтобы в диалоговом окне мне предлагалось осуществить выбор из ехе-файлов. Естественно, мне необходимо указать идентификатор ресурса в методе lnitlnstance() моего при­ложения. После внесенных изменений он стал выглядеть следую­щим образом:
BOOL CDocViewlApp::Initlnstance () [...]]]></description>
			<content:encoded><![CDATA[<p>В заключение необходимо привести пример использования стро­ки ресурсов для формирования диалога открытия файла. В файл ресурсов я добавил строку</p>
<p><b>IDRJDOCUMENT</b> <b>&quot;<u>\nExe-f</u>ile\nExe-file\n</b></p>
<p><b>Executable files (*.exe)<u>\n.exe\n\n</u>&quot;</b></p>
<p>Мне бы хотелось, чтобы в диалоговом окне мне предлагалось осуществить выбор из ехе-файлов. Естественно, мне необходимо указать идентификатор ресурса в методе 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( IDRJDOCUMENT,</b></p>
<p><b>NULL, NULL, NULL );</b></p>
<p><b>AddDocTemplate( pDocTemplate ); CMainFrame* pMainFrame = new CMainFrame; pMainFrame-&gt;LoadFrame( IDR_RESOURCE );</b></p>
<p><b>m_pMainWnd = pMainFrame; pMainFrame-&gt;ShowWindow(m_nCmdShow ) ; pMainFrame-&gt;UpdateWindow() ;</b></p>
<p><b>return TRUE;</b></p>
<p>}</p>
<p>Посмотрим, правильны ли мои рассуждения и сработает ли в данном случае моя программа. Итак, компилируем&#8230; Запуска­ем&#8230; Выбираем «File», «Ореп» и&#8230;</p>
<p>Окно, появившееся на отображении, вы видите на 13. © Очень надеюсь, что того материала, который мы только что изу­чили, достаточно для понимания того, что происходит при подго­товке стандартного диалога. Надеюсь, что и в этом случае мы ус­пешно решили все поставленные задачи &#8211; мы поняли «физику» процесса и осознали возможную степень влияния программиста на процесс создания диалогового окна. Конечно, я мог бы объяс­нять все мелочи, встречающиеся в исходном коде, например, ото­бражение диалогового окна при помощи метода DoModal(), но имеет ли это смысл? </p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-lnitlnstance.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Метод CDocView1::lnitlnstance</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cdocview1lnitlnstance.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cdocview1lnitlnstance.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:36:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[Работа с файлами]]></category>
		<category><![CDATA[CDocTemplate]]></category>
		<category><![CDATA[lnitlnstance]]></category>
		<category><![CDATA[Метод CDocView1]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cdocview1lnitlnstance.html</guid>
		<description><![CDATA[После приведенных изменений метод CDocView1::lnitlnstance() имел следующее содержание:
BOOL CDocViewlApp::Initlnstance() {
#ifdef _AFXDLL
Enable3dControls (); #else
Enable3dControlsStatic(); #endif
LoadStdProfileSettings(); CDocTemplate* pDocTemplate; pDocTemplate = new CDocTemplate( 0,
NULL ),
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>После приведенных изменений метод CDocView1::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; pDocTemplate = new CDocTemplate( 0,</b></p>
<p><b>NULL ),</b></p>
<p><b>NULL,</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>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cdocview1lnitlnstance.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Простейшая программа работы с MFC</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%bf%d1%80%d0%be%d1%81%d1%82%d0%b5%d0%b9%d1%88%d0%b0%d1%8f-%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%b0-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%8b-%d1%81-mfc.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%bf%d1%80%d0%be%d1%81%d1%82%d0%b5%d0%b9%d1%88%d0%b0%d1%8f-%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%b0-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%8b-%d1%81-mfc.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:10:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CWinApp]]></category>
		<category><![CDATA[lnitlnstance]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/%d0%bf%d0%b5%d1%80%d0%b2%d0%b0%d1%8f-%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%b0-%d0%bd%d0%b0-mfc/%d0%bf%d1%80%d0%be%d1%81%d1%82%d0%b5%d0%b9%d1%88%d0%b0%d1%8f-%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%b0-%d1%8</guid>
		<description><![CDATA[Уважаемый читатель, сейчас нам с вами предстоит разобраться, каким образом должна быть написана простейшая программа ра­боты с MFC. В тех книгах, которые я читал ранее, этот процесс описывался очень отрывочно. Создайте класс, производный от клас­са CWinApp, перекройте метод lnitlnstance()&#8230; А почему так? Поче­му я должен перекрывать именно метод lnitlnstance(), а не какой-то другой? То есть [...]]]></description>
			<content:encoded><![CDATA[<p>Уважаемый читатель, сейчас нам с вами предстоит разобраться, каким образом должна быть написана простейшая программа ра­боты с MFC. В тех книгах, которые я читал ранее, этот процесс описывался очень отрывочно. Создайте класс, производный от клас­са CWinApp, перекройте метод lnitlnstance()&#8230; А почему так? Поче­му я должен перекрывать именно метод lnitlnstance(), а не какой-то другой? То есть мне предлагалось просто поверить автору на слово, а я не хочу так делать. Постараемся сейчас самостоятель­но разобраться, что к чему.</p>
<p style="text-align: center;"><img class="aligncenter" src="http://www.programmfc.ru/image/13.jpg" alt="Пример" width="300" height="264" /></p>
<p>Если вы помните, уважаемый читатель, я ранее оговорился, что при описании MFC мною был принят за аксиому тот факт, что класс приложения должен быть унаследован от класса CWinApp, вклю­ченного в MFC. Что ж, напишем простейшую программу для MFC:</p>
<p><strong>#include &lt;afxwin.h&gt;</strong></p>
<p><strong>class CEmpty : public CWinApp {</strong></p>
<p>};</p>
<p><strong>CEmpty theApp;</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%bf%d1%80%d0%be%d1%81%d1%82%d0%b5%d0%b9%d1%88%d0%b0%d1%8f-%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%b0-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%8b-%d1%81-mfc.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Метод lnitApplication</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-lnitapplication.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-lnitapplication.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:09:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CWinApp]]></category>
		<category><![CDATA[lnitlnstance]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-lnitapplication.html</guid>
		<description><![CDATA[Эта функция в настоящее время является устаревшей. В Windows более ранних версий, скажем, Windows 3.1, можно было запустить несколько копий о/уного и того же приложения. При этом весьма высокой была вероятность того, что все они будут использовать одни и те же данные, подготовленные при запуске первой копии приложения. Метод lnitApplication() использовался именно для под­готовки ОБЩИХ [...]]]></description>
			<content:encoded><![CDATA[<p>Эта функция в настоящее время является устаревшей. В Windows более ранних версий, скажем, Windows 3.1, можно было запустить несколько копий о/уного и того же приложения. При этом весьма высокой была вероятность того, что все они будут использовать одни и те же данные, подготовленные при запуске первой копии приложения. Метод lnitApplication() использовался именно для под­готовки ОБЩИХ для всех копий данных при запуске первой копии приложения. В настоящее время этот метод используется для ини­циализации менеджера документов, который используется при ра­боте с архитектурой «Document/view (документ/представление)». Об этой архитектуре речь пойдет в соответствующей части книги.</p>
<p>Следом за методом lnitApplication() вызывается метод lnitlnstance(). Предназначение этого метода как раз и заключается в том, чтобы произвести инициализацию приложения. Исходный код этого метода находится в файле аррсоге.срр:</p>
<p><b>BOOL CWinApp::InitInstance() {</b></p>
<p><b>return TRUE;</b></p>
<p><b>}</b></p>
<p>Очевидно, что по умолчанию метод не производит никаких дей­ствий, т. е. мы должны переопределить этот метод в своей про­грамме и вставить сюда операторы, обеспечивающие реальную инициализацию нашего приложения.</p>
<p>Сразу после завершения работы метода lnitlnstance() вызыва­ется метод Run(). Его исходный код находится в файле аррсоге.срр:</p>
<p><b>int CWinApp::Run()</b></p>
<p>{</p>
<p><b>if (m_pMainWnd == NULL &amp;&amp; AfxOleGetUserCtrl()) {</b></p>
<p><b>// Not launched /Embedding or /Automation, // but has no main window!</b></p>
<p><b>TRACEO(&quot;Warning: m_pMainWnd is NULL in CWinApp::Run -</b></p>
<p><b>quitting application.\n&quot;);</b></p>
<p><b>AfxPostQuitMessage(0);</b></p>
<p>}</p>
<p><b>return CWinThread::Run();</b></p>
<p><b>}</b></p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-lnitapplication.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Поле m_pMainWnd</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%bf%d0%be%d0%bb%d0%b5-m_pmainwnd.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%bf%d0%be%d0%bb%d0%b5-m_pmainwnd.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:09:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CWinApp]]></category>
		<category><![CDATA[lnitlnstance]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%bf%d0%be%d0%bb%d0%b5-m_pmainwnd.html</guid>
		<description><![CDATA[Внимательно взглянув на текст этого метода, можно заметить, что в том случае, когда поле m_pMainWnd равно нулю и приложение было загружено системой, а не OLE, работа метода немедленно завершается. При этом в отладочное окно выдается сообщение «Warning: m_pMainWnd is NULL in CWinApp::Run &#8211; quitting applica­tion.» (Предупреждение: m_pMainWnd равно NULL в методе CWinApp::Run &#8211; приложение завершается). [...]]]></description>
			<content:encoded><![CDATA[<p>Внимательно взглянув на текст этого метода, можно заметить, что в том случае, когда поле m_pMainWnd равно нулю и приложение было загружено системой, а не OLE, работа метода немедленно завершается. При этом в отладочное окно выдается сообщение «Warning: m_pMainWnd is NULL in CWinApp::Run &#8211; quitting applica­tion.» (Предупреждение: m_pMainWnd равно NULL в методе CWinApp::Run &#8211; приложение завершается). Возникает вопрос: что же мы сделали не так, и почему возникла ошибка? Заглянув в спи­сок полей нашего объекта-приложения, мы увидим, что поле m_pMainWnd приложение наследует от класса CWinThread. В описа­нии класса CWinThread можно найти следующую запись:</p>
<p>CWnd* m_pMainWnd; // main window</p>
<p>//(usually same AfxGetApp()-&gt;m_pMainWnd)</p>
<p>Другими словами, поле m_pMainWnd должно хранить указатель на объект класса CWnd, который должен быть ассоциирован с ок­ном, являющимся ГЛАВНЫМ окном приложения. Но где должен быть создан этот объект? У нас есть две возможности &#8211; метод Ini-tApplicationQ и метод lnitlnstance(). Так как метод InitApplicationQ используется MFC для других целей (инициализация менеджера документов), то, чтобы не переписывать метод lnitApplication(), луч­ше всего будет создать объект класса CWnd в переопределенном методе lnitlnstance(). Отсюда делаем еще один вывод: <i>объект клас­са CWnd, который будет ассоциирован с главным окном прило­жения, целесообразно создавать в переопределенном методе InitlnstanceQ приложения.</i></p>
<p>А теперь давайте еще немного порассуждаем. Если наши рассуждения верны, то объект класса CWnd будет создан во вре­мя отработки метода InitlnstanceQ приложения. Но объект приложения будет создан ранее, во время отработки startup-кода! Инициализацией полей класса, в том числе и поля m_pWinMain, должен, естественно, заниматься конструктор класса. Но кон­структор класса CWinThread отрабатывает раньше конструктора класса CWinApp и, тем более, раньше метода lnitlnstance() при­ложения. Следовательно, поле m_pMainWnd после создания объекта приложения остается неинициализированным или со­держит неверную информацию. Значит, <i>после того, как в ме­тоде InitlnstanceQ будет создано главное окно приложения, полю m_pMainWnd необходимо присвоить значение указателя на ассоциированный с окном объект. </i>В противном случае про­грамма, увы, работать не будет!</p>
<p>Что ж, попробуем немного изменить нашу программу и доба­вить в нее переопределенный метод lnitlnstance(), в котором будет создан объект класса CWnd. Текст измененной программы:</p>
<p>#include &lt;afxwin.h&gt;</p>
<p>class CExampleApp : public CWinApp {</p>
<p>BOOL Initlnstance() ;</p>
<p>};</p>
<p><b>class CMainWnd : public CWnd {</b></p>
<p>};</p>
<p><b>BOOL CExampleApp::Initlnstance() {</b></p>
<p><b>CMainWnd* pMainWnd = new CMainWnd; m_pMainWnd = pMainWnd; return TRUE;</b></p>
<p>}</p>
<p><b>CExampleApp theApp;</b></p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%bf%d0%be%d0%bb%d0%b5-m_pmainwnd.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Метод CWinApp:Run</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cwinapprun.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cwinapprun.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:09:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CWinApp]]></category>
		<category><![CDATA[lnitlnstance]]></category>
		<category><![CDATA[Метод CWinApp]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cwinapprun.html</guid>
		<description><![CDATA[Запускаем программу на выполнение&#8230; Что такое? Программа «зависла»&#8230; Да нет, программа не «зависла». Вспомните, уважае­мый читатель, что после метода lnitlnstance() немедленно вызыва­ется метод CWinApp::Run(). Именно в нем программа и «циклит»! Придется опять искать причину неправильной работы программы. Что же может случиться? Мы создали объект класса CWnd, запи­сали указатель на него в поле m_pMainWnd, чего же [...]]]></description>
			<content:encoded><![CDATA[<p>Запускаем программу на выполнение&#8230; Что такое? Программа «зависла»&#8230; Да нет, программа не «зависла». Вспомните, уважае­мый читатель, что после метода lnitlnstance() немедленно вызыва­ется метод CWinApp::Run(). Именно в нем программа и «циклит»! Придется опять искать причину неправильной работы программы. Что же может случиться? Мы создали объект класса CWnd, запи­сали указатель на него в поле m_pMainWnd, чего же еще? Взгля­нув на исходный код метода CWinApp::Run(), можно с уверенно­стью сказать, что причину «зацикливания» нужно искать в методе CWinThread::Run(). Его исходный текст находится в файле thrdcore.cpp:</p>
<p><b>int CWinThread::Run() {</b></p>
<p><b>ASSERT_VALID(this);</b></p>
<p><b>// for tracking the idle time state BOOL bldle = TRUE; LONG HdleCount = 0;</b></p>
<p><b>// acquire and dispatch messages until a WM_QUIT message is received, for (;;) {</b></p>
<p><b>// phasel: check to see if we can do idle work while (bldle &amp;&amp;</b></p>
<p><b>! : <img src='http://www.programmfc.ru/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> eekMessage(&amp;m_msgCur, NULL, NULL, NULL, PM_NOREMOVE)) {</b></p>
<p><b>// call Onldle while in bldle state</b></p>
<p><b>if (!0nldle (HdleCount++) )</b></p>
<p><b>bldle = FALSE; // assume &quot;no idle&quot; state</b></p>
<p>}</p>
<p><b>// phase2: pump messages while available</b></p>
<p><b>do</b></p>
<p>{</p>
<p><b>// pump message, but quit on WM_QUIT if (!PumpMessage())</b></p>
<p><b>return Exitlnstance ();</b></p>
<p><b>// reset &quot;no idle&quot; state after pumping &quot;normal&quot; message if (IsIdleMessage(&amp;m_msgCur)) {</b></p>
<p><b>bldle = TRUE; HdleCount = 0;</b></p>
<p>}</p>
<p><b>} while (::PeekMessage(&amp;m_msgCur,</b></p>
<p><b>NULL, NULL, NULL,</b></p>
<p><b>PM_NOREMOVE));</b></p>
<p>}</p>
<p><b>ASSERT(FALSE); // not reachable</b></p>
<p>}</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cwinapprun.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Имя регистрируемого класса</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%b8%d0%bc%d1%8f-%d1%80%d0%b5%d0%b3%d0%b8%d1%81%d1%82%d1%80%d0%b8%d1%80%d1%83%d0%b5%d0%bc%d0%be%d0%b3%d0%be-%d0%ba%d0%bb%d0%b0%d1%81%d1%81%d0%b0.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%b8%d0%bc%d1%8f-%d1%80%d0%b5%d0%b3%d0%b8%d1%81%d1%82%d1%80%d0%b8%d1%80%d1%83%d0%b5%d0%bc%d0%be%d0%b3%d0%be-%d0%ba%d0%bb%d0%b0%d1%81%d1%81%d0%b0.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:09:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CWinApp]]></category>
		<category><![CDATA[lnitlnstance]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%b8%d0%bc%d1%8f-%d1%80%d0%b5%d0%b3%d0%b8%d1%81%d1%82%d1%80%d0%b8%d1%80%d1%83%d0%b5%d0%bc%d0%be%d0%b3%d0%be-%d0%ba%d0%bb%d0%b0%d1%81%d1%81%d0%b0.html</guid>
		<description><![CDATA[Функции в качестве аргументов передаются стили окон регистри­руемого класса, хэндлы курсора, фона и иконки. В отличие от преды­дущей эта функция сама формирует имя регистрируемого класса. В том случае, если хэндлы иконки, курсора и фона равны нулю, то имя класса формируется в соответствии с вызовом функции
wsprintf(IpszName,
_T(&#34;Afx:%x:%x&#34;) , (UINT)hlnst, nClassStyle);
Примером может служить имя Afx:400000:0. Первое число в [...]]]></description>
			<content:encoded><![CDATA[<p>Функции в качестве аргументов передаются стили окон регистри­руемого класса, хэндлы курсора, фона и иконки. В отличие от преды­дущей эта функция сама формирует имя регистрируемого класса. В том случае, если хэндлы иконки, курсора и фона равны нулю, то имя класса формируется в соответствии с вызовом функции</p>
<p><b>wsprintf(IpszName,</b></p>
<p><b>_T(&quot;Afx:%x:%x&quot;) , (UINT)hlnst, nClassStyle);</b></p>
<p>Примером может служить имя Afx:400000:0. Первое число в име­ни класса обозначает хэндл текущей копии приложения, второе число &#8211; стиль окон регистрируемого класса.</p>
<p>Если не все параметры, переданные функции, равны NULL, то формируется полное имя класса в соответствии с функцией</p>
<p><b>wsprintf(IpszName,</b></p>
<p><b>_Т(&quot;Afх:%х:%х:%х:%х:%х&quot;),</b></p>
<p><b>(UINT)hlnst, nClassStyle,</b></p>
<p><b>(UINT)hCursor,</b></p>
<p><b>(UINT)hbrBackground,</b></p>
<p><b>(UINT)hlcon);</b></p>
<p>Примером такого имени может служить Afx:400000:8:14c6:0:4687. При этом первое число в имени класса означает хэндл текущей копии приложения, вггорое число &#8211; стиль окон регистрируемого класса, третье число означает хэндл курсора, четвертое &#8211; хэндл фона, и, наконец, пятое &#8211; хэндл иконки окна.</p>
<p>После формирования имени класса функция производит запол­нение структуры типа WNDCLASS и регистрирует класс окон, при­чем в качестве имени класса используется только что сформиро­ванное функцией имя.</p>
<p>Зарегистрировав класс окна, можно создавать окно. А создав окно, нужно не забыть его отобразить, верно? Таким образом, мы</p>
<p>«вычислили» те несколько шагов, которые ОБЯЗАТЕЛЬНО нужно вы­полнить при написании программы с использованием MFC:</p>
<p>1. Описываем класс приложения, производный от класса CWinApp.</p>
<p>2. Описываем класс, к которому будет принадлежать главное окно приложения (обычно CFrameWnd или CMDIFrameWnd).</p>
<p>3. Переопределяем метод lnitlnstance() класса приложения.</p>
<p>4. В методе lnitlnstance() создаем новый объект класса, к которо­му будет принадлежать главное окно приложения.</p>
<p>5. Указатель на только что созданный объект записываем в поле m__pMainWnd.</p>
<p>6. Регистрируем класс окон, к которому будет принадлежать глав­ное окно приложения.</p>
<p>7. В методе lnitlnstance() создаем непосредственно окно только что зарегистрированного класса, которое будет являться главным окном приложения.</p>
<p>8. Создаем объект класса приложения.</p>
<p>Исходный текст демонстрационной программы, написанной в соответствии с определенной нами последовательностью шагов, приведен ниже:</p>
<p><b>#include &lt;afxwin.h&gt;</b></p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%b8%d0%bc%d1%8f-%d1%80%d0%b5%d0%b3%d0%b8%d1%81%d1%82%d1%80%d0%b8%d1%80%d1%83%d0%b5%d0%bc%d0%be%d0%b3%d0%be-%d0%ba%d0%bb%d0%b0%d1%81%d1%81%d0%b0.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Метод CWinThread:Run</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cwinthreadrun.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cwinthreadrun.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:07:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[lnitlnstance]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cwinthreadrun.html</guid>
		<description><![CDATA[И перед тем, как начать рассказ, о том, что происходит в методе CWinThread::Run(), мне бы хотелось обратить внимание читателя на одну деталь. Раз метод CWinThread::Run() занимается обработ­кой сообщений, т. е. представляет собой аналог стандартного цик­ла обработки сообщений, то это означает, что все действия по ини­циализации нашего приложения, в том числе и создание окна, должны быть [...]]]></description>
			<content:encoded><![CDATA[<p>И перед тем, как начать рассказ, о том, что происходит в методе CWinThread::Run(), мне бы хотелось обратить внимание читателя на одну деталь. Раз метод CWinThread::Run() занимается обработ­кой сообщений, т. е. представляет собой аналог стандартного цик­ла обработки сообщений, то это означает, что <i>все действия по ини­циализации нашего приложения, в том числе и создание окна, должны быть осуществлены ДО вызова метода Run()\ </i>Другими словами, MFC написано с таким расчетом, что главное окно при­ложения будет создано именно в методе lnitlnstance()!</p>
<p>Вернемся к рассмотрению метода CWinThread::Run(). Обраща­ет на себя внимание тот факт, что метод позволяет производить какие-то действия в тот период, когда в очереди нет никаких сооб­щений. Другими словами, если переменная bldle равна TRUE и функция PeekMessage(), при помощи которой осуществляется выборка сообщений, вернула FALSE, то метод вызывает другой метод, Onldle(). </p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cwinthreadrun.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
