﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Tinysun-随笔分类-VC++/MFC</title><link>http://www.blogjava.net/tinysun/category/37794.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 03 Apr 2009 05:04:11 GMT</lastBuildDate><pubDate>Fri, 03 Apr 2009 05:04:11 GMT</pubDate><ttl>60</ttl><item><title>VC常用插件</title><link>http://www.blogjava.net/tinysun/archive/2009/03/31/263238.html</link><dc:creator>何克勤</dc:creator><author>何克勤</author><pubDate>Tue, 31 Mar 2009 13:50:00 GMT</pubDate><guid>http://www.blogjava.net/tinysun/archive/2009/03/31/263238.html</guid><wfw:comment>http://www.blogjava.net/tinysun/comments/263238.html</wfw:comment><comments>http://www.blogjava.net/tinysun/archive/2009/03/31/263238.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tinysun/comments/commentRss/263238.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tinysun/services/trackbacks/263238.html</trackback:ping><description><![CDATA[转http://zhouhuishine.i170.cn/Article_37710<br />
1.Visual&nbsp;Assist（强烈推荐）<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.wholetomato.com/" target="_blank"><u><font color="#0000ff">http://www.wholetomato.com/</font></u></a><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VA从5.0一直到现在的VAX，功能越来越强大，除了以前版本中的自动识别各种关键字，系统函数，成员变量，自动给出输入提示，自动更正大小写错误，自动标示错误等等以外，最新的版本中还在<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WorkSpace窗口中加入一个VA&nbsp;View，可以更方便的查找工程中的文件、类和变量。<br />
<br />
&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;2.WndTabs（强烈推荐）<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.wndtabs.com/" target="_blank"><u><font color="#0000ff">http://www.wndtabs.com/</font></u></a><br />
<br />
WndTabs主要是在编辑窗口中显示了所有已经打开的文件，在VC中能够更方便的操作这些文件，比如修改文件属性，copy文件路径、文件名等，并且还开放源代码，你要是愿意的话，可以添加自己很兴趣的功能。<br />
<br />
&nbsp;<br />
<br />
3.LineCounter<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.wndtabs.com/" target="_blank"><u><font color="#0000ff">http://www.wndtabs.com/</font></u></a><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;用来统计整个工程的代码行数，包括总行数、代码行数、注释行数、空行数等，并且对多个工程一起统计时，不会把相同的文件计算多次.<br />
<br />
&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4.Spelly<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.wndtabs.com/" target="_blank"><u><font color="#0000ff">http://www.wndtabs.com/</font></u></a>&nbsp;<br />
<br />
一个拼写检查的插件，可以对整个文件或所选部分进行拼写检查，支持C/C++/C#,&nbsp;VB,&nbsp;Fortran&nbsp;和HTML。<br />
<br />
&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.SourceStyler&nbsp;C++<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.sourcestyler.com/" target="_blank"><u><font color="#0000ff">http://www.sourcestyler.com/</font></u></a><br />
<br />
此插件是针对C++的一个格式化工具，可以针对自己的编码习惯，选择一种编码风格，也可以自己定义，而且定义非常详细，有表达式、指针、模板、类、枚举等十几种，肯定能满足你的需要。<br />
<br />
<br />
&nbsp;<br />
<br />
6.Numega&nbsp;BoundsChecker（强烈推荐）<br />
<br />
下载：百度一下&#8230;&#8230;<br />
<br />
是针对Visual&nbsp;C++6.0应用程序的最为全面的错误检测工具。BoundsChecker&nbsp;能自动指出静态，堆栈内存错误和资源泄漏问题。BoundsChecker&nbsp;能够校验最新的&nbsp;Windows&nbsp;APIs，包括&nbsp;ActiveX,&nbsp;DirectX,&nbsp;OLE/COM,&nbsp;ODBC等等。能够发现与&nbsp;Windows&nbsp;平台兼容性。<br />
<br />
&nbsp;<br />
<br />
7.BCGControlBar&nbsp;Library&nbsp;<br />
<br />
下载：百度一下&#8230;&#8230;<br />
<br />
非常好的一套应用于vc6的界面扩展类库，轻松的作出&nbsp;vc2003&nbsp;的界面。并且给了各种界面例子，如vc.net、outlook、更换皮肤等等。<br />
<br />
&nbsp;<br />
<br />
8.Comment&nbsp;Wizard<br />
<br />
下载：百度一下&#8230;&#8230;<br />
<br />
Visual&nbsp;C++插件，提供了Visual&nbsp;C++源代码注解标准化与自动化功能。在它的帮助下，您可快速创建标头文件信息注解，文件中模块注解，&nbsp;C++处理方式，以及Ｃ语言功能与历史校正功能注解，等等。<br />
<input id="articleView_Plugin_Type_input" type="hidden" value="-1" />
<img src ="http://www.blogjava.net/tinysun/aggbug/263238.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tinysun/" target="_blank">何克勤</a> 2009-03-31 21:50 <a href="http://www.blogjava.net/tinysun/archive/2009/03/31/263238.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MFC单文档视图穷追猛打</title><link>http://www.blogjava.net/tinysun/archive/2008/11/29/243431.html</link><dc:creator>何克勤</dc:creator><author>何克勤</author><pubDate>Sat, 29 Nov 2008 08:34:00 GMT</pubDate><guid>http://www.blogjava.net/tinysun/archive/2008/11/29/243431.html</guid><wfw:comment>http://www.blogjava.net/tinysun/comments/243431.html</wfw:comment><comments>http://www.blogjava.net/tinysun/archive/2008/11/29/243431.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tinysun/comments/commentRss/243431.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tinysun/services/trackbacks/243431.html</trackback:ping><description><![CDATA[<p align="center">MFC单文档/视图结构穷追猛打</p>
<p>目录</p>
<p>第一章找回WinMain函数&nbsp;2<br />
第二章InitApplication()函数&nbsp;2<br />
第三章InitInstance ()函数&nbsp;3<br />
第一节：new CSingleDocTemplate&nbsp;3<br />
第二节：AddDocTemplate(pDocTemplate);&nbsp;5<br />
第三节：ProcessShellCommand(cmdInfo)&nbsp;5<br />
第一段AfxGetApp()-&gt;OnCmdMsg(&#8230;)&nbsp;6<br />
第二段OnFileNew();&nbsp;6<br />
第四节 ：m_pMainWnd-&gt;ShowWindow(SW_SHOW); ///显示窗口&nbsp;8<br />
第五节 ：m_pMainWnd-&gt; UpdateWindow (); ///重画窗口&nbsp;8<br />
第四章pApp-&gt;Run函数&nbsp;8<br />
第五章总结&nbsp;8</p>
<p>&nbsp; 本文将针对一个单文档来描述MFC的文档/视图结构，他直接打开MFC的源代码进行分析，在分析过程中去掉了无关的部分。所以第一步就是要创建一个称为First得工程，文档类型是单文档，下文将围绕这个工程来讲的。<br />
第一章找回WinMain函数<br />
首先在<a href="http://dev.21tx.com/language/vc/" target="_blank">VC</a>的安装路径中找到WINMAIN.CPP文件，AfxWinMain函数就是VC编译器的入口，去掉一些不重要的东西后得到如下得程序。<br />
int AFXAPI AfxWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow)<br />
{<br />
int nReturnCode = -1;<br />
CWinApp* pApp = AfxGetApp(); ///获取应用程序类的指针与文档视图无关。<br />
AfxWinInit(hInstance, hPrevInstance,lpCmdLine,nCmdShow); ///与文档视图无关。<br />
pApp-&gt;InitApplication();&nbsp; ///初始化应用程序详见下文。<br />
pApp-&gt;InitInstance();&nbsp;&nbsp;&nbsp;&nbsp; ///最重要下面祥述<br />
nReturnCode = pApp-&gt;Run();///消息循环直到应用程序被关闭。与文档视图无关。<br />
AfxWinTerm();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ///与文档视图无关。<br />
return nReturnCode;///整个应用结束。<br />
}<br />
下面分节讲述。<br />
第二章InitApplication()函数<br />
在文件Appcore.cpp文件中InitApplication如下：<br />
BOOL CWinApp::InitApplication()<br />
{<br />
&nbsp;if (CDocManager::pStaticDocManager != NULL)&nbsp;&nbsp; ///这段和我们关系不大,暂时不理它<br />
&nbsp;{<br />
&nbsp;&nbsp;if (m_pDocManager == NULL)<br />
&nbsp;&nbsp;&nbsp;m_pDocManager = CDocManager::pStaticDocManager;<br />
&nbsp;&nbsp;CDocManager::pStaticDocManager = NULL;<br />
&nbsp;}</p>
<p>&nbsp;if (m_pDocManager != NULL)<br />
&nbsp;&nbsp;m_pDocManager-&gt;AddDocTemplate(NULL);<br />
&nbsp;else<br />
&nbsp;&nbsp;CDocManager::bStaticInit = FALSE;&nbsp; /*我们的程序将会执行到这句,表示文档类用动态方式创建,也就是说用RUNTIME_CLASS来创建的(详见下文)。*/<br />
&nbsp;return TRUE;<br />
}<br />
&nbsp; 说明：CDocManager类是一个不公开的类，他主要用来管理多文档模板对象的，对于单文档只有一个文档模板这个类不是很重要，但还是用它管理文档模板的；本文只在相关之处作说明。bStaticInit是它的一个静态成员。<br />
第三章InitInstance ()函数<br />
&nbsp; 它一般被重载，在First工程中，InitInstance中和文档视图类有关的程序有下面的一些：</p>
<p>&nbsp;CSingleDocTemplate* pDocTemplate;&nbsp; ///定义指针<br />
&nbsp;pDocTemplate = new CSingleDocTemplate(<br />
&nbsp;&nbsp;IDR_MAINFRAME,<br />
&nbsp;&nbsp;RUNTIME_CLASS(CFirstDoc),<br />
&nbsp;&nbsp;RUNTIME_CLASS(CMainFrame),<br />
&nbsp;&nbsp;RUNTIME_CLASS(CFirstView));&nbsp;&nbsp;&nbsp; ///这条语句的作用见第一段<br />
&nbsp;AddDocTemplate(pDocTemplate);</p>
<p>&nbsp;CCommandLineInfo cmdInfo;&nbsp;&nbsp;&nbsp; ///定义一个对象<br />
&nbsp;ParseCommandLine(cmdInfo);&nbsp;&nbsp;&nbsp; ///解析命令行并发送参数，与文档视图无关</p>
<p>&nbsp;if (!ProcessShellCommand(cmdInfo))&nbsp;&nbsp; ///这是最重要的详见的三段<br />
&nbsp;&nbsp;return FALSE;</p>
<p>&nbsp;m_pMainWnd-&gt;ShowWindow(SW_SHOW);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ///显示窗口<br />
&nbsp;m_pMainWnd-&gt;UpdateWindow();<br />
第一节：new CSingleDocTemplate<br />
new CSingleDocTemplate其实就是创建一个CSingleDocTemplate对象并调用他的构造函数，要讲清楚这句话，首先必须明白RUNTIME_CLASS结构，RUNTIME_CLASS结构定义如下：<br />
#define RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&amp;class_name::class##class_name))<br />
于是这句话展开后如下(关于符合##的具体意义参见MSDN)：<br />
&nbsp;pDocTemplate = new CSingleDocTemplate(<br />
IDR_MAINFRAME,<br />
(CRuntimeClass*)(&amp;CFirstDoc::classCFirstDoc),<br />
(CRuntimeClass*)(&amp;CMainFrame::classCMainFrame),<br />
(CRuntimeClass*)(&amp;CFirstView::classCFirstView));<br />
这时我们会发现CfirstDoc，CmainFrame，CfirstView各会多冒出一个静态成员出来，它究竟在哪里呢？查看这三个类的定义我们会发现每个类定义都有一个宏DECLARE_DYNCREATE，在实现文件中有另外一个宏IMPLEMENT_DYNCREATE。下面把这些宏的展开情况列出如下：<br />
（1）文档类<br />
DECLARE_DYNCREATE(CFirstDoc) 展开后为：<br />
public:&nbsp; <br />
&nbsp;static const CRuntimeClass classCFirstDoc; ///这就是上面所说的那个静态成员<br />
&nbsp;virtual CRuntimeClass* GetRuntimeClass() const; <br />
&nbsp;static CObject* PASCAL CreateObject();</p>
<p>IMPLEMENT_DYNCREATE(CFirstDoc, CDocument)&nbsp; 展开后为：<br />
&nbsp;CObject* PASCAL CFirstDoc::CreateObject()<br />
&nbsp;&nbsp;{ return new CFirstDoc; }<br />
&nbsp;const CRuntimeClass CFirstDoc::classCFirstDoc= { <br />
&nbsp;&nbsp;"CFirstDoc", sizeof(class CFirstDoc), 0xFFFF, CFirstDoc::CreateObject, &nbsp;&nbsp;&nbsp;(CRu<br />
ntimeClass*)(&amp;CDocument::classCDocument), NULL };<br />
&nbsp;CRuntimeClass* CFirstDoc::GetRuntimeClass() const <br />
&nbsp;&nbsp;{ return (CRuntimeClass*)(&amp;CFirstDoc::classCFirstDoc); } <br />
（2）视图类<br />
DECLARE_DYNCREATE(CFirstView)&nbsp; 展开后为：<br />
public:&nbsp; <br />
&nbsp;static const CRuntimeClass classCFirstView; <br />
&nbsp;virtual CRuntimeClass* GetRuntimeClass() const; <br />
&nbsp;static CObject* PASCAL CreateObject();</p>
<p>IMPLEMENT_DYNCREATE(CFirstView, CView)&nbsp; 展开后为：<br />
&nbsp;CObject* PASCAL CFirstView::CreateObject()<br />
&nbsp;&nbsp;{ return new CFirstView; }<br />
&nbsp;const CRuntimeClass CFirstView::classCFirstView = { <br />
&nbsp;&nbsp;" CFirstView ", sizeof(class CFirstView), 0xFFFF, CFirstView::CreateObject, &nbsp;&nbsp;&nbsp;(CRu<br />
ntimeClass*)(&amp;CView::classCView), NULL };<br />
&nbsp;CRuntimeClass* CFirstView::GetRuntimeClass() const <br />
&nbsp;&nbsp;{ return (CRuntimeClass*)(&amp; CFirstView::classCFirstView); } <br />
（3）主框架类<br />
DECLARE_DYNCREATE(CMainFrame)&nbsp; 展开后为：<br />
public:&nbsp; <br />
&nbsp;static const CRuntimeClass classCMainFrame; <br />
&nbsp;virtual CRuntimeClass* GetRuntimeClass() const; <br />
&nbsp;static CObject* PASCAL CreateObject();</p>
<p>IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)&nbsp; 展开后为：<br />
&nbsp;CObject* PASCAL CMainFrame::CreateObject()<br />
&nbsp;&nbsp;{ return new CMainFrame; }<br />
&nbsp;const CRuntimeClass CMainFrame::classCMainFrame = { <br />
&nbsp;&nbsp;"CMainFrame", sizeof(class CMainFrame), 0xFFFF, CMainFrame::CreateObject, &nbsp;&nbsp;&nbsp;(CRu<br />
ntimeClass*)(&amp; CFrameWnd::classCFrameWnd), NULL };<br />
&nbsp;CRuntimeClass* CMainFrame::GetRuntimeClass() const <br />
&nbsp;&nbsp;{ return (CRuntimeClass*)(&amp;CMainFrame::classCMainFrame); } </p>
<p>&nbsp; 这些宏首先在你的定义文件中定义一个以class+类名为名字的静态变量。然后定义一个返回这个静态变量的函数GetRuntimeClass并在实现文件中实现之。最后定义并实现一个创建对象的函数CreateObject。</p>
<p>好了，我们现在就来看看CSingleDocTemplate对象的构造函数做了些什么：下面是他的实现<br />
CSingleDocTemplate::CSingleDocTemplate(UINT nIDResource,<br />
&nbsp;CRuntimeClass* pDocClass, CRuntimeClass* pFrameClass,<br />
&nbsp;CRuntimeClass* pViewClass)<br />
&nbsp;&nbsp;: CDocTemplate(nIDResource, pDocClass, pFrameClass, pViewClass)<br />
{<br />
&nbsp;m_pOnlyDoc = NULL;<br />
}<br />
它主要是初始化他的父类CDocTemplate,CDocTemplate做了些什么？如下：<br />
{<br />
&lt;1&gt;把资源ID及文档、框架、视图的三个CRuntimeClass结构的静态成员的地址(也就是传进来的四个参数) 保存了起来。<br />
&lt;2&gt;LoadTemplate();///为指定的文档模板对象装载资源<br />
}<br />
至此这个new语句总算讲完了。<br />
第二节：AddDocTemplate(pDocTemplate);<br />
下面是他的实现函数<br />
void CWinApp::AddDocTemplate(CDocTemplate* pTemplate)<br />
{<br />
&nbsp;if (m_pDocManager == NULL)<br />
m_pDocManager = new CDocManager; /*创建一个文档管理类，对于单文档常常只有一个文档模板用CDocManager类并不是很重要,我们可以忽略这句*/<br />
&nbsp;m_pDocManager-&gt;AddDocTemplate(pTemplate); /*把文档模板指针保存在CDocManager实例中由CDocManager去管理他,我们只要知道有这个事就行了*/<br />
}<br />
第三节：ProcessShellCommand(cmdInfo)<br />
&nbsp;&nbsp; 这个函数发送的一个命令就是FileNew其他的暂时不管他，其实所有的文档类，框架类，视图类都是在这个函数中创建的，在第一段中已经讲到应用程序类将上三个类的CRuntimeClass一个静态成员地址保存起来了，关于CRuntimeClass结构的具体功能参照MSDN。<br />
ProcessShellCommand描述如下:<br />
BOOL CWinApp::ProcessShellCommand(CCommandLineInfo&amp; rCmdInfo)<br />
{<br />
&nbsp;BOOL bResult = TRUE;<br />
&nbsp;switch (rCmdInfo.m_nShellCommand)<br />
&nbsp;{<br />
&nbsp;case CCommandLineInfo::FileNew:<br />
&nbsp;&nbsp;if (!AfxGetApp()-&gt;OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL))<br />
&nbsp;&nbsp;&nbsp;OnFileNew();<br />
&nbsp;&nbsp;if (m_pMainWnd == NULL)<br />
&nbsp;&nbsp;&nbsp;bResult = FALSE;<br />
&nbsp;&nbsp;break;<br />
&nbsp;case CCommandLineInfo::FileOpen:<br />
&nbsp;&nbsp;if (!OpenDocumentFile(rCmdInfo.m_strFileName))<br />
&nbsp;&nbsp;&nbsp;bResult = FALSE;<br />
&nbsp;&nbsp;break;<br />
&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.///还有很多消息处理略去<br />
&nbsp;}<br />
&nbsp;return bResult;<br />
}<br />
第一段AfxGetApp()-&gt;OnCmdMsg(&#8230;)<br />
AfxGetApp()-&gt;OnCmdMsg主要是派发命令消息，跟我们关系最大的消息是菜单命令ID_FILE_NEW，下面讲述他的处理函数OnFileNew<br />
第二段OnFileNew();<br />
&nbsp;OnFileNew只是简单的调用文档管理对象的同名函数,他的描述如下：<br />
void CWinApp::OnFileNew()<br />
{<br />
&nbsp;if (m_pDocManager != NULL)<br />
&nbsp;&nbsp;m_pDocManager-&gt;OnFileNew();///只是调用CDocManager::OnFileNew<br />
}<br />
文档管理类的OnFileNew去掉一些没用的东西后实现如下：<br />
void CDocManager::OnFileNew()<br />
{<br />
&nbsp;CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetHead();/*获得第一个文档模板,对于单文档只有一个文档模板*/<br />
&nbsp;if (m_templateList.GetCount() &gt; 1)///对单文档这段没用<br />
&nbsp;{<br />
&nbsp;&nbsp;CNewTypeDlg dlg(&amp;m_templateList);<br />
&nbsp;&nbsp;int nID = dlg.DoModal();<br />
&nbsp;&nbsp;if (nID == IDOK)<br />
&nbsp;&nbsp;&nbsp;pTemplate = dlg.m_pSelectedTemplate;<br />
&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;return;&nbsp;&nbsp;&nbsp;&nbsp; /// none - cancel operation<br />
&nbsp;}<br />
&nbsp;pTemplate-&gt;OpenDocumentFile(NULL);/*其实是调用CSingleDocTemplate::OpenDocumentFile函数下面祥述这里,因为在CDocTemplate 类中这个函数是一个纯虚函数*/<br />
}<br />
下面简述pTemplate-&gt;OpenDocumentFile(NULL);这个函数，<br />
这是最重要的一个函数,他执行了如下6个步骤：</p>
<p>&lt;1&gt;pDocument = CreateNewDocument();///创建一个新文档<br />
&nbsp;&nbsp; {<br />
CDocument* pDocument = (CDocument*)m_pDocClass-&gt;CreateObject();/*这是才真正的创建文档对象，这里创建的文档对象就是上面RUNTIME_CLASS(CFirstDoc),中的对象这是MFC开发人员想出来的一种运行时创建对象的方法，应该说比较不错的,不知道<a href="http://dev.21tx.com/language/c/" target="_blank">C++</a>Builder的是怎样构造的。*/<br />
&nbsp;&nbsp;AddDocument(pDocument);&nbsp; ///把创建的对象指针记录下来，以后还要用的。<br />
}<br />
&lt;2&gt; pFrame = CreateNewFrame(pDocument, NULL);&nbsp; /*根据新文档指针创建新文档框架,这个比较重要下一段描述*/<br />
&lt;3&gt;SetDefaultTitle(pDocument);&nbsp; ///设置缺省标题，不重要的<br />
&lt;4&gt;pDocument-&gt;OnNewDocument()&nbsp;&nbsp; ///清除老文档内容<br />
{<br />
&nbsp;DeleteContents();&nbsp;&nbsp; ///删除原来的内容而不管是否存盘<br />
&nbsp;SetModifiedFlag(FALSE);&nbsp;&nbsp; ///清除曾经修改过的标记<br />
}<br />
&lt;5&gt;pThread-&gt;m_pMainWnd = pFrame;&nbsp; ///框架窗口作为的指针作为主窗口的指针<br />
&lt;.6&gt;InitialUpdateFrame(pFrame, pDocument, bMakeVisible);&nbsp;&nbsp; /*使框架中的视图窗口接受到OnInitialUpdat的调用,并作原始更新。*/</p>
<p>至此第一段的OnFileNew函数总算讲完。下面讲&lt;2&gt; CreateNewFrame函数<br />
CreateNewFrame是CDocTemplate的成员函数如下3个步骤：<br />
&lt;2.1&gt;CCreateContext context;&nbsp;&nbsp;&nbsp; ///创建CcreateContext对象.也就是我们重载LoadFrame函数的那个CcreateContext的来源*/<br />
context.m_pCurrentFrame = pOther;&nbsp; ///保存当前框架，一般为NULL<br />
context.m_pCurrentDoc = pDoc;&nbsp;&nbsp;&nbsp;&nbsp; ///保存文档对象指针<br />
context.m_pNewViewClass = m_pViewClass;&nbsp; ///保存视图对象指针<br />
context.m_pNewDocTemplate = this;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ///保存文档模板的指针。<br />
&lt;2.2&gt;CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass-&gt;CreateObject(); ///真正创建框架的对象<br />
&lt;2.3&gt;pFrame-&gt;LoadFrame(m_nIDResource,WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;NULL, &amp;context)&nbsp;&nbsp; ///加载资源，这是最重要的，下面讲述<br />
{<br />
&lt;2.3.1&gt; GetIconWndClass(dwDefaultStyle, nIDResource)&nbsp;&nbsp; ///加载资源并注册窗口<br />
&nbsp;{<br />
&nbsp;&nbsp;AfxFindResourceHandle<br />
&nbsp;&nbsp;::LoadIcon&nbsp; ///加载光标资源<br />
&nbsp;&nbsp;CREATESTRUCT cs;&nbsp; ///创建一个CREATESTRUCT结构实例<br />
&nbsp;&nbsp;PreCreateWindow(cs);&nbsp;&nbsp; /*调用窗口预创建函数，这个函数我们可以重载的<br />
&nbsp;&nbsp;根据cs调用 AfxRe<a href="http://dev.21tx.com/corp/gis/" target="_blank">GIS</a>terWndClass注册框架窗口*/<br />
}<br />
&lt;2.3.2&gt; Create(&#8230;)&nbsp; ///创建框架窗口,后面祥述，此处暂时不讲。<br />
&lt;2.3.3&gt; m_hMenuDefault = ::GetMenu(m_hWnd);&nbsp; ///获取并保存菜单句柄<br />
&lt;2.3.4&gt; LoadAccelTable(MAKEINTRESOURCE(nIDResource));&nbsp; ///装载加速键表<br />
}<br />
&nbsp;&nbsp;下面讲Create函数，如下4个步骤：<br />
&nbsp;&nbsp;&lt;2.3.2.1&gt;hMenu = ::LoadMenu(hInst, lpszMenuName);&nbsp; ///加载菜单<br />
&lt;2.3.2.2&gt;CREATESTRUCT cs;&nbsp; ///创建一个CREATESTRUCT结构实例<br />
cs.lpCreateParams = lpParam;&nbsp; ///(此时的lpParam就是&lt;2.1&gt;建的context对象指针)<br />
&lt;2.3.2.3&gt; PreCreateWindow(cs);&nbsp; ///调用窗口预创建函数，这个函数我们可以重载的,又调用一次<br />
&lt;2.3.2.4&gt;调用API函数::CreateWindowEx真正创建框架窗口，创建过程中会发出WM_CREATE和WM_NCCREATE等消息。<br />
下面讲接收WM_CREATE消息的消息处理函数CMainFrame::OnCreate，其他消息不重要<br />
&lt;2.3.2.3.1&gt;CMainFrame::OnCreate最重要的是调用CFrameWnd::OnCreateHelper函数如下:<br />
{<br />
&lt;1&gt;CWnd::OnCreate(lpcs);&nbsp; ///调用缺省的<br />
&lt;2&gt;调用可重载函数OnCreateClient(lpcs,pContext)函数, 在OnCreateClient函数内只是调用CreateView(pContext, AFX_IDW_PANE_FIRST)函数; <br />
CreateView函数步骤如下：<br />
{<br />
&lt;2.1&gt; pView=pContext-&gt;m_pNewViewClass-&gt;CreateObject(); /*创建视图对象*/<br />
&lt;2.2&gt;pView-&gt;Create(&#8230;);/*调用视图对象的Create函数真正创建视图,其更详细的动作可以不理他，但要知道这里会发生很多事情(跟创建框架窗口类似的)；其他一些不重要的动作可以不理他；*/<br />
}<br />
&lt;3&gt;PostMessage(WM_SETMESSAGESTRING, AFX_IDS_IDLEMESSAGE);/*发一个WM_SETMESSAGESTRING消息初始化消息串*/<br />
&lt;4&gt;RecalcLayout();&nbsp; ///重定控制栏等无关动作<br />
}<br />
&lt;2.3.2.3.2&gt; m_wndToolBar.CreateEx;&nbsp;&nbsp; ///创建工具栏<br />
&lt;2.3.2.3.3&gt; LoadToolBar;&nbsp; /停靠工具栏等无关动作<br />
至此WM_CREATE消息处理讲完，同时第三段的ProcessShellCommand函数也结束了<br />
&nbsp;<br />
第四节 ：m_pMainWnd-&gt;ShowWindow(SW_SHOW); ///显示窗口<br />
第五节 ：m_pMainWnd-&gt; UpdateWindow (); ///重画窗口<br />
至此第二节InitInstance ()函数讲完,<br />
第四章pApp-&gt;Run函数<br />
Run函数处理消息循环直到程序推出，已经有很多书籍讲到他的过程，本文不描述他。<br />
第五章总结<br />
从上面的描述中可以看出，文档/视图结构的关键在CRuntimeClass结构，通过CRuntimeClass结构实现动态创建对象。<br />
</p>
 <img src ="http://www.blogjava.net/tinysun/aggbug/243431.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tinysun/" target="_blank">何克勤</a> 2008-11-29 16:34 <a href="http://www.blogjava.net/tinysun/archive/2008/11/29/243431.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MFC下关于“建立空文档失败”问题的分析（转载）</title><link>http://www.blogjava.net/tinysun/archive/2008/11/29/243429.html</link><dc:creator>何克勤</dc:creator><author>何克勤</author><pubDate>Sat, 29 Nov 2008 08:01:00 GMT</pubDate><guid>http://www.blogjava.net/tinysun/archive/2008/11/29/243429.html</guid><wfw:comment>http://www.blogjava.net/tinysun/comments/243429.html</wfw:comment><comments>http://www.blogjava.net/tinysun/archive/2008/11/29/243429.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tinysun/comments/commentRss/243429.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tinysun/services/trackbacks/243429.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
&nbsp;
<p style="word-break: break-all; line-height: 18pt"><span style="font-size: 10pt; color: #333333">这类问题的出现主要在</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">bool CWinApp::ProcessShellCommand(CCommandLineInfo&amp; rCmdInfo);</span></p>
<p style="word-break: break-all; line-height: 18pt"><span style="font-size: 10pt; color: #333333">函数的关键内容：</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&nbsp;<br />
BOOL bResult = TRUE;&nbsp;<br />
switch (rCmdInfo.m_nShellCommand)&nbsp;<br />
{&nbsp;<br />
case CCommandLineInfo::FileNew:&nbsp;&nbsp;// </span><span style="font-size: 10pt; color: #333333">新建</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&nbsp;<br />
&nbsp;if (!AfxGetApp()-&gt;OnCmdMsg(ID_FILE_NEW</span><span style="font-size: 10pt; color: #333333">，</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'"> 0</span><span style="font-size: 10pt; color: #333333">，</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'"> NULL</span><span style="font-size: 10pt; color: #333333">，</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'"> NULL))&nbsp;<br />
&nbsp;&nbsp;OnFileNew();&nbsp;<br />
&nbsp;if (m_pMainWnd == NULL)<span style="display: none"> &lt;_pv<span>
<hr align="left" size="1" />
</span>3&amp;&shy;' </span>&nbsp;<br />
&nbsp;&nbsp;bResult = FALSE;&nbsp;<br />
&nbsp;break;&nbsp;<br />
case CCommandLineInfo::FileOpen:&nbsp;<br />
&nbsp;if (!OpenDocumentFile(rCmdInfo.m_strFileName))&nbsp;<br />
&nbsp;&nbsp;bResult = FALSE;&nbsp;<br />
&nbsp;break;&nbsp;<br />
</span><span style="font-size: 10pt; color: #333333">通过上面的内容我们可以看出：如果没有对</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">ID_FILE_NEW</span><span style="font-size: 10pt; color: #333333">做映射的话出现问题就在</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">OnFileNew();&nbsp;<br />
CWinApp</span><span style="font-size: 10pt; color: #333333">对</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">OnFileNew</span><span style="font-size: 10pt; color: #333333">的默认实现是调用</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">m_pDocManager-&gt;OnFileNew();</span>
<p style="word-break: break-all; line-height: 18pt"><span style="font-size: 10pt; color: #333333">我们继续解析</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">cdocmanager</span><span style="font-size: 10pt; color: #333333">，它究竟干了些什么？</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&nbsp;<br />
</span><span style="font-size: 10pt; color: #333333">（首先说明一下</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">CDocManager</span><span style="font-size: 10pt; color: #333333">它主要的功能是帮助</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">CWinApp</span><span style="font-size: 10pt; color: #333333">是管理文档模板链表和注册文件类型</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">.</span><span style="font-size: 10pt; color: #333333">）</span></p>
<p style="word-break: break-all; line-height: 18pt"><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">//</span><span style="font-size: 10pt; color: #333333">如果模板列表为空的话</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&nbsp;<br />
if (m_templateList.IsEmpty())&nbsp;<br />
{<span style="display: none"> r;Rg"&gt;h<span>
<hr align="left" size="1" />
</span>q </span>&nbsp;<br />
&nbsp;TRACE0("Error: no document templates registered with CWinApp.&nbsp;<br />
");&nbsp;<br />
&nbsp;AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);&nbsp; //</span><span style="font-size: 10pt; color: #333333">报错并返回</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">.</span><span style="font-size: 10pt; color: #333333">这里不会报建立新文档出错。</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&nbsp;<br />
&nbsp;return;<span style="display: none"> q3,7I<span>
<hr align="left" width="33%" size="1" />
</span>?m </span>&nbsp;<br />
}</span>
<p style="word-break: break-all; line-height: 18pt"><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">cdoctemplate* pTemplate = (CDocTemplate*)m_templateList.GetHead();&nbsp;<br />
if (m_templateList.GetCount() &gt; 1)&nbsp;<br />
{&nbsp;<br />
&nbsp;// more than one document template to choose from&nbsp;<br />
&nbsp;// bring up dialog prompting user&nbsp;<br />
&nbsp;CNewTypeDlg dlg(&amp;m_templateList);&nbsp;<br />
&nbsp;int nID = dlg.DoModal();&nbsp;<br />
&nbsp;if (nID == IDOK)&nbsp;<br />
&nbsp;&nbsp;pTemplate = dlg.m_pSelectedTemplate;</span>Mj8F </span>&nbsp;<br />
&nbsp;else&nbsp;<br />
&nbsp;&nbsp;return;&nbsp;&nbsp;&nbsp;&nbsp; // none - cancel operation<span style="display: none"> mT‑#=<span>
<hr align="left" width="33%" size="1" />
</span>w </span>&nbsp;<br />
}</span>
<p style="word-break: break-all; line-height: 18pt"><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">assert(ptemplate != NULL);<span style="display: none"> &shy;Mv<span>
<hr align="left" size="1" />
</span>]kW </span>&nbsp;<br />
ASSERT_KINDOF(CDocTemplate</span><span style="font-size: 10pt; color: #333333">，</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'"> pTemplate);</span>
<p style="word-break: break-all; line-height: 18pt"><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">ptemplate-&gt;opendocumentfile(null);</span></p>
<p style="word-break: break-all; line-height: 18pt"><span style="font-size: 10pt; color: #333333">通过上面的代码我们可以看出，</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">cwinapp</span><span style="font-size: 10pt; color: #333333">的</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">onfilenew</span><span style="font-size: 10pt; color: #333333">和</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">onfileopen</span><span style="font-size: 10pt; color: #333333">分别调用</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">cdocmanager</span><span style="font-size: 10pt; color: #333333">的虚拟函数</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">onfilenew</span><span style="font-size: 10pt; color: #333333">和</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">onfileopen</span><span style="font-size: 10pt; color: #333333">。而在</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">cdocmanager</span><span style="font-size: 10pt; color: #333333">里面。通过模板链表选择不同的模板来调用文档模板的</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">opendocumentfile();&nbsp;<br />
</span><span style="font-size: 10pt; color: #333333">如果传入参数</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">NULL</span><span style="font-size: 10pt; color: #333333">表示新建文件。</span></p>
<p style="word-break: break-all; line-height: 18pt"><span style="font-size: 10pt; color: #333333">下面我们来看看</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">cdoctemplate::opendocumentfile()</span><span style="font-size: 10pt; color: #333333">它是一个最关键的函数。因为他是虚拟函数，我们考虑</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">CSingleDocTemplate::OpenDocumentFile</span><span style="font-size: 10pt; color: #333333">的情况。</span><span style="display: none; font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'"> z<span>
<hr align="left" width="33%" size="1" />
</span>4RqL= </span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&nbsp;<br />
</span><span style="font-size: 10pt; color: #333333">这个函数里面有一段代码：</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&nbsp;<br />
</span><span style="font-size: 10pt; color: #333333">其中：</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">AFX_IDP_FAILED_TO_CREATE_DOC </span><span style="font-size: 10pt; color: #333333">就是字符</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&#8220;</span><span style="font-size: 10pt; color: #0938f7">建立空文档失败</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&#8221;</span><span style="font-size: 10pt; color: #333333">的资源</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">id&nbsp;<br />
// create a new document&nbsp;<br />
pDocument = CreateNewDocument();&nbsp;<br />
ASSERT(pFrame == NULL);&nbsp;&nbsp;&nbsp;&nbsp; // will be created below&nbsp;<br />
bCreated = TRUE;&nbsp;<br />
if (pDocument == NULL)</span>N+ </span>&nbsp;<br />
{&nbsp;<br />
AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);&nbsp;<br />
return NULL;&nbsp;<br />
}&nbsp;<br />
ASSERT(pDocument == m_pOnlyDoc);</span>?#Z </span>&nbsp;<br />
if (pFrame == NULL)&nbsp;<br />
{&nbsp;<br />
ASSERT(bCreated);</span>
<p style="word-break: break-all; line-height: 18pt"><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">// create frame - set as main document frame<span style="display: none"> <span>
<hr align="left" size="1" />
</span>@(m`w </span>&nbsp;<br />
BOOL bAutoDelete = pDocument-&gt;m_bAutoDelete;&nbsp;<br />
pDocument-&gt;m_bAutoDelete = FALSE;&nbsp;<br />
// don&#8217;t destroy if something goes wrong&nbsp;<br />
pFrame = CreateNewFrame(pDocument</span><span style="font-size: 10pt; color: #333333">，</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'"> NULL);&nbsp;<br />
pDocument-&gt;m_bAutoDelete = bAutoDelete;</span>1nD{WwQ </span>&nbsp;<br />
if (pFrame == NULL)&nbsp;<br />
{&nbsp;<br />
&nbsp;AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);<span style="display: none"> <span>
<hr align="left" size="1" />
</span>%BvyG </span>&nbsp;<br />
&nbsp;delete pDocument;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // explicit delete on error&nbsp;<br />
&nbsp;return NULL;&nbsp;<br />
}</span>
<p style="word-break: break-all; line-height: 18pt"><span style="font-size: 10pt; color: #333333">通过观察上面的代码我们很容易的看出</span><span style="font-size: 10pt; color: #333333">有两个可能出错的原因：</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">1 CreateNewDocument</span><span style="font-size: 10pt; color: #333333">返回为</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">NULL 2 createnewframe </span><span style="font-size: 10pt; color: #333333">返回为空。</span></p>
<p style="word-break: break-all; line-height: 18pt"><span style="font-size: 10pt; color: #333333">先看</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'"> CreateNewDocument() </span><span style="font-size: 10pt; color: #333333">一般来说这个函数很少失败。不过在调试时也不能掉以轻心。</span><span style="display: none; font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'"> <span>
<hr align="left" size="1" />
</span>6GYC<br clear="all" />
&gt;'@ </span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&nbsp;<br />
</span><span style="font-size: 10pt; color: #333333">再看看</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">CreateNewFrame()&nbsp; </span><span style="font-size: 10pt; color: #333333">里面有一个函数</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">LoadFrame</span><span style="font-size: 10pt; color: #333333">是造成这种</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&#8220;</span><span style="font-size: 10pt; color: #333333">建立新文档失败</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&#8221;</span><span style="font-size: 10pt; color: #333333">错误的源泉所在。</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&nbsp;<br />
</span><span style="font-size: 10pt; color: #333333">只要它返回</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">False</span><span style="font-size: 10pt; color: #333333">就会弹出这样的提示。</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&nbsp;<br />
</span><span style="font-size: 10pt; color: #333333">我们在来看看</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">LoadFrame() </span><span style="font-size: 10pt; color: #333333">里面调用</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">CFrameWnd::Create()</span><span style="font-size: 10pt; color: #333333">来创建窗口，创建窗口失败返回</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">Fasle</span><span style="font-size: 10pt; color: #333333">。</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&nbsp;<br />
</span><span style="font-size: 10pt; color: #333333">这样问题就变的比较简单了。</span>
<p style="word-break: break-all; line-height: 18pt"><span style="font-size: 10pt; color: #333333">看看</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">create</span><span style="font-size: 10pt; color: #333333">和</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">createex</span><span style="font-size: 10pt; color: #333333">函数的动作就知道怎么回事了。</span><span style="display: none; font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'"> H-@<span>
<hr align="left" size="1" />
</span>[V:!R </span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&nbsp;<br />
</span><span style="font-size: 10pt; color: #0938f7; font-family: 'Arial','sans-serif'">****************************************************************</span></span>S_zS </span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&nbsp;<br />
</span><span style="font-size: 10pt; color: red; font-family: 'Arial','sans-serif'">1</span><span style="font-size: 10pt; color: #0909f7">如果找不到菜单资源</span><span style="font-size: 10pt; color: #0909f7">返回</span><span style="font-size: 10pt; color: #0909f7; font-family: 'Arial','sans-serif'">False </span><span style="font-size: 10pt; color: #0909f7">同时也弹出</span><span style="font-size: 10pt; color: #0909f7; font-family: 'Arial','sans-serif'">&#8220;</span><span style="font-size: 10pt; color: #0909f7">建立空文档失败</span><span style="font-size: 10pt; color: #0909f7; font-family: 'Arial','sans-serif'">&#8221;&nbsp;<br />
HINSTANCE hInst = AfxFindResourceHandle(lpszMenuName</span><span style="font-size: 10pt; color: #0909f7">，</span><span style="font-size: 10pt; color: #0909f7; font-family: 'Arial','sans-serif'"> RT_MENU);&nbsp;<br />
if ((hMenu = ::LoadMenu(hInst</span><span style="font-size: 10pt; color: #0909f7">，</span><span style="font-size: 10pt; color: #0909f7; font-family: 'Arial','sans-serif'"> lpszMenuName)) == NULL)&nbsp;<br />
{&nbsp;<br />
&nbsp;TRACE0("Warning: failed to load menu for CFrameWnd.<span style="display: none"> Dq<span>
<hr align="left" width="33%" size="1" />
</span>dtg </span>&nbsp;<br />
");&nbsp;<br />
&nbsp;PostNcDestroy();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // perhaps delete the C++ object&nbsp;<br />
&nbsp;return FALSE;&nbsp;<br />
}<span style="display: none"> v<br clear="all" />
<span>
<hr align="left" width="33%" size="1" />
</span>&nbsp;7* &shy;C </span>&nbsp;<br />
</span><span style="font-size: 10pt; color: red; font-family: 'Arial','sans-serif'">2</span><span style="font-size: 10pt; color: #0909f7">重载了</span><span style="font-size: 10pt; color: #0909f7; font-family: 'Arial','sans-serif'">PreCreateWindow</span><span style="font-size: 10pt; color: #0909f7">而且返回</span><span style="font-size: 10pt; color: #0909f7; font-family: 'Arial','sans-serif'">False</span><span style="font-size: 10pt; color: #0909f7">也会导致弹出</span><span style="font-size: 10pt; color: #0909f7; font-family: 'Arial','sans-serif'">&#8220;</span><span style="font-size: 10pt; color: #0909f7">建立空文档失败</span><span style="font-size: 10pt; color: #0909f7; font-family: 'Arial','sans-serif'">&#8221;&nbsp;<br />
</span><span style="font-size: 10pt; color: red; font-family: 'Arial','sans-serif'">3</span><span style="font-size: 10pt; color: #0909f7">在</span><span style="font-size: 10pt; color: #0909f7; font-family: 'Arial','sans-serif'">OnCreate </span><span style="font-size: 10pt; color: #0909f7">里面返回</span><span style="font-size: 10pt; color: #0909f7; font-family: 'Arial','sans-serif'">-1 </span><span style="font-size: 10pt; color: #0909f7">也会导致弹出</span><span style="font-size: 10pt; color: #0909f7; font-family: 'Arial','sans-serif'">&#8220;</span><span style="font-size: 10pt; color: #0909f7">建立空文档失败</span><span style="font-size: 10pt; color: #0909f7; font-family: 'Arial','sans-serif'">&#8221;</span><span style="font-size: 10pt; color: #0909f7">。</span><span style="font-size: 10pt; color: red; font-family: 'Arial','sans-serif'">&nbsp;<br />
</span><span style="font-size: 10pt; color: #0033ff; font-family: 'Arial','sans-serif'">******************************************************************</span>
<p style="word-break: break-all; line-height: 18pt"><span style="font-size: 10pt; color: #333333">以上就是我分析的</span><span style="font-size: 10pt; color: #333333">出现这样</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&#8220;</span><span style="font-size: 10pt; color: #333333">建立空文档失败</span><span style="font-size: 10pt; color: #333333; font-family: 'Arial','sans-serif'">&#8221;</span><span style="font-size: 10pt; color: #333333">问题的大致原因。也许还有其他的原因。我这里就不一一列举了。</span></p>
 <img src ="http://www.blogjava.net/tinysun/aggbug/243429.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tinysun/" target="_blank">何克勤</a> 2008-11-29 16:01 <a href="http://www.blogjava.net/tinysun/archive/2008/11/29/243429.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>