<?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; DoPromptFileName</title>
	<atom:link href="http://www.programmfc.ru/tag/dopromptfilename/feed" rel="self" type="application/rss+xml" />
	<link>http://www.programmfc.ru</link>
	<description>Мой второй блог в серии программирования</description>
	<lastBuildDate>Mon, 08 Feb 2010 19:34:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Класс CDocManager</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%ba%d0%bb%d0%b0%d1%81%d1%81-cdocmanager.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%ba%d0%bb%d0%b0%d1%81%d1%81-cdocmanager.html#comments</comments>
		<pubDate>Mon, 08 Feb 2010 19:34:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[Работа с файлами]]></category>
		<category><![CDATA[CDocTemplate]]></category>
		<category><![CDATA[CWinApp]]></category>
		<category><![CDATA[DoPromptFileName]]></category>
		<category><![CDATA[OnFileOpen]]></category>
		<category><![CDATA[OpenDocumentFile]]></category>
		<category><![CDATA[Класс CDocManager]]></category>

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

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/dopromptfilename.html</guid>
		<description><![CDATA[На основании сказанного делаем вывод:
Строка ресурсов, идентификатор которой указывается при создании шаблона документа, должна состоять из подстрок, отделенных друг от друга символом-разделителем (по умол­чанию &#8211; &#8216;\п&#8217;). При этом пятая и четвертая подстроки соот­ветственно хранят наименование фильтра и непосредствен­но фильтр, используемые при формировании стандартно­го диалогового окна открытия файла.
Значит, вот для чего используются шаблоны документов в про­цессе [...]]]></description>
			<content:encoded><![CDATA[<p>На основании сказанного делаем вывод:</p>
<p>Строка ресурсов, идентификатор которой указывается при создании шаблона документа, должна состоять из подстрок, отделенных друг от друга символом-разделителем (по умол­чанию &#8211; &#8216;\п&#8217;). При этом пятая и четвертая подстроки соот­ветственно хранят наименование фильтра и непосредствен­но фильтр, используемые при формировании стандартно­го диалогового окна открытия файла.</p>
<p>Значит, вот для чего используются шаблоны документов в про­цессе формирования диалога открытия файла! Только для того, чтобы выбрать ПОДСТРОКИ, описывающие тип файла нашего до­кумента! Кажется, мы нашли еще один ответ на те вопросы, кото­рые сами себе и поставили! Теперь становится ясным смысл пято­го аргумента у DoPromptFileName().</p>
<p>Замечу попутно, что программист может изменить значение сим­вола-разделителя. Если он хочет в качестве разделителя исполь­зовать не символ &#8216;\п\ а любой другой, то все, что ему нужно, &#8211; это перекрыть метод CDocTemplate::GetDocString() и при вызове в нем AfxExtractSubString() в качестве четвертого аргумента добавить значение символа-разделителя. И все!</p>
<p>Ну, и, наверное, последний вопрос о подготовке стандартного окна. Допустим, что мы в шаблоне указали интересующее нас рас­ширение файлов. Сможем ли мы в диалоговом окне открыть файл не только с этим расширением? Ответ на этот вопрос следует из текста метода DoPromptFileName(). Разработчики MFC предвиде­ли это. В ЛЮБОМ случае к списку фильтров добавляется фильтр для открытия любого файла «АН Files ( *.*)».</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/dopromptfilename.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Шаблон документа</title>
		<link>http://www.programmfc.ru/uncategorized/%d1%88%d0%b0%d0%b1%d0%bb%d0%be%d0%bd-%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/%d1%88%d0%b0%d0%b1%d0%bb%d0%be%d0%bd-%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:41:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CDocTemplate]]></category>
		<category><![CDATA[DoPromptFileName]]></category>
		<category><![CDATA[OnFileOpen]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d1%88%d0%b0%d0%b1%d0%bb%d0%be%d0%bd-%d0%b4%d0%be%d0%ba%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d0%b0.html</guid>
		<description><![CDATA[Мы разобрали назначение всех аргументов, за исключением пятого. Казалось бы, к чему при выдаче диалогового окна нам нуж­но знать шаблон документа? Да, наверное, весь шаблон нам знать ни к чему. Но не зря же мы ранее заметили, что шаблон документа является центром архитектуры «документ/представление» и хра­нилищем всей информации!
Обратите внимание, ува­жаемый читатель, что поэтому наш путь [...]]]></description>
			<content:encoded><![CDATA[<p>Мы разобрали назначение всех аргументов, за исключением пятого. Казалось бы, к чему при выдаче диалогового окна нам нуж­но знать шаблон документа? Да, наверное, весь шаблон нам знать ни к чему. Но не зря же мы ранее заметили, что шаблон документа является центром архитектуры «документ/представление» и хра­нилищем всей информации!</p>
<p>Обратите внимание, ува­жаемый читатель, что поэтому наш путь лежит к исходному тексту этой функции, кото­рый находится в файле docmgr.cpp:</p>
<p><b>AFX_STATIC void AFXAPI _AfxAppendFilterSuffix (</b></p>
<p><b>CStringS filter, OPENFILENAME&amp; ofn, CDocTemplate*pTemplate, CString* pstrDefaultExt)</b></p>
<p>{</p>
<p><b>ASSERT_VALID(pTemplate);</b></p>
<p><b>ASSERT_KINDOF(CDocTemplate, pTemplate);</b></p>
<p><b>CString strFilterExt, strFilterName;</b></p>
<p><b>if (pTemplate-&gt;GetDocString(strFilterExt,</b></p>
<p><b>CDocTemplate::filterExt) &amp;&amp; !strFilterExt.IsEmpty() &amp;&amp; pTemplate-&gt;GetDocString(strFilterName, CDocTemplate::filterName)&amp;&amp; !strFilterName.IsEmpty())</b></p>
<p>{</p>
<p><b>// a file based document template &#8211; add to filter list ASSERT(strFilterExt[0] == </b><b><sup>Л</sup></b><b>.&#8217;); if (pstrDefaultExt != NULL) {</b></p>
<p><b>// set the default extension</b></p>
<p><b>*pstrDefaultExt = ((LPCTSTR)strFilterExt) + 1;</b></p>
<p><b>// skip the </b><b><sup>Л</sup></b><b>.&#8217;</b></p>
<p><b>ofn.lpstrDefExt = (LPTSTR)(LPCTSTR)(*pstrDefaultExt); ofn.nFilterlndex = ofn.nMaxCustFilter + 1;</b></p>
<p><b>// 1 based number</b></p>
<p><b>// add to filter</b></p>
<p><b>filter += strFilterName; ASSERT (! filter. IsEmpty ());// must have a file type name filter += (TCHAR)&#8217;\0&#8242;; // next string please filter += (TCHAR)&#8217;*'; filter += strFilterExt;</b></p>
<p><b>filter += (TCHAR)&#8217;\0&#8242;; // next string please ofn.nMaxCustFilter++;</b></p>
<p>(CDocManager::OnFileOpen ) Сердцем этого метода яв-</p>
<p>I _____ ляются, в свою очередь, вы-</p>
<p><sup>|</sup>—<u>{ CDocManager::DoPromptFileName J</u> <sub>зовы</sub> методов CDocTem-</p>
<p>I—<u>{^AfxAppendFilterSuffix )</u> plate::GetDocString():</p>
<p>L-<u>[CDocTemplate::GetDocString]</u></p>
<p><b>BOOL CDocTemplate::GetDocString(CStrirvg&amp; rString,</b></p>
<p><b>enum DocStringlndex i) const</b></p>
<p>{</p>
<p><b>return AfxExtractSubString(rString, m_strDocStrings, (int)i); }</b></p>
<p>Несмотря на кажущуюся простоту вызова, здесь можно заме­тить кое-что интересное. Во-первых, в классе CDocTemplate есть перечисление DocStringlndex:</p>
<p><b>enum DocStringlndex {</b></p>
<p><b>windowTitle, // default window title</b></p>
<p><b>docName, // user visible name for default document</b></p>
<p><b>fileNewName, // user visible name for FileNew</b></p>
<p><b>// for file based documents:</b></p>
<p><b>filterName, // user visible name for FileOpen filterExt, // user visible extension for FileOpen // for file based documents with Shell open support: regFileTypeld, // REGEDIT visible registered</b></p>
<p><b>// file type identifier regFileTypeName, // Shell visible registered</b></p>
<p><b>// file type name</b></p>
<p>};</p>
<p><u>(CDocManager::OnFileOpen ]</u> Об этом перечислении мы</p>
<p>I <i><sub>r</sub></i><i> </i><b>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; v</b> достоточно скоро вспомним.</p>
<p><u>4CDocManager::DoPromptFileNam</u>eJ Во-вторых, наконец-то о се-</p>
<p>L-T_AfxAppendFilterSuffix <i>Л</i><i> </i>бе напоминает та строка,</p>
<p>[ <sub>(</sub> —----------------------- которую мы загрузили из ре-</p>
<p>L<u>{CDocTemplate::GetDocStringj</u> <sub>С</sub>у<sub>рс0</sub>в при создании шабло-</p>
<p>L_f AfxExtractSubstring] <sup>на</sup> Документа! Интересно</p>
<p>также, что в совокупности</p>
<p>именно с этой строкой индекс из перечисления передается функ­ции AfxExtractSubString(). Значит, этот индекс является либо номе­ром символа в строке, либо номером какой-то подстроки? Для того чтобы получить ответ и на этот вопрос, нам нужно лезть еще даль­ше в дебри MFC. Ниже я привожу определение (файл afxwin.h) и тек­ст (файл winstr.cpp) функции AfxExtractSubString():</p>
<p><b>BOOL AFXAPI AfxExtractSubString(CString&amp; rString, LPCTSTR IpszFullString, int iSubString, TCHAR chSep = </b><b>Лп</b><b>&#8216;);</b></p>
<p><b>BOOL AFXAPI AfxExtractSubString(CString&amp; rString,</b></p>
<p><b>LPCTSTR IpszFullString, int iSubString, TCHAR chSep)</b></p>
<p>{</p>
<p><b>if (IpszFullString == NULL) return FALSE;</b></p>
<p><b>while (iSubString—) {</b></p>
<p><b>IpszFullString = _tcschr(IpszFullString, chSep);</b></p>
<p><b>if (IpszFullString == NULL)</b></p>
<p>{</p>
<p><b>rString.Empty();</b> <b>// return empty string as well</b></p>
<p><b>return FALSE;</b></p>
<p>}</p>
<p><b>lpszFullString++;</b> <b>// point past the separator</b></p>
<p>}</p>
<p><b>LPCTSTR lpchEnd = _tcschr(IpszFullString, chSep); int nLen = (lpchEnd == NULL) ?</b></p>
<p><b>lstrlen(IpszFullString) : (int)(lpchEnd -</b></p>
<p><b>IpszFullString);</b></p>
<p><b>ASSERT(nLen &gt;= 0);</b></p>
<p><b>memcpy(rString.GetBufferSetLength(nLen),</b></p>
<p><b>IpszFullString,</b></p>
<p><b>nLen*sizedf&quot; (TCHAR) ) ; return TRUE;</b></p>
<p>}</p>
<p>Так вот оно что! Оказывается, строка, индекс ресурса которой мы указали при создании шаблона документа, состоит из подстрок! Каждая подстрока отделена от предыдущей символом-разделите­лем! Функции передается указатель на строку, состоящую из под­строк (второй аргумент), индекс подстроки (третий аргумент) и зна­чение символа-разделителя (по умолчанию это VT). Первый аргу­мент &#8211; это указатель на подстроку с соответствующим индексом. Если мы посмотрим на тексты DoPromptFileName() и __AfxAppend-FilterSuffix(), то придем к выводу, что пятая и четвертая подстроки хранят соответственно фильтр и название фильтра, используемые при формировании стандартного диалогового окна открытия фай­ла! Выскажем также предположение, что в перечислении DocString­lndex в некотором смысле определены назначения подстрок.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d1%88%d0%b0%d0%b1%d0%bb%d0%be%d0%bd-%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>Выбрать файл</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%b2%d1%8b%d0%b1%d1%80%d0%b0%d1%82%d1%8c-%d1%84%d0%b0%d0%b9%d0%bb.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%b2%d1%8b%d0%b1%d1%80%d0%b0%d1%82%d1%8c-%d1%84%d0%b0%d0%b9%d0%bb.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:40:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CDocTemplate]]></category>
		<category><![CDATA[DoPromptFileName]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%b2%d1%8b%d0%b1%d1%80%d0%b0%d1%82%d1%8c-%d1%84%d0%b0%d0%b9%d0%bb.html</guid>
		<description><![CDATA[Что нам для этого нужно сделать? Практически ничего. MFC уже подготовила за нас все необходимые данные, нам нужно только пару раз щелкнуть мышкой в диалоговом окне &#8211; и файл выбран! Есть, правда, два «но».
«Но» первое. Мы хотим знать «физику» процесса подготовки диалогового окна. «Но» второе &#8211; мы хотим изменить список выда­ваемых на отображение файлов, используя [...]]]></description>
			<content:encoded><![CDATA[<p>Что нам для этого нужно сделать? Практически ничего. MFC уже подготовила за нас все необходимые данные, нам нужно только пару раз щелкнуть мышкой в диалоговом окне &#8211; и файл выбран! Есть, правда, два «но».</p>
<p>«Но» первое. Мы хотим знать «физику» процесса подготовки диалогового окна. «Но» второе &#8211; мы хотим изменить список выда­ваемых на отображение файлов, используя для этого другой фильтр. Чтобы ответить на этот вопрос, нам, естественно, придет­ся опять лезть в дебри MFC, и, в частности, начать придется с ме­тода DoPromptFileName():</p>
<p><b>BOOL CDocManager::QpPromptFileName(CStringS fileName,</b></p>
<p><b>UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog,</b></p>
<p><b>CDocTemplate* pTemplate)</b></p>
<p><b>CFileDialog dlgFile(bOpenFileDialog);</b></p>
<p><b>CString title;</b></p>
<p><b>VERIFY(title.LoadString(nIDSTitle));</b></p>
<p><b>dlgFile,m_ofn.Flags |= lFlags;</b></p>
<p><b>CString strFilter; CString strDefault; if (pTemplate != NULL) {</b></p>
<p><b>ASSERT_VALID(pTemplate);</b></p>
<p><b>_Af xAppendFilterSuf f ix (strFilter, *~</b></p>
<p><b>dlgFile,m_ofn,</b></p>
<p><b>pTemplate,</b></p>
<p><b>&amp;strDefault);</b></p>
<p>}</p>
<p><b>else {</b></p>
<p><b>// do for all doc template</b></p>
<p><b>POSITION pos = m_templateList.GetHeadPosition() ; BOOL bFirst = TRUE;</b></p>
<p><b>while (pos != NULL) {</b></p>
<p><b>CDocTemplate* pTemplate =</b></p>
<p><b>(CDocTemplate*)m_templateList.GetNext(pos) ; _AfxAppendFilterSuffix(strFilter,</b></p>
<p><b>dlgFile.m_ofn, pTemplate, bFirst ? SstrDefault : NULL) ;</b></p>
<p><b>bFirst = FALSE;</b></p>
<p>}</p>
<p>}</p>
<p><b>// append the &quot;*.*&quot; all files filter CString allFilter;</b></p>
<p><b>VERIFY(allFilter.LoadString(AFX_IDS_ALLFILTER) ) ; strFilter += allFilter;</b></p>
<p><b>strFilter += (TCHAR)&#8217;\0&#8242;; // next string please strFilter += _T(<sup>XX</sup>*.*&quot;);</b></p>
<p><b>strFilter += (TCHAR)&#8217;\0&#8242;; // last string dlgFile.m_ofn.nMaxCustFilter++;</b></p>
<p><b>dlgFile.m_ofn.IpstrFilter = strFilter; dlgFile.m_ofn.IpstrTitle = title;</b></p>
<p><b>dlgFile.m_of</b><b>п</b><b>.IpstrFile = fileName.GetBuffer(_</b><b>МАХ</b><b>_</b><b>РАТН</b><b>);</b></p>
<p><b>int nResult = dlgFile.DoModal(); fileName.ReleaseBuffer(); return nResult == IDOK;</b></p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%b2%d1%8b%d0%b1%d1%80%d0%b0%d1%82%d1%8c-%d1%84%d0%b0%d0%b9%d0%bb.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Метод CWinApp::OnFileOpen</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cwinapponfileopen.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-cwinapponfileopen.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:40:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Архитектура]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[CWinApp]]></category>
		<category><![CDATA[DoPromptFileName]]></category>
		<category><![CDATA[OnFileOpen]]></category>
		<category><![CDATA[OpenDocumentFile]]></category>
		<category><![CDATA[Метод CWinApp]]></category>

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