<?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; Возможности MFC</title>
	<atom:link href="http://www.programmfc.ru/category/vozmozhnosti-mfc/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>Конструктор CCtrlView::CCtrlView</title>
		<link>http://www.programmfc.ru/vozmozhnosti-mfc/%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d0%be%d1%80-cctrlviewcctrlview.html</link>
		<comments>http://www.programmfc.ru/vozmozhnosti-mfc/%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d0%be%d1%80-cctrlviewcctrlview.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:53:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Возможности MFC]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d0%be%d1%80-cctrlviewcctrlview.html</guid>
		<description><![CDATA[Как легко заметить, конструктору CCtrlView::CCtrlView() в каче­стве параметра передается имя класса, которое тут же записыва­ется в поле m_strClass. Отметим этот факт. Затем в методе CFrameWnd::CreateView() вызывается метод Create() нашего объ­екта представления:
BOOL CWnd::Create(LPCTSTR IpszClassName, LPCTSTR IpszWindowName, DWORD dwStyle, const RECT&#38; rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
// can&#8217;t use for desktop or pop-up windows // (use [...]]]></description>
			<content:encoded><![CDATA[<p>Как легко заметить, конструктору CCtrlView::CCtrlView() в каче­стве параметра передается имя класса, которое тут же записыва­ется в поле m_strClass. Отметим этот факт. Затем в методе CFrameWnd::CreateView() вызывается метод Create() нашего объ­екта представления:</p>
<p><b>BOOL CWnd::Create(LPCTSTR IpszClassName, LPCTSTR IpszWindowName, DWORD dwStyle, const RECT&amp; rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)</b></p>
<p>{</p>
<p><b>// can&#8217;t use for desktop or pop-up windows // (use CreateEx instead) ASSERT(pParentWnd != NULL); ASSERT((dwStyle &amp; WS_POPUP) == </b>0); <b>return CreateEx (0,</b></p>
<p><b>IpszClassName,</b></p>
<p><b>IpszWindowName,</b></p>
<p><b>dwStyle </b>I <b>WS_CHILD,</b></p>
<p><b>rect.left, rect.top,</b></p>
<p><b>rect.right &#8211; rect.left,</b></p>
<p><b>rect.bottom &#8211; rect.top,</b></p>
<p><b>pParentWnd-&gt;GetSafeHwnd(),</b></p>
<p><b>(HMENU)nID,</b></p>
<p><b>(LPVOID)pContext);</b></p>
<p>}</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/vozmozhnosti-mfc/%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d0%be%d1%80-cctrlviewcctrlview.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/%d1%87%d1%82%d0%be-%d0%bf%d1%80%d0%be%d0%b8%d1%81%d1%85%d0%be%d0%b4%d0%b8%d1%82-%d0%bf%d1%80%d0%b8-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b5-%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d0%be.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d1%87%d1%82%d0%be-%d0%bf%d1%80%d0%be%d0%b8%d1%81%d1%85%d0%be%d0%b4%d0%b8%d1%82-%d0%bf%d1%80%d0%b8-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b5-%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d0%be.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:22:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Возможности MFC]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[Что происходит при работе конструктора?]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d1%87%d1%82%d0%be-%d0%bf%d1%80%d0%be%d0%b8%d1%81%d1%85%d0%be%d0%b4%d0%b8%d1%82-%d0%bf%d1%80%d0%b8-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b5-%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d0%be.html</guid>
		<description><![CDATA[Итак, что же происходит при работе конструктора? Естествен­но, инициализируются все поля объекта. Мы можем заметить, что поле m_nMode хранит режим работы архива, в поле m_pFile со­храняется указатель на объект класса CFile, на основе которого создан архив. Назначение остальных полей, надеюсь, мы поймем чуть позже. Обратите внимание, читатель, что среди инициализи­руемых полей есть поле m_bUserBuf, которому [...]]]></description>
			<content:encoded><![CDATA[<p>Итак, что же происходит при работе конструктора? Естествен­но, инициализируются все поля объекта. Мы можем заметить, что поле m_nMode хранит режим работы архива, в поле m_pFile со­храняется указатель на объект класса CFile, на основе которого создан архив. Назначение остальных полей, надеюсь, мы поймем чуть позже. Обратите внимание, читатель, что среди инициализи­руемых полей есть поле m_bUserBuf, которому присваивается зна­чение TRUE.</p>
<p>В том случае, если длина буфера, переданного конструктору, окажется менее 128 байтов, конструктор не будет использовать переданный ему буфер и сделает указатель на буфер равным NULL, а длину буфера сделает равной 128 байтам. Длина бу­фера сохраняется в поле m_nBufSize. После этого, в том случае, если указатель на буфер оказался равным NULL (например, при вызове конструктора использовался указатель по умолчанию или указанный при вызове конструктора размер буфера был меньше 128 байтов), то конструктор выделяет новый буфер тре­буемого размера, записывает указатель на буфер в поле mJpBufferStart и&#8230; Нам становится понятно назначение еще одного поля! Поле m_bUserBuf является флагом. Значение TRUE этого поля определяет, что объект будет использовать ранее подготовленный буфер, значение FALSE говорит о том, что бу­фер, используемый объектом, был создан во время работы кон­структора. Естественно, в том случае, когда конструктор са­мостоятельно выделяет буфер для работы, значение этого поля делается равным FALSE.</p>
<p>После того как все указатели проинициализированы, определяет­ся указатель на конец буфера. Этот указатель хранится в поле mJpBufMax. Но возникает вопрос &#8211; а зачем нам необходимо хра­нить две величины, фактически определяющие размер буфера &#8211; поле mjiBufSize и поле mJpBufSize? Вопрос закономерен, то отвечу я на него немного позже, ОК?</p>
<p>А затем происходит одна интересная вещь. Указатель на те­кущую позицию буфера (поле mJpBufCur) в том случае, если происходит чтение из архива, устанавливается на конец буфе­ра. В случае, если происходит запись в архив, указатель уста­навливается на начало буфера. Это, разумеется, не означает, что чтение или запись будут производиться в обратном поряд­ке. Нет, конечно, все гораздо проще. Если при операции чтения из архива в буфер указатель на текущую позицию буфера дос­тигает конца буфера, это означает, что буфер заполнен, читать больше некуда, и необходимо произвести некоторые действия для того, чтобы буфер можно было бы использовать повторно. Аналогично, если при записи из буфера в архив указатель на начало файла и на текущее позицию в буфере совпадают, то это означает, что все данные из буфера уже «сброшены» в ар­хив и что опять-таки необходимо произвести некоторые дейст­вия для того, чтобы заполнить буфер. Другими словами, поло­жение указателя является своеобразным флагом, вынуждающим метод произвести подготовку буфера к считыванию данных из архива или записи данных в архив.</p>
<p>Запись в архив и чтение из архива больших объемов информа­ции производится при помощи перегруженных операторов ««» и «»». В классе CArchive мы можем найти перегруженные опера­ции для чтения из архива и записи в архив переменных типа WORD, DWORD, float, double. Помимо этого предусмотрены операции за­писи в архив и чтения из архива строк. Для того, чтобы понять, как происходит чтение из архива и запись в архив примитивов, рас­смотрим, каким образом осуществляется запись в архив и чтение из архива переменной типа WORD.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d1%87%d1%82%d0%be-%d0%bf%d1%80%d0%be%d0%b8%d1%81%d1%85%d0%be%d0%b4%d0%b8%d1%82-%d0%bf%d1%80%d0%b8-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b5-%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d0%be.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Аргументы конструктора</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%b0%d1%80%d0%b3%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d1%8b-%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d0%be%d1%80%d0%b0.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%b0%d1%80%d0%b3%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d1%8b-%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d0%be%d1%80%d0%b0.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:22:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Возможности MFC]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[Аргументы]]></category>
		<category><![CDATA[Аргументы конструктора]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%b0%d1%80%d0%b3%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d1%8b-%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d0%be%d1%80%d0%b0.html</guid>
		<description><![CDATA[Первым аргументом конструктора является указатель на объ­ект класса CFile, на основе которого будет создан объект класса CArchive. Второй аргумент &#8211; это режим работы архива. Если вы заглянете в описание класса CArchive, то увидите в нем перечис­ление Mode, в котором как раз и приводятся значения, которые может принимать второй аргумент конструктора. В 14 приве­дено назначение каждого [...]]]></description>
			<content:encoded><![CDATA[<p>Первым аргументом конструктора является указатель на объ­ект класса CFile, на основе которого будет создан объект класса CArchive. Второй аргумент &#8211; это режим работы архива. Если вы заглянете в описание класса CArchive, то увидите в нем перечис­ление Mode, в котором как раз и приводятся значения, которые может принимать второй аргумент конструктора. В 14 приве­дено назначение каждого из этих режимов:</p>
<p>Режим работы архива, кстати, может быть получен при помощи методов lsl_oading()</p>
<p><b>_AFX_INLINE BOOL CArchive::IsLoading() const { return (m_nMode &amp; CArchive::load) != 0; }</b></p>
<p>и lsStoring()</p>
<p><b>_AFX_INLINE BOOL CArchive::IsStoring() const { return (m_nMode &amp; CArchive::load) == 0; }</b></p>
<p>Третий аргумент конструктора &#8211; это размер временного буфера, который будет использоваться для промежуточного хранения данных. По умолчанию размер буфера равен 4К (4096 байтов). Четвертым аргументом, как можно уже догадаться, является указатель на вре­менный буфер. По умолчанию указатель на буфер равен NULL, т. е. буфер по умолчанию создается самим конструктором.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%b0%d1%80%d0%b3%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d1%8b-%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d0%be%d1%80%d0%b0.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Конструктор класса CArchive</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d0%be%d1%80-%d0%ba%d0%bb%d0%b0%d1%81%d1%81%d0%b0-carchive.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d0%be%d1%80-%d0%ba%d0%bb%d0%b0%d1%81%d1%81%d0%b0-carchive.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:22:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Возможности MFC]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[Конструктор класса CArchive]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d0%be%d1%80-%d0%ba%d0%bb%d0%b0%d1%81%d1%81%d0%b0-carchive.html</guid>
		<description><![CDATA[Исходный текст конструктора клас-саа CArchive находится в файле агссоге.срр:

CArchive::CArchive(CFile* pFile, UINT nMode, int nBufSize, void* lpBuf) :
m_strFileName(pFile-&#62;GetFilePath() )
{
ASSERT_VALID(pFile);
// initialize members not dependent on allocated buffer
m_nMode = nMode; m_pFile = pFile; m_pSchemaMap = NULL; m_pLoadArray = NULL; m_pDocument = NULL; m_bForceFlat = TRUE;
m_nObjectSchema = (UINT)-l; // start with invalid schema
if (IsStoringO )
m_nGrowSize = nBlockSize; else
m_nGrowSize = [...]]]></description>
			<content:encoded><![CDATA[<p>Исходный текст конструктора клас-саа CArchive находится в файле агссоге.срр:</p>
<p style="text-align: center;"><img class="aligncenter" src="http://www.programmfc.ru/image/11.jpg" alt="Пример" width="362" height="271" /></p>
<p><strong>CArchive::CArchive(CFile* pFile, UINT nMode, int nBufSize, void* lpBuf) :</strong></p>
<p><strong>m_strFileName(pFile-&gt;GetFilePath() )</strong></p>
<p><strong>{</strong></p>
<p><strong>ASSERT_VALID(pFile);</strong></p>
<p><strong>// initialize members not dependent on allocated buffer</strong></p>
<p><strong>m_nMode = nMode; m_pFile = pFile; m_pSchemaMap = NULL; m_pLoadArray = NULL; m_pDocument = NULL; m_bForceFlat = TRUE;</strong></p>
<p><strong>m_nObjectSchema = (UINT)-l; // start with invalid schema</strong></p>
<p><strong>if (IsStoringO )</strong></p>
<p><strong>m_nGrowSize = nBlockSize; else</strong></p>
<p><strong>m_nGrowSize = nGrowSize; m_nHashSize = nHashSize;</strong></p>
<p><strong>// initialize the buffer. minimum size is 128 m_lpBufStart = (BYTE*)lpBuf; m_bUserBuf = TRUE; m_bDirectBuffer = FALSE;</strong></p>
<p><strong>if (nBufSize &lt; nBufSizeMin) {</strong></p>
<p><strong>// force use of private buffer of minimum size m_nBufSize = nBufSizeMin; m_lpBufStart = NULL;</strong></p>
<p><strong>}</strong></p>
<p><strong>else</strong></p>
<p><strong>m_nBufSize = nBufSize;</strong></p>
<p><strong>nBufSize = m_nBufSize; if (m_lpBufStart == NULL) {</strong></p>
<p><strong>// check for CFile providing buffering support m_bDirectBuffer =</strong></p>
<p><strong>m_pPile-&gt;GetBufferPtr(CFile::bufferCheck); if (!m_bDirectBuffer) {</strong></p>
<p><strong>// no support for direct buffering, // allocate new buffer m_lpBufStart = new BYTE[m_nBufSize]; m_bUserBuf = FALSE;</strong></p>
<p>}</p>
<p><strong>else {</strong></p>
<p><em>I/ </em><strong>CFile* supports direct buffering! nBufSize = 0; // will trigger initial FillBuffer</strong></p>
<p>}</p>
<p>}</p>
<p><strong>if (!m_bDirectBuffer) {</strong></p>
<p><strong>ASSERT(m_lpBufStart !=NULL);</strong></p>
<p><strong>ASSERT(AfxIsValidAddress(m_lpBufStart,</strong></p>
<p><strong>nBufSize, IsStoring()));</strong></p>
<p><strong>}</strong></p>
<p><strong>m_lpBufMax = m_lpBufStart + nBufSize;</strong></p>
<p><strong>m_lpBufCur = (IsLoading()) ? m_lpBufMax : m_lpBufStart;<br />
ASSERT (m_pStoreMap == NULL);</strong> <strong>// same as m_pLoadArray</strong></p>
<p>}</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%ba%d0%be%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%ba%d1%82%d0%be%d1%80-%d0%ba%d0%bb%d0%b0%d1%81%d1%81%d0%b0-carchive.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Класс CArchive</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%ba%d0%bb%d0%b0%d1%81%d1%81-carchive.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%ba%d0%bb%d0%b0%d1%81%d1%81-carchive.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:22:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Возможности MFC]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[Класс CArchive]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%ba%d0%bb%d0%b0%d1%81%d1%81-carchive.html</guid>
		<description><![CDATA[Естественно, что сериализация неразрывно связана с файла­ми. Но для осуществления сериализации объекты класса CFile слишком громоздки. Поэтому для сериализации используются так называемые архивы. Архив создается на базе файла и обеспечи­вает более удобные средства для осуществления записи объектов в файл. Класс CArchive в файле afx.h описан следующим образом:
class CArchive {
public:
// Flag values
enum Mode { store = [...]]]></description>
			<content:encoded><![CDATA[<p>Естественно, что сериализация неразрывно связана с файла­ми. Но для осуществления сериализации объекты класса CFile слишком громоздки. Поэтому для сериализации используются так называемые архивы. Архив создается на базе файла и обеспечи­вает более удобные средства для осуществления записи объектов в файл. Класс CArchive в файле afx.h описан следующим образом:</p>
<p><b>class CArchive {</b></p>
<p><b>public:</b></p>
<p><b>// Flag values</b></p>
<p><b>enum Mode { store = 0, load = </b><b><i>1</i></b><b><i><sub>Г</sub></i></b><b><i><sub></sub></i></b></p>
<p><b>bNoFlushOnDelete = 2, bNoByteSwap = 4 };</b></p>
<p><b>CArchive(CFile* pFile,</b></p>
<p><b>UINT nMode,</b></p>
<p><b>int nBufSize = 4096,</b></p>
<p><b>void* lpBuf = NULL); -CArchive();</b></p>
<p><b>// Attributes</b></p>
<p><b>BOOL IsLoadingO const; BOOL IsStoringO const; BOOL IsByteSwapping() const; BOOL IsBufferEmpty() const; CFile* GetFileO const;</b></p>
<p><b>UINT GetObjectSchema(); // only valid when reading</b></p>
<p><b>// a CObject* void SetObjectSchema(UINT nSchema);</b></p>
<p><b>// pointer to document being serialized — must set // to serialize COleClientltems in a document! CDocument* m_pDocument;</b></p>
<p><b>// Operations</b></p>
<p><b>UINT Read(void* lpBuf, UINT nMax);</b></p>
<p><b>void Write(const void* lpBuf, UINT nMax);</b></p>
<p><b>void Flush(); void Close();</b></p>
<p><b>void Abort(); // close and shutdown without exceptions</b></p>
<p><b>// reading and writing strings</b></p>
<p><b>void WriteString(LPCTSTR lpsz);</b></p>
<p><b>LPTSTR ReadString(LPTSTR lpsz, UINT nMax);</b></p>
<p><b>BOOL ReadString(CStringS rString);</b></p>
<p><b>public:</b></p>
<p><b>// Object I/O is pointer based to avoid added // construction overhead.</b></p>
<p><b>// Use the Serialize member function directly for // embedded objects.</b></p>
<p><b>friend CArchive&amp; AFXAPI operator«(CArchive&amp; ar,</b></p>
<p><b>const CObject* pOb);</b></p>
<p><b>friend CArchiveS AFXAPI operator»(CArchive&amp; ar,</b></p>
<p><b>CObject*&amp; pOb); friend CArchive&amp; AFXAPI operator&gt;&gt;(CArchive&amp; ar,</b></p>
<p><b>const CObject*&amp; pOb);</b></p>
<p><b>// insertion operations CArchive&amp; operator« (BYTE by) ; CArchiveS operator« (WORD w) ; CArchiveS operator« (LONG 1) ; CArchive&amp; operator« (DWORD dw) ; CArchiveS operator« (float f) ; CArchive&amp; operator« (double d) ; CArchive&amp; operator&lt;&lt; (int i); CArchive&amp; operator&lt;&lt;(short w); CArchive&amp; operator&lt;&lt; (char ch); CArchive&amp; operator&lt;&lt;(unsigned u);</b></p>
<p><b>// extraction operations CArchiveS operator» (BYTE&amp; by) ; CArchive&amp; operator&gt;&gt;(W0RD&amp; w); CArchive&amp; operator» (DWORDS dw) ; CArchive&amp; operator» (L0NG&amp; 1) ; CArchive&amp; operator» (floats f) ; CArchive&amp; operator&gt;&gt;(doubles d);</b></p>
<p><b>CArchive&amp; operator&gt;&gt;(int&amp; i);</b></p>
<p><b>CArchive&amp; operator&gt;&gt;(short&amp; w); CArchive&amp; operator&gt;&gt;(char&amp; ch); CArchive&amp; operator&gt;&gt;(unsigned&amp; u);</b></p>
<p><b>// object read/write</b></p>
<p><b>CObject* ReadObject(const CRuntimeClass* pClass); void WriteObject(const CObject* pOb);</b></p>
<p><b>// advanced object mapping (used for forced references) void MapObject(const CObject* pOb);</b></p>
<p><b>// advanced versioning support</b></p>
<p><b>void WriteClass(const CRuntimeClass* pClassRef);</b></p>
<p><b>CRuntimeClass* ReadClass(const CRuntimeClass*</b></p>
<p><b>pClassRefRequested = NULL, UINT* pSchema = NULL, DWORD* pObTag = NULL);</b></p>
<p><b>void SerializeClass(const CRuntimeClass* pClassRef);</b></p>
<p><b>// advanced operations (used when storing/loading // many objects)</b></p>
<p><b>void SetStoreParams(UINT nHashSize = 2053,</b></p>
<p><b>UINT nBlockSize = 128); void SetLoadParams(UINT nGrowBy = 1024);</b></p>
<p><b>// Implementation public:</b></p>
<p><b>BOOL m_bForceFlat; // for COleClientltem implementation</b></p>
<p><b>// (default TRUE) BOOL m_bDirectBuffer; // TRUE if m_pFile supports</b></p>
<p><b>// direct buffering void FillBuffer(UINT nBytesNeeded);</b></p>
<p><b>void CheckCount(); // throw exception if m_nMapCount</b></p>
<p><b>// is too large</b></p>
<p><b>// special functions for reading and writing</b></p>
<p><b>// (16-bit compatible) counts</b></p>
<p><b>DWORD ReadCount();</b></p>
<p><b>void WriteCount(DWORD dwCount);</b></p>
<p><b>// public for advanced use UINT m_nObjectSchema; CString m_strFileName;</b></p>
<p><b>protected:</b></p>
<p><b>// archive objects cannot be copied or assigned</b></p>
<p><b>CArchive(const CArchive&amp; arSrc);</b></p>
<p><b>void operator= (const CArchive&amp; arSrc);</b></p>
<p><b>BOOL m_nMode; BOOL m_bUserBuf; int m_nBufSize;</b></p>
<p><b>CFile* m_pFile;</b> <b>«&#8217;</b></p>
<p><b>BYTE* m_lpBufCur; BYTE* m_lpBufMax; BYTE* m_lpBufStart;</b></p>
<p><b>// array/map for CObject* and CRuntimeClass* load/store</b></p>
<p><b>UINT m_nMapCount;</b></p>
<p><b>union</b></p>
<p><b>{</b></p>
<p><b>CPtrArray* m_pLoadArray; CMapPtrToPtr* m_pStoreMap;</b></p>
<p><b>};</b></p>
<p><b>// map to keep track of mismatched schemas CMapPtrToPtr* mjpSchemaMap;</b></p>
<p><b>// advanced parameters (controls performance with // large archives) UINT m_nGrowSize; UINT m_nHashSize;</b></p>
<p><b>};</b></p>
<p>Давайте попробуем разобраться в принципах работы архива. Для того чтобы создать архив, необходимо, естественно, восполь­зоваться конструктором класса. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%ba%d0%bb%d0%b0%d1%81%d1%81-carchive.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Сериализация и архивы</title>
		<link>http://www.programmfc.ru/uncategorized/%d1%81%d0%b5%d1%80%d0%b8%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b8-%d0%b0%d1%80%d1%85%d0%b8%d0%b2%d1%8b.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d1%81%d0%b5%d1%80%d0%b8%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b8-%d0%b0%d1%80%d1%85%d0%b8%d0%b2%d1%8b.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:21:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Возможности MFC]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d1%81%d0%b5%d1%80%d0%b8%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b8-%d0%b0%d1%80%d1%85%d0%b8%d0%b2%d1%8b.html</guid>
		<description><![CDATA[Иногда программе может потребоваться сохранить данные, сфор­мированные в каком-то виде в оперативной памяти, на каком-то устройстве, обеспечивающем длительное хранение данных. Таки­ми устройствами могут быть дискета, винчестер, компакт-диск и т.д. При этом программа должен обеспечить сохранение текущего со­стояния совокупности своих объектов таким образом, чтобы затем, при повторном запуске программы, текущее состояние объектов могло бы быть полностью [...]]]></description>
			<content:encoded><![CDATA[<p>Иногда программе может потребоваться сохранить данные, сфор­мированные в каком-то виде в оперативной памяти, на каком-то устройстве, обеспечивающем длительное хранение данных. Таки­ми устройствами могут быть дискета, винчестер, компакт-диск и т.д. При этом программа должен обеспечить сохранение текущего со­стояния совокупности своих объектов таким образом, чтобы затем, при повторном запуске программы, текущее состояние объектов могло бы быть полностью восстановлено. Совокупность действий, обеспечивающих, с одной стороны, сохранение текущих данных в форме, позволяющей последующее восстановление, и, с другой стороны, непосредственно восстановление текущего состояния данных, называется сериализацией.</p>
<p>Для того чтобы реализовать сериализацию, можно пойти при­вычным путем &#8211; в программе создать файл, затем при помощи стан­дартных операций записи в файл «сбросить» в него данные, потом при помощи таких же стандартных операций считать данные. Но де­ло в том, что программе придется работать не с объектами, а с не­которыми блоками памяти или, на худой конец, со строками. Все будет работать нормально, но каждый раз придется считать, какую переменную куда записать, помнить о формате записанной инфор­мации&#8230; Ужас!</p>
<p>Можно, конечно, пойти другим путем. В каждой программе раз­работать методы, реализующие сериализацию для каждого кон­кретного класса. Можно при этом использовать уже имеющиеся в языках средства для записи данных в файл.</p>
<p>Но я не зря выше употребил слово «стандартные». Дело в том, что MFC позволяет программистам использовать процедуры се-риализации, которые являются стандартными для MFC. Конечно, процедуру сериализации для всех возможных объектов и органи­зованных в памяти структур данных написать невозможно, но впол­не возможно определить порядок применения процедур сериали-зации, описать интерфейсы и т.д.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d1%81%d0%b5%d1%80%d0%b8%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b8-%d0%b0%d1%80%d1%85%d0%b8%d0%b2%d1%8b.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Интересный факт</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%b8%d0%bd%d1%82%d0%b5%d1%80%d0%b5%d1%81%d0%bd%d1%8b%d0%b9-%d1%84%d0%b0%d0%ba%d1%82.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%b8%d0%bd%d1%82%d0%b5%d1%80%d0%b5%d1%81%d0%bd%d1%8b%d0%b9-%d1%84%d0%b0%d0%ba%d1%82.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:21:16 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Возможности MFC]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[Интересный факт]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%b8%d0%bd%d1%82%d0%b5%d1%80%d0%b5%d1%81%d0%bd%d1%8b%d0%b9-%d1%84%d0%b0%d0%ba%d1%82.html</guid>
		<description><![CDATA[Обратите внимание на один интересный факт. В том случае, если в сумме указатель файла и число записываемых байтов пре­вышают размер файла, вызывается метод GrowFile(), т. е. размер файла динамически увеличивается. Затем метод вызывает Метсру(), который непосредственно осуществляет копирование из буфера в файл в памяти. Никакого значения метод WriteQ не возвращает.
Метод работает подобно методу Read(), отличие [...]]]></description>
			<content:encoded><![CDATA[<p>Обратите внимание на один интересный факт. В том случае, если в сумме указатель файла и число записываемых байтов пре­вышают размер файла, вызывается метод GrowFile(), т. е. размер файла динамически увеличивается. Затем метод вызывает Метсру(), который непосредственно осуществляет копирование из буфера в файл в памяти. Никакого значения метод WriteQ не возвращает.</p>
<p>Метод работает подобно методу Read(), отличие состоит только в направлении перемещения информации. Кроме этого, метод Write() не возвращает никакого значения.</p>
<p>Перед тем как завершить рассмотрение класса CMemFile, не­обходимо заметить, что методы LockRange(), UnlockRange() и Duplicate(), унаследованные от класса CFile, не поддерживаются. Обращение к ним немедленно приводит к выработке исключения.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%b8%d0%bd%d1%82%d0%b5%d1%80%d0%b5%d1%81%d0%bd%d1%8b%d0%b9-%d1%84%d0%b0%d0%ba%d1%82.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Метод Write</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-write-2.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-write-2.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:21:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Возможности MFC]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>
		<category><![CDATA[Метод Write]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-write-2.html</guid>
		<description><![CDATA[Методу Write(), который используется для записи данных из бу­фера памяти в файл, в качестве аргументов также передаются указатель на буфер в памяти, данные из которого должны быть занесены в файл, и количество записываемых байтов. Исходный код метода находится в файле filemem.cpp:
void CMemFile::Write(const void* lpBuf, UINT nCount) {
ASSERT_VALID(this);
if (nCount == 0) return;
ASSERT(lpBuf != NULL);
ASSERT(AfxIsValidAddress(lpBuf, nCount, FALSE));
if [...]]]></description>
			<content:encoded><![CDATA[<p>Методу Write(), который используется для записи данных из бу­фера памяти в файл, в качестве аргументов также передаются указатель на буфер в памяти, данные из которого должны быть занесены в файл, и количество записываемых байтов. Исходный код метода находится в файле filemem.cpp:</p>
<p>void CMemFile::Write(const void* lpBuf, UINT nCount) {</p>
<p>ASSERT_VALID(this);</p>
<p>if (nCount == <b>0) </b>return;</p>
<p>ASSERT(lpBuf != NULL);</p>
<p>ASSERT(AfxIsValidAddress(lpBuf, nCount, FALSE));</p>
<p>if (m_nPosition + nCount &gt; m_nBufferSize) GrowFile(m_nPosition + nCount);</p>
<p>ASSERT(m_nPosition + nCount &lt;= m_nBufferSize);</p>
<p>Memcpy((BYTE*)m_lpBuffer + m_nPosition, (BYTE*)lpBuf, nCount);</p>
<p>m_nPosition += nCount;</p>
<p>if (m_nPosition &gt; m_nFileSize) m_nFileSize = m_nPosition;</p>
<p>ASSERT_VALID(this);</p>
<p><b>}</b></p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-write-2.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Метод Метсру</title>
		<link>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-%d0%bc%d0%b5%d1%82%d1%81%d1%80%d1%83.html</link>
		<comments>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-%d0%bc%d0%b5%d1%82%d1%81%d1%80%d1%83.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:20:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Возможности MFC]]></category>
		<category><![CDATA[Первая программа на MFC]]></category>

		<guid isPermaLink="false">http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-%d0%bc%d0%b5%d1%82%d1%81%d1%80%d1%83.html</guid>
		<description><![CDATA[В качестве аргументов методу передаются указатель на бу­фер, в который будет считана информация из файла в памяти, а также число байтов, подлежащих считыванию. В случае, если число считываемых байтов равно нулю, метод немедленно воз­вращает нуль. Если по каким-то причинам указатель файла ока­зался больше размера файла, метод также возвращает нуль. Если число байтов от указателя файла [...]]]></description>
			<content:encoded><![CDATA[<p>В качестве аргументов методу передаются указатель на бу­фер, в который будет считана информация из файла в памяти, а также число байтов, подлежащих считыванию. В случае, если число считываемых байтов равно нулю, метод немедленно воз­вращает нуль. Если по каким-то причинам указатель файла ока­зался больше размера файла, метод также возвращает нуль. Если число байтов от указателя файла до конца файла превы­шает или равно числу подлежащих считыванию байтов, то бу­дет осуществлена попытка считать указанное количество бай­тов. В противном случае считываться будут только байты, нахо­дящиеся между указателем файла и концом файла. При помо­щи метода Метсру() производится копирование данных из фай­<i>па </i>в памяти в буфер, после чего указатель файла увеличивается на число считанных байтов. Метод возвращает число успешно считанных байтов.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.programmfc.ru/uncategorized/%d0%bc%d0%b5%d1%82%d0%be%d0%b4-%d0%bc%d0%b5%d1%82%d1%81%d1%80%d1%83.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
