<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>MFC浅出</title><link>http://blog.vckbase.com/zaboli/category/495.html</link><description>
MFC 一个功能相对完善的类库，每天你都会发出它的新奇之处~ :P</description><managingEditor>玻璃小屋</managingEditor><dc:language>zh-CHS</dc:language><generator>.Text Version 0.958.2004.214</generator><item><dc:creator>玻璃小屋</dc:creator><title>SendMessage CString </title><link>http://blog.vckbase.com/zaboli/archive/2009/06/22/37737.html</link><pubDate>Mon, 22 Jun 2009 06:21:00 GMT</pubDate><guid>http://blog.vckbase.com/zaboli/archive/2009/06/22/37737.html</guid><wfw:comment>http://blog.vckbase.com/zaboli/comments/37737.html</wfw:comment><comments>http://blog.vckbase.com/zaboli/archive/2009/06/22/37737.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://blog.vckbase.com/zaboli/comments/commentRss/37737.html</wfw:commentRss><trackback:ping>http://blog.vckbase.com/zaboli/services/trackbacks/37737.html</trackback:ping><description>发送&lt;BR&gt;&amp;nbsp;CString strHello = "Hello!";&lt;BR&gt;&amp;nbsp;::SendMessage(this-&amp;gt;m_hWnd,WM_1,1,*(LPARAM*)&amp;amp;strHello);&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;接收&lt;BR&gt;// CdtToolsDlg 消息处理程序&lt;BR&gt;LRESULT CdtToolsDlg::On1(WPARAM,LPARAM l)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;CString strHello = *(CString*)(LPARAM*)&amp;amp;l;&lt;BR&gt;&amp;nbsp;return TRUE;&lt;BR&gt;}&lt;img src ="http://blog.vckbase.com/zaboli/aggbug/37737.html" width = "1" height = "1" /&gt;</description></item><item><dc:creator>玻璃小屋</dc:creator><title>W2A、OLE2A等 ATL 宏会引发 stack overflow。使用时注意。</title><link>http://blog.vckbase.com/zaboli/archive/2009/01/09/36198.html</link><pubDate>Fri, 09 Jan 2009 01:33:00 GMT</pubDate><guid>http://blog.vckbase.com/zaboli/archive/2009/01/09/36198.html</guid><wfw:comment>http://blog.vckbase.com/zaboli/comments/36198.html</wfw:comment><comments>http://blog.vckbase.com/zaboli/archive/2009/01/09/36198.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blog.vckbase.com/zaboli/comments/commentRss/36198.html</wfw:commentRss><trackback:ping>http://blog.vckbase.com/zaboli/services/trackbacks/36198.html</trackback:ping><description>最近一个转换文件的程序，在转换大批量文件是老是 stack overflow。&lt;BR&gt;查来查去。。原来是 在大循环中用了W2A和A2W两个宏。&lt;BR&gt;MSDN的 &lt;SPAN id=nsrTitle&gt;TN059: Using MFC MBCS/Unicode Conversion Macros 有描述，这两个宏在大循环中要有特殊的写法，不然保不准就 stack overflow。&lt;BR&gt;&lt;BR&gt;Other Considerations
&lt;DIV class=section id=sectionSection3 name="collapseableSection"&gt;
&lt;P&gt;Do not use the macros in a tight loop. For example, you do not want to write the following kind of code:&lt;/P&gt;
&lt;DIV class=code&gt;&lt;SPAN codeLanguage="other"&gt;
&lt;TABLE cellSpacing=0 cellPadding=0 width="100%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH&gt;&amp;nbsp;&lt;/TH&gt;
&lt;TH&gt;&lt;SPAN class=copyCode onkeypress="CopyCode_CheckKey(this, event)" onmouseover=ChangeCopyCodeIcon(this) onclick=CopyCode(this) tabIndex=0 onmouseout=ChangeCopyCodeIcon(this)&gt;&lt;IMG class=copyCodeImage alt="Copy image" src="ms-help://MS.MSDNQTR.v90.chs/dv_vclib/icons/copycode.gif" align=absMiddle name=ccImage&gt;Copy Code&lt;/SPAN&gt;&lt;/TH&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD colSpan=2&gt;&lt;PRE&gt;void BadIterateCode(LPCTSTR lpsz)
{
   USES_CONVERSION;
   for (int ii = 0; ii &amp;lt; 10000; ii++)
      pI-&amp;gt;SomeMethod(ii, T2COLE(lpsz));
}&lt;/PRE&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;P&gt;The code above could result in allocating megabytes of memory on the stack depending on what the contents of the string &lt;SPAN class=code&gt;lpsz&lt;/SPAN&gt; is! It also takes time to convert the string for each iteration of the loop. Instead, move such constant conversions out of the loop:&lt;/P&gt;
&lt;DIV class=code&gt;&lt;SPAN codeLanguage="other"&gt;
&lt;TABLE cellSpacing=0 cellPadding=0 width="100%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH&gt;&amp;nbsp;&lt;/TH&gt;
&lt;TH&gt;&lt;SPAN class=copyCode onkeypress="CopyCode_CheckKey(this, event)" onmouseover=ChangeCopyCodeIcon(this) onclick=CopyCode(this) tabIndex=0 onmouseout=ChangeCopyCodeIcon(this)&gt;&lt;IMG class=copyCodeImage alt="Copy image" src="ms-help://MS.MSDNQTR.v90.chs/dv_vclib/icons/copycode.gif" align=absMiddle name=ccImage&gt;Copy Code&lt;/SPAN&gt;&lt;/TH&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD colSpan=2&gt;&lt;PRE&gt;void MuchBetterIterateCode(LPCTSTR lpsz)
{
   USES_CONVERSION;
   LPCOLESTR lpszT = T2COLE(lpsz);
   for (int ii = 0; ii &amp;lt; 10000; ii++)
      pI-&amp;gt;SomeMethod(ii, lpszT);
}&lt;/PRE&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;P&gt;If the string is not constant, then encapsulate the method call into a function. This will allow the conversion buffer to be freed each time. For example:&lt;/P&gt;
&lt;DIV class=code&gt;&lt;SPAN codeLanguage="other"&gt;
&lt;TABLE cellSpacing=0 cellPadding=0 width="100%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH&gt;&amp;nbsp;&lt;/TH&gt;
&lt;TH&gt;&lt;SPAN class=copyCode onkeypress="CopyCode_CheckKey(this, event)" onmouseover=ChangeCopyCodeIcon(this) onclick=CopyCode(this) tabIndex=0 onmouseout=ChangeCopyCodeIcon(this)&gt;&lt;IMG class=copyCodeImage alt="Copy image" src="ms-help://MS.MSDNQTR.v90.chs/dv_vclib/icons/copycode.gif" align=absMiddle name=ccImage&gt;Copy Code&lt;/SPAN&gt;&lt;/TH&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD colSpan=2&gt;&lt;PRE&gt;void CallSomeMethod(int ii, LPCTSTR lpsz)
{
   USES_CONVERSION;
   pI-&amp;gt;SomeMethod(ii, T2COLE(lpsz));
}

void MuchBetterIterateCode2(LPCTSTR* lpszArray)
{
   for (int ii = 0; ii &amp;lt; 10000; ii++)
      CallSomeMethod(ii, lpszArray[ii]);
}&lt;/PRE&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;P&gt;Never return the result of one of the macros, unless the return value implies making a copy of the data before the return. For example, this code is bad:&lt;/P&gt;
&lt;DIV class=code&gt;&lt;SPAN codeLanguage="other"&gt;
&lt;TABLE cellSpacing=0 cellPadding=0 width="100%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH&gt;&amp;nbsp;&lt;/TH&gt;
&lt;TH&gt;&lt;SPAN class=copyCode onkeypress="CopyCode_CheckKey(this, event)" onmouseover=ChangeCopyCodeIcon(this) onclick=CopyCode(this) tabIndex=0 onmouseout=ChangeCopyCodeIcon(this)&gt;&lt;IMG class=copyCodeImage alt="Copy image" src="ms-help://MS.MSDNQTR.v90.chs/dv_vclib/icons/copycode.gif" align=absMiddle name=ccImage&gt;Copy Code&lt;/SPAN&gt;&lt;/TH&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD colSpan=2&gt;&lt;PRE&gt;LPTSTR BadConvert(ISomeInterface* pI)
{
   USES_CONVERSION;
   LPOLESTR lpsz = NULL;
   pI-&amp;gt;GetFileName(&amp;amp;lpsz);
   LPTSTR lpszT = OLE2T(lpsz);
   CoMemFree(lpsz);
   return lpszT; // bad! returning alloca memory
}&lt;/PRE&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;P&gt;The code above could be fixed by changing the return value to something that copies the value:&lt;/P&gt;
&lt;DIV class=code&gt;&lt;SPAN codeLanguage="other"&gt;
&lt;TABLE cellSpacing=0 cellPadding=0 width="100%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH&gt;&amp;nbsp;&lt;/TH&gt;
&lt;TH&gt;&lt;SPAN class=copyCode onkeypress="CopyCode_CheckKey(this, event)" onmouseover=ChangeCopyCodeIcon(this) onclick=CopyCode(this) tabIndex=0 onmouseout=ChangeCopyCodeIcon(this)&gt;&lt;IMG class=copyCodeImage alt="Copy image" src="ms-help://MS.MSDNQTR.v90.chs/dv_vclib/icons/copycode.gif" align=absMiddle name=ccImage&gt;Copy Code&lt;/SPAN&gt;&lt;/TH&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD colSpan=2&gt;&lt;PRE&gt;CString BetterConvert(ISomeInterface* pI)
{
   USES_CONVERSION;
   LPOLESTR lpsz = NULL;
   pI-&amp;gt;GetFileName(&amp;amp;lpsz);
   LPTSTR lpszT = OLE2T(lpsz);
   CoMemFree(lpsz);
   return lpszT; // CString makes copy
}&lt;/PRE&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;P&gt;The macros are easy to use and easy to insert into your code, but as you can tell from the caveats above, you need to be careful when using them.&lt;/P&gt;&lt;/DIV&gt;&lt;/SPAN&gt;&lt;img src ="http://blog.vckbase.com/zaboli/aggbug/36198.html" width = "1" height = "1" /&gt;</description></item><item><dc:creator>玻璃小屋</dc:creator><title>MFC的一个BUG? void CHtmlView::OnDestroy() 造成的 GetActiveView()的困扰。</title><link>http://blog.vckbase.com/zaboli/archive/2007/11/30/31010.html</link><pubDate>Fri, 30 Nov 2007 09:16:00 GMT</pubDate><guid>http://blog.vckbase.com/zaboli/archive/2007/11/30/31010.html</guid><wfw:comment>http://blog.vckbase.com/zaboli/comments/31010.html</wfw:comment><comments>http://blog.vckbase.com/zaboli/archive/2007/11/30/31010.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://blog.vckbase.com/zaboli/comments/commentRss/31010.html</wfw:commentRss><trackback:ping>http://blog.vckbase.com/zaboli/services/trackbacks/31010.html</trackback:ping><description>&lt;P&gt;标准的从CView 继承的 CMyXXXView 应该都掉用 CView::OnDestroy 做一些自己被消灭后的身后事。。如下：&lt;BR&gt;&lt;BR&gt;void CView::OnDestroy()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;CFrameWnd* pFrame = GetParentFrame();&lt;BR&gt;&amp;nbsp;if (pFrame != NULL &amp;amp;&amp;amp; pFrame-&amp;gt;GetActiveView() == this)&lt;BR&gt;&amp;nbsp;&amp;nbsp;pFrame-&amp;gt;SetActiveView(NULL);&amp;nbsp;&amp;nbsp;&amp;nbsp; // deactivate during death&lt;BR&gt;&amp;nbsp;CWnd::OnDestroy();&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;可是我们的 CHtmlView 大侠的 OnDestroy() 却什么都没做。。。&lt;BR&gt;void CHtmlView::OnDestroy()&lt;BR&gt;{&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;由于以上原因，我写的 Multi Doc/View 结构中用了CHtmlView 的派生类，结果在程序退出时，在GetActiveView 中遇到访问违历。。。因为 CHtmlView 销毁时没有执行 SetActiveView(NULL);&lt;BR&gt;&lt;BR&gt;我把我派生的 CXXHtmlView 改成：&lt;BR&gt;&lt;BR&gt;void CHotHtmlGuXiaoView::OnDestroy()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;CFrameWnd* pFrame = GetParentFrame();&lt;BR&gt;&amp;nbsp;if (pFrame != NULL &amp;amp;&amp;amp; pFrame-&amp;gt;GetActiveView() == this)&lt;BR&gt;&amp;nbsp;&amp;nbsp;pFrame-&amp;gt;SetActiveView(NULL);&amp;nbsp;&amp;nbsp;&amp;nbsp; // deactivate during death&lt;/P&gt;
&lt;P&gt;&amp;nbsp;//CHtmlView::OnDestroy(); 注释。。。反正什么都没做。。。&lt;BR&gt;&amp;nbsp;// TODO: 在此处添加消息处理程序代码&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;是MFC的BUG？？还是我没按照MFC的流程做事？？？&lt;BR&gt;&lt;BR&gt;不管了，反正目前问题解决了。。。。&lt;BR&gt;&lt;/P&gt;&lt;img src ="http://blog.vckbase.com/zaboli/aggbug/31010.html" width = "1" height = "1" /&gt;</description></item><item><dc:creator>玻璃小屋</dc:creator><title>对话框事件中循环处理数据时的消息分发~</title><link>http://blog.vckbase.com/zaboli/archive/2007/08/03/27941.html</link><pubDate>Fri, 03 Aug 2007 01:34:00 GMT</pubDate><guid>http://blog.vckbase.com/zaboli/archive/2007/08/03/27941.html</guid><wfw:comment>http://blog.vckbase.com/zaboli/comments/27941.html</wfw:comment><comments>http://blog.vckbase.com/zaboli/archive/2007/08/03/27941.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://blog.vckbase.com/zaboli/comments/commentRss/27941.html</wfw:commentRss><trackback:ping>http://blog.vckbase.com/zaboli/services/trackbacks/27941.html</trackback:ping><description>&lt;BR&gt;&amp;nbsp;&amp;nbsp;while(PeekMessage(&amp;amp;msg, NULL, NULL, NULL, PM_REMOVE))&lt;BR&gt;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;TranslateMessage(&amp;amp;msg);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;DispatchMessage(&amp;amp;msg);&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;img src ="http://blog.vckbase.com/zaboli/aggbug/27941.html" width = "1" height = "1" /&gt;</description></item><item><dc:creator>玻璃小屋</dc:creator><title>做 DLL 时 “__declspec(dllexport)” 和 “.def 文件”定义导出函数的区别（转自MSDN）</title><link>http://blog.vckbase.com/zaboli/archive/2006/10/29/22911.html</link><pubDate>Sun, 29 Oct 2006 13:49:00 GMT</pubDate><guid>http://blog.vckbase.com/zaboli/archive/2006/10/29/22911.html</guid><wfw:comment>http://blog.vckbase.com/zaboli/comments/22911.html</wfw:comment><comments>http://blog.vckbase.com/zaboli/archive/2006/10/29/22911.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blog.vckbase.com/zaboli/comments/commentRss/22911.html</wfw:commentRss><trackback:ping>http://blog.vckbase.com/zaboli/services/trackbacks/22911.html</trackback:ping><description>&lt;P&gt;若要确定用于导出函数的方法（.def 文件或 __declspec(dllexport) 关键字），请回答下列问题：&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;是否要一直添加附加的导出函数？&lt;/P&gt;
&lt;LI&gt;
&lt;P&gt;谁要使用 DLL？例如，是由许多无法重新生成的可执行文件使用的第三方 DLL 还是仅由可以轻松重新生成的应用程序使用的 DLL？&lt;/P&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;H1 class=heading&gt;使用 .DEF 文件的优缺点&lt;/H1&gt;
&lt;DIV class=seeAlsoNoToggleSection id=sectionSection0&gt;
&lt;P&gt;在 .def 文件中导出函数使您得以控制导出序号。当将附加的导出函数添加到 DLL 时，可以给它们分配更高的序号值（高于任何其他导出函数）。当您进行此操作时，使用隐式链接的应用程序不必与包含新函数的新导入库重新链接。这非常重要，例如，在设计将由许多应用程序使用的第三方 DLL 时。可以通过添加附加功能不断地增强 DLL，同时确保现有应用程序继续正常使用新的 DLL。MFC DLL 是使用 .def 文件生成的。&lt;/P&gt;
&lt;P&gt;使用 .def 文件的另一个优点是：可以使用 NONAME 属性导出函数，该属性仅将序号放到 DLL 的导出表中。对具有大量导出函数的 DLL，使用 NONAME 属性可以减小 DLL 文件的大小。有关编写模块定义语句的信息，请参见&lt;?XML:NAMESPACE PREFIX = MSHelp NS = "http://msdn.microsoft.com/mshelp" /&gt;&lt;MSHelp:link tabIndex=0 keywords="F65CD3A7-65D7-4D06-939F-A8B1ECD50F2D"&gt;模块定义语句的规则&lt;/MSHelp:link&gt;。有关序号导出的更多信息，请参见&lt;A href="ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_vccore/html/679719fd-d965-4df3-9f7a-7d86ad831702.htm"&gt;按序号而不是按名称从 DLL 导出函数&lt;/A&gt;。&lt;/P&gt;
&lt;P&gt;使用 .def 文件的主要缺点是：在 C++ 文件中导出函数时，必须将修饰名放到 .def 文件中，或者通过使用外部&amp;#8220;C&amp;#8221;用标准 C 链接定义导出函数，以避免编译器进行名称修饰。&lt;/P&gt;
&lt;P&gt;如果需要将修饰名放到 .def 文件中，则可以通过使用 &lt;MSHelp:link tabIndex=0 keywords="4BC06822-5330-44B4-8A3F-6180DFD41DFB"&gt;DUMPBIN&lt;/MSHelp:link&gt; 工具或 &lt;MSHelp:link tabIndex=0 keywords="9CCCE53D-4E36-43DA-87B0-7603DDFDEA63"&gt;/MAP&lt;/MSHelp:link&gt; 链接器选项来获取修饰名。请注意，编译器产生的修饰名是编译器特定的。如果将 Visual C++ 编译器产生的修饰名放到 .def 文件中，则链接到 DLL 的应用程序必须也是用相同版本的 Visual C++ 生成的，这样调用应用程序中的修饰名才能与 DLL 的 .def 文件中的导出名相匹配。&lt;/P&gt;&lt;/DIV&gt;
&lt;H1 class=heading&gt;使用 __declspec(dllexport) 的优缺点&lt;/H1&gt;
&lt;DIV class=seeAlsoNoToggleSection id=sectionSection1&gt;
&lt;P&gt;使用 __declspec(dllexport) 非常方便，因为不必考虑维护 .def 文件和获取导出函数的修饰名。例如，如果您设计的 DLL 供自己控制的应用程序使用，则此方法很适用。如果通过新的导出函数重新生成 DLL，还必须重新生成应用程序，因为如果使用不同版本的编译器进行重新编译，则导出的 C++ 函数的修饰名可能会发生变化。&lt;/P&gt;&lt;/DIV&gt;&lt;img src ="http://blog.vckbase.com/zaboli/aggbug/22911.html" width = "1" height = "1" /&gt;</description></item><item><dc:creator>玻璃小屋</dc:creator><title>关于MFC的CSocket和CAsyncSocket封装的一个大误解！</title><link>http://blog.vckbase.com/zaboli/archive/2006/10/23/22843.html</link><pubDate>Mon, 23 Oct 2006 05:51:00 GMT</pubDate><guid>http://blog.vckbase.com/zaboli/archive/2006/10/23/22843.html</guid><wfw:comment>http://blog.vckbase.com/zaboli/comments/22843.html</wfw:comment><comments>http://blog.vckbase.com/zaboli/archive/2006/10/23/22843.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://blog.vckbase.com/zaboli/comments/commentRss/22843.html</wfw:commentRss><trackback:ping>http://blog.vckbase.com/zaboli/services/trackbacks/22843.html</trackback:ping><description>&lt;P&gt;说实话！开始用CSocket和 CAsyncSocket的时候觉的很好用。都是用来写客户端的嘛！比如 ftp啦，什么的。都是单线程的。&lt;BR&gt;可是后来做的多了，听的多了。似乎大家都对CSocket和CAsyncSocket斥之以鼻！后来要写服务器方面的程序了连接多了，线程模式也是多线程了。查了很多资料，都说这两个封装的效率很低。似乎是每创建一个CSocket对象，都会创建一个窗口。这样的话，如果写服务器程序，几百几千个socket的话，就有几百几千的windows了。。。那就晕了。。。。。&lt;BR&gt;&lt;BR&gt;直到某一天有了如下我老人家自以为是，最后砸了自己的脚的对话：&lt;BR&gt;&lt;BR&gt;2006-10-23 12:39:26 周伯通&lt;BR&gt;CAsyncSocket的OnSend,OnSend等会重入吗？ &lt;/P&gt;
&lt;P&gt;2006-10-23 12:40:36 周伯通&lt;BR&gt;[:D] &lt;/P&gt;
&lt;P&gt;2006-10-23 12:41:17 ㊣毛毛&lt;BR&gt;啥叫重入？？包的顺序混乱？ &lt;BR&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;2006-10-23 12:41:30 ㊣毛毛&lt;BR&gt;写服务端？还是客户端？ &lt;BR&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;2006-10-23 12:42:19 周伯通&lt;BR&gt;就是一个OnReceive没结束，令一个OnReceive又开始了 &lt;/P&gt;
&lt;P&gt;2006-10-23 12:42:32 周伯通&lt;BR&gt;老大，你连这个都不懂？ &lt;/P&gt;
&lt;P&gt;2006-10-23 12:42:41 周伯通&lt;BR&gt;我今天眼花了？ &lt;/P&gt;
&lt;P&gt;2006-10-23 12:43:45 ㊣毛毛&lt;BR&gt;他是基于消息的。 &lt;BR&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;2006-10-23 12:44:23 周伯通&lt;BR&gt;进不进对列？ &lt;/P&gt;
&lt;P&gt;2006-10-23 12:45:05 ㊣毛毛&lt;BR&gt;[:L] &lt;BR&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;2006-10-23 12:45:20 周伯通&lt;BR&gt;[:D] &lt;/P&gt;
&lt;P&gt;2006-10-23 12:45:35 周伯通&lt;BR&gt;你是汉正街的水货 &lt;/P&gt;
&lt;P&gt;2006-10-23 12:45:53 ㊣毛毛&lt;BR&gt;每个CAsyncSocket都有一个窗口。 &lt;BR&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;2006-10-23 12:46:08 周伯通&lt;BR&gt;你是汉正街的水货 &lt;BR&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;2006-10-23 12:46:28 ㊣毛毛&lt;BR&gt;当有数据的时候，socket 会发消息给这个窗口。 &lt;BR&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;2006-10-23 12:47:01 周伯通&lt;BR&gt;每个调用了AfxSockInit的线程都只有一个窗口！ &lt;/P&gt;
&lt;P&gt;2006-10-23 12:47:23 周伯通&lt;BR&gt;五年前我最喜欢哪这个问题考别人 &lt;/P&gt;
&lt;P&gt;2006-10-23 12:47:35 ㊣毛毛&lt;BR&gt;我真晕。。。 &lt;BR&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;2006-10-23 12:47:40 周伯通&lt;BR&gt;[:D] &lt;/P&gt;
&lt;P&gt;2006-10-23 12:48:31 周伯通&lt;BR&gt;1000个连接要是有1000个隐藏窗口，硬件厂商就高兴了 &lt;/P&gt;
&lt;P&gt;2006-10-23 12:48:36 周伯通&lt;BR&gt;[:D] &lt;/P&gt;
&lt;P&gt;2006-10-23 12:49:51 周伯通&lt;BR&gt;你是开发人员？还是冒牌的？ &lt;/P&gt;
&lt;P&gt;2006-10-23 12:49:55 周伯通&lt;BR&gt;[:D] &lt;/P&gt;
&lt;P&gt;2006-10-23 12:50:04 ㊣毛毛&lt;BR&gt;唉。 &lt;BR&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;2006-10-23 12:50:41 周伯通&lt;BR&gt;[:P] &lt;/P&gt;
&lt;P&gt;2006-10-23 12:52:03 周伯通&lt;BR&gt;别生气，开个玩笑 &lt;/P&gt;
&lt;P&gt;2006-10-23 12:54:06 周伯通&lt;BR&gt;{5CBB6 &lt;/P&gt;
&lt;P&gt;2006-10-23 13:02:55 周伯通&lt;BR&gt;伤心了？ &lt;/P&gt;
&lt;P&gt;2006-10-23 13:03:00 周伯通&lt;BR&gt;自卑了？ &lt;/P&gt;
&lt;P&gt;2006-10-23 13:08:06 周伯通&lt;BR&gt;I am sorry! &lt;/P&gt;
&lt;P&gt;2006-10-23 13:09:33 ㊣毛毛&lt;BR&gt;刚刚查了半天代码。。应该是每个线程一个窗口！ &lt;BR&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;2006-10-23 13:09:49 ㊣毛毛&lt;BR&gt;每个有 CSocket的线程！ &lt;BR&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;2006-10-23 13:10:01 周伯通&lt;BR&gt;也不一定 &lt;/P&gt;
&lt;P&gt;2006-10-23 13:10:09 ㊣毛毛&lt;BR&gt;应该是的。 &lt;BR&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;2006-10-23 13:10:29 周伯通&lt;BR&gt;关键是看该线程是否调用AfxSockInit &lt;/P&gt;
&lt;P&gt;2006-10-23 13:11:03 ㊣毛毛&lt;BR&gt;。。。不调用根本就不能用 socket 函数 -.- &lt;BR&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;2006-10-23 13:11:26 周伯通&lt;BR&gt;取决与AfxSockInit创建的一个数据结构，就是那个我特烦的模块线程状态 &lt;/P&gt;
&lt;P&gt;2006-10-23 13:11:54 周伯通&lt;BR&gt;因为有人可能只在主线程中Call sockInit &lt;/P&gt;
&lt;P&gt;2006-10-23 13:13:43 周伯通&lt;BR&gt;我不知道这样做现在还可不可以！！ &lt;/P&gt;
&lt;P&gt;2006-10-23 13:14:02 周伯通&lt;BR&gt;Long Long ago是可以的 &lt;/P&gt;
&lt;P&gt;2006-10-23 13:16:31 ㊣毛毛&lt;BR&gt;按他的模式，是每个线程都有一个 socket wnd.. &lt;BR&gt;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;2006-10-23 13:16:58 周伯通&lt;BR&gt;对 &lt;/P&gt;
&lt;P&gt;2006-10-23 13:17:08 周伯通&lt;BR&gt;但他又。。 &lt;/P&gt;
&lt;P&gt;2006-10-23 13:17:17 周伯通&lt;BR&gt;唉 &lt;/P&gt;
&lt;P&gt;2006-10-23 13:17:26 周伯通&lt;BR&gt;不清不白 &lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;。。。所以结论应该是：不是创建一个新的CSocket对象就要创建一个新的窗口。而是同一个线程里面的 CSocket对象共享一个m_hSocketWindow。所以这样看来，我以前的每个CSocket一个窗口的想法就错了，所以按此想法推理的CSocket写服务器程序效率的结论似乎也占不住脚！CSocket应该还是不错的封装！效率差在什么地方？？差在低层消息循环的开销？可是其他模型在实际工程中的同步什么的开销也应该不少吧？？请路过的老鸟指教？？&lt;BR&gt;&lt;BR&gt;另外 线程数据的结构如下，摘自afxstat_.h&lt;BR&gt;&lt;BR&gt;// AFX_MODULE_THREAD_STATE (local to thread *and* module)&lt;BR&gt;class AFX_MODULE_THREAD_STATE : public CNoTrackObject&lt;BR&gt;{&lt;BR&gt;public:&lt;BR&gt;&amp;nbsp;AFX_MODULE_THREAD_STATE();&lt;BR&gt;&amp;nbsp;virtual ~AFX_MODULE_THREAD_STATE();&lt;/P&gt;
&lt;P&gt;&amp;nbsp;// current CWinThread pointer&lt;BR&gt;&amp;nbsp;CWinThread* m_pCurrentWinThread;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;// list of CFrameWnd objects for thread&lt;BR&gt;&amp;nbsp;CTypedSimpleList&amp;lt;CFrameWnd*&amp;gt; m_frameList;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;// temporary/permanent map state&lt;BR&gt;&amp;nbsp;DWORD m_nTempMapLock;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // if not 0, temp maps locked&lt;BR&gt;&amp;nbsp;CHandleMap* m_pmapHWND;&lt;BR&gt;&amp;nbsp;CHandleMap* m_pmapHMENU;&lt;BR&gt;&amp;nbsp;CHandleMap* m_pmapHDC;&lt;BR&gt;&amp;nbsp;CHandleMap* m_pmapHGDIOBJ;&lt;BR&gt;&amp;nbsp;CHandleMap* m_pmapHIMAGELIST;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;// thread-local MFC new handler (separate from C-runtime)&lt;BR&gt;&amp;nbsp;_PNH m_pfnNewHandler;&lt;/P&gt;
&lt;P&gt;#ifndef _AFX_NO_SOCKET_SUPPORT&lt;BR&gt;&amp;nbsp;// WinSock specific thread state&lt;BR&gt;&amp;nbsp;HWND m_hSocketWindow;&lt;BR&gt;#ifdef _AFXDLL&lt;BR&gt;&amp;nbsp;CEmbeddedButActsLikePtr&amp;lt;CMapPtrToPtr&amp;gt; m_pmapSocketHandle;&lt;BR&gt;&amp;nbsp;CEmbeddedButActsLikePtr&amp;lt;CMapPtrToPtr&amp;gt; m_pmapDeadSockets;&lt;BR&gt;&amp;nbsp;CEmbeddedButActsLikePtr&amp;lt;CPtrList&amp;gt; m_plistSocketNotifications;&lt;BR&gt;#else&lt;BR&gt;&amp;nbsp;CMapPtrToPtr* m_pmapSocketHandle;&lt;BR&gt;&amp;nbsp;CMapPtrToPtr* m_pmapDeadSockets;&lt;BR&gt;&amp;nbsp;CPtrList* m_plistSocketNotifications;&lt;BR&gt;#endif&lt;BR&gt;#endif&lt;/P&gt;
&lt;P&gt;&amp;nbsp;// common controls thread state&lt;BR&gt;&amp;nbsp;CToolTipCtrl* m_pToolTip;&lt;BR&gt;&amp;nbsp;CWnd* m_pLastHit;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // last window to own tooltip&lt;BR&gt;&amp;nbsp;INT_PTR m_nLastHit;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // last hittest code&lt;BR&gt;&amp;nbsp;TOOLINFO* m_pLastInfo;&amp;nbsp;&amp;nbsp;&amp;nbsp; // last TOOLINFO structure&lt;BR&gt;&amp;nbsp;INT_PTR m_nLastStatus;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // last flyby status message&lt;BR&gt;&amp;nbsp;CControlBar* m_pLastStatus; // last flyby status control bar&lt;BR&gt;};&lt;/P&gt;&lt;img src ="http://blog.vckbase.com/zaboli/aggbug/22843.html" width = "1" height = "1" /&gt;</description></item><item><dc:creator>玻璃小屋</dc:creator><title>世上好人多。MFC、对话框的一些技巧（转）</title><link>http://blog.vckbase.com/zaboli/archive/2006/09/28/22561.html</link><pubDate>Thu, 28 Sep 2006 06:24:00 GMT</pubDate><guid>http://blog.vckbase.com/zaboli/archive/2006/09/28/22561.html</guid><wfw:comment>http://blog.vckbase.com/zaboli/comments/22561.html</wfw:comment><comments>http://blog.vckbase.com/zaboli/archive/2006/09/28/22561.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blog.vckbase.com/zaboli/comments/commentRss/22561.html</wfw:commentRss><trackback:ping>http://blog.vckbase.com/zaboli/services/trackbacks/22561.html</trackback:ping><description>&lt;A href="http://dtor.cnblogs.com/archive/2006/07/13/449957.html"&gt;http://dtor.cnblogs.com/archive/2006/07/13/449957.html&lt;/A&gt;&lt;img src ="http://blog.vckbase.com/zaboli/aggbug/22561.html" width = "1" height = "1" /&gt;</description></item><item><dc:creator>玻璃小屋</dc:creator><title>关掉 vs2005 的 64位 time_t 的选项 _USE_32BIT_TIME_T</title><link>http://blog.vckbase.com/zaboli/archive/2006/03/30/18934.html</link><pubDate>Thu, 30 Mar 2006 05:57:00 GMT</pubDate><guid>http://blog.vckbase.com/zaboli/archive/2006/03/30/18934.html</guid><wfw:comment>http://blog.vckbase.com/zaboli/comments/18934.html</wfw:comment><comments>http://blog.vckbase.com/zaboli/archive/2006/03/30/18934.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blog.vckbase.com/zaboli/comments/commentRss/18934.html</wfw:commentRss><trackback:ping>http://blog.vckbase.com/zaboli/services/trackbacks/18934.html</trackback:ping><description>升级老代码会用到吧。&lt;img src ="http://blog.vckbase.com/zaboli/aggbug/18934.html" width = "1" height = "1" /&gt;</description></item><item><dc:creator>玻璃小屋</dc:creator><title>(ZT)How To Know When the User Clicks a Check Box in a TreeView Control</title><link>http://blog.vckbase.com/zaboli/archive/2006/02/23/17900.html</link><pubDate>Thu, 23 Feb 2006 01:18:00 GMT</pubDate><guid>http://blog.vckbase.com/zaboli/archive/2006/02/23/17900.html</guid><wfw:comment>http://blog.vckbase.com/zaboli/comments/17900.html</wfw:comment><comments>http://blog.vckbase.com/zaboli/archive/2006/02/23/17900.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blog.vckbase.com/zaboli/comments/commentRss/17900.html</wfw:commentRss><trackback:ping>http://blog.vckbase.com/zaboli/services/trackbacks/17900.html</trackback:ping><description>&lt;img src ="http://blog.vckbase.com/zaboli/aggbug/17900.html" width = "1" height = "1" /&gt;</description></item><item><dc:creator>玻璃小屋</dc:creator><title>CSplitterWnd!?</title><link>http://blog.vckbase.com/zaboli/archive/2005/04/29/5068.html</link><pubDate>Fri, 29 Apr 2005 01:42:00 GMT</pubDate><guid>http://blog.vckbase.com/zaboli/archive/2005/04/29/5068.html</guid><wfw:comment>http://blog.vckbase.com/zaboli/comments/5068.html</wfw:comment><comments>http://blog.vckbase.com/zaboli/archive/2005/04/29/5068.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://blog.vckbase.com/zaboli/comments/commentRss/5068.html</wfw:commentRss><trackback:ping>http://blog.vckbase.com/zaboli/services/trackbacks/5068.html</trackback:ping><description>&lt;P&gt;&lt;FONT color=#ff1493&gt;&lt;/FONT&gt;&lt;BR&gt;今天想分割一下窗口，没有用 Doc/View 结构~ 想用CSplitterWnd 分割出一个 继承自 CTreeCtrl的窗口和一个继承自 CWnd 的窗口。&lt;BR&gt;&lt;BR&gt;在 CSpliterWnd 的父窗口的 OnCreate 中调用&lt;BR&gt;&lt;BR&gt;int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)&lt;BR&gt;{&lt;BR&gt;&lt;BR&gt;&amp;nbsp;// 创建拆分器窗口&lt;BR&gt;&amp;nbsp;if (!m_wndSplitter.CreateStatic(this, 1, 2))&lt;BR&gt;&amp;nbsp;&amp;nbsp;return -1;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CHotTreeCtrl), CSize(200, 200), NULL) ||&lt;BR&gt;&amp;nbsp;&amp;nbsp;!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CHotVtPain), CSize(100, 100), NULL))&lt;BR&gt;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;DWORD nRet = GetLastError();&lt;BR&gt;&amp;nbsp;&amp;nbsp;m_wndSplitter.DestroyWindow();&lt;BR&gt;&amp;nbsp;&amp;nbsp;return -1;&lt;BR&gt;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&amp;nbsp;return 0;&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;编译成功。可是运行时创建出来的Pane(0,0)不是&amp;nbsp;CTreeCtrl ，而是普通的CWnd~~~，晕死，也许是对MFC了解不够，于是后来就查了查CSplitterWnd::CreateView这个成员函数的代码：&lt;BR&gt;&amp;nbsp;&lt;BR&gt;/////////////////////////////////////////////////////////////////////////////&lt;BR&gt;// CSplitterWnd default creation of parts&lt;/P&gt;
&lt;P&gt;// You must create ALL panes unless DYNAMIC_SPLIT is defined!&lt;BR&gt;//&amp;nbsp; Usually the splitter window is invisible when creating a pane&lt;BR&gt;BOOL CSplitterWnd::CreateView(int row, int col,&lt;BR&gt;&amp;nbsp;CRuntimeClass* pViewClass, SIZE sizeInit, CCreateContext* pContext)&lt;BR&gt;{&lt;BR&gt;#ifdef _DEBUG&lt;BR&gt;&amp;nbsp;ASSERT_VALID(this);&lt;BR&gt;&amp;nbsp;ASSERT(row &amp;gt;= 0 &amp;amp;&amp;amp; row &amp;lt; m_nRows);&lt;BR&gt;&amp;nbsp;ASSERT(col &amp;gt;= 0 &amp;amp;&amp;amp; col &amp;lt; m_nCols);&lt;BR&gt;&amp;nbsp;ASSERT(pViewClass != NULL);&lt;BR&gt;&amp;nbsp;ASSERT(pViewClass-&amp;gt;IsDerivedFrom(RUNTIME_CLASS(CWnd)));&lt;BR&gt;&amp;nbsp;ASSERT(AfxIsValidAddress(pViewClass, sizeof(CRuntimeClass), FALSE));&lt;/P&gt;
&lt;P&gt;&amp;nbsp;if (GetDlgItem(IdFromRowCol(row, col)) != NULL)&lt;BR&gt;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;TRACE(traceAppMsg, 0, "Error: CreateView - pane already exists for row %d, col %d.\n",&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;row, col);&lt;BR&gt;&amp;nbsp;&amp;nbsp;ASSERT(FALSE);&lt;BR&gt;&amp;nbsp;&amp;nbsp;return FALSE;&lt;BR&gt;&amp;nbsp;}&lt;BR&gt;#endif&lt;/P&gt;
&lt;P&gt;&amp;nbsp;// set the initial size for that pane&lt;BR&gt;&amp;nbsp;m_pColInfo[col].nIdealSize = sizeInit.cx;&lt;BR&gt;&amp;nbsp;m_pRowInfo[row].nIdealSize = sizeInit.cy;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;BOOL bSendInitialUpdate = FALSE;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;CCreateContext contextT;&lt;BR&gt;&amp;nbsp;if (pContext == NULL)&lt;BR&gt;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;// if no context specified, generate one from the currently selected&lt;BR&gt;&amp;nbsp;&amp;nbsp;//&amp;nbsp; client if possible&lt;BR&gt;&amp;nbsp;&amp;nbsp;CView* pOldView = (CView*)GetActivePane();&lt;BR&gt;&amp;nbsp;&amp;nbsp;if (pOldView != NULL &amp;amp;&amp;amp; pOldView-&amp;gt;IsKindOf(RUNTIME_CLASS(CView)))&lt;BR&gt;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// set info about last pane&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;ASSERT(contextT.m_pCurrentFrame == NULL);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;contextT.m_pLastView = pOldView;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;contextT.m_pCurrentDoc = pOldView-&amp;gt;GetDocument();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (contextT.m_pCurrentDoc != NULL)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;contextT.m_pNewDocTemplate =&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; contextT.m_pCurrentDoc-&amp;gt;GetDocTemplate();&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;pContext = &amp;amp;contextT;&lt;BR&gt;&amp;nbsp;&amp;nbsp;bSendInitialUpdate = TRUE;&lt;BR&gt;&amp;nbsp;}&lt;/P&gt;
&lt;P&gt;&amp;nbsp;CWnd* pWnd;&lt;BR&gt;&amp;nbsp;TRY&lt;BR&gt;&amp;nbsp;{&lt;BR&gt;&lt;FONT color=#ff1493&gt;&amp;nbsp;&amp;nbsp;pWnd = (CWnd*)pViewClass-&amp;gt;CreateObject();//这里是动态 new 一个 你传进来的 窗口类的实例！！！&lt;BR&gt;&amp;nbsp;&amp;nbsp;if (pWnd == NULL)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;AfxThrowMemoryException();&lt;/FONT&gt;&lt;BR&gt;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;CATCH_ALL(e)&lt;BR&gt;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;TRACE(traceAppMsg, 0, "Out of memory creating a splitter pane.\n");&lt;BR&gt;&amp;nbsp;&amp;nbsp;// Note: DELETE_EXCEPTION(e) not required&lt;BR&gt;&amp;nbsp;&amp;nbsp;return FALSE;&lt;BR&gt;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;END_CATCH_ALL&lt;/P&gt;
&lt;P&gt;&amp;nbsp;ASSERT_KINDOF(CWnd, pWnd);&lt;BR&gt;&amp;nbsp;ASSERT(pWnd-&amp;gt;m_hWnd == NULL);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // not yet created&lt;/P&gt;
&lt;P&gt;&amp;nbsp;DWORD dwStyle = AFX_WS_DEFAULT_VIEW &amp;amp; ~WS_BORDER;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;// Create with the right size (wrong position)&lt;BR&gt;&amp;nbsp;CRect rect(CPoint(0,0), sizeInit);&lt;BR&gt;&lt;FONT color=#ff1493&gt;//值得注意的是这里，它实际上调用的是 CWnd的 Create来创建普通窗口！！而不是掉用的我们继承的CTreeCtrl 的 CHotTreeCtrl 的Create来创建 &amp;#8220;SysTreeView&amp;#8220; 类型的窗口！！！所以就没有办法在&amp;nbsp;pane(0,0)中创建出 树型控件了！！！！可是人家 MFC 的 Doc/view 结构可以正常啊~~ 于是还是要查MFC源代码！！！&lt;BR&gt;&amp;nbsp;if (!pWnd-&amp;gt;Create(NULL, NULL, dwStyle,&lt;BR&gt;&amp;nbsp;&amp;nbsp;rect, this, IdFromRowCol(row, col), pContext))&lt;BR&gt;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;TRACE(traceAppMsg, 0, "Warning: couldn't create client pane for splitter.\n");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// pWnd will be cleaned up by PostNcDestroy&lt;BR&gt;&amp;nbsp;&amp;nbsp;return FALSE;&lt;BR&gt;&amp;nbsp;}&lt;BR&gt;&lt;/FONT&gt;&amp;nbsp;ASSERT((int)_AfxGetDlgCtrlID(pWnd-&amp;gt;m_hWnd) == IdFromRowCol(row, col));&lt;/P&gt;
&lt;P&gt;&amp;nbsp;// send initial notification message&lt;BR&gt;&amp;nbsp;if (bSendInitialUpdate)&lt;BR&gt;&amp;nbsp;&amp;nbsp;pWnd-&amp;gt;SendMessage(WM_INITIALUPDATE);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;return TRUE;&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;上面提到还是从MFC 源代码入手于是就找 CTreeView的代码！&lt;BR&gt;//CTreeView 的构造函数如下！其中：WC_TREEVIEW 就是字符串&amp;#8220;SysTreeView32&amp;#8221;&lt;BR&gt;_AFXCVIEW_INLINE CTreeView::CTreeView() : CCtrlView(&lt;FONT style="BACKGROUND-COLOR: #ff1493"&gt;WC_TREEVIEW&lt;/FONT&gt;,&lt;BR&gt;&amp;nbsp;AFX_WS_DEFAULT_VIEW)&lt;BR&gt;&amp;nbsp;{ }&lt;BR&gt;好！我们继续找 CCtrlView 的代码！-_-&lt;BR&gt;下面的CCtrlView的构造函数，实际上把 &amp;#8220;SysTreeView32&amp;#8221; 传给了 m_strClass，然后我们注意 CtreeView::PreCreateWindow 成员函数中 它又：&amp;nbsp;&amp;nbsp;cs.lpszClass = m_strClass，到这里就真象大白了，原来 MFC 利用 CSplitterWnd 是用 窗口的 PreCreateWindow 来改变窗口 注册类的！！！&lt;BR&gt;&lt;BR&gt;CCtrlView::CCtrlView(LPCTSTR lpszClass, DWORD dwStyle)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&lt;FONT color=#ff1493&gt;m_strClass = lpszClass;&lt;/FONT&gt;&lt;BR&gt;&amp;nbsp;m_dwDefaultStyle = dwStyle;&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;BOOL CCtrlView::PreCreateWindow(CREATESTRUCT&amp;amp; cs)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;ASSERT(cs.lpszClass == NULL);&lt;BR&gt;&amp;nbsp;&lt;FONT color=#ff1493&gt;cs.lpszClass = m_strClass;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;// initialize common controls&lt;BR&gt;&amp;nbsp;VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTLS_REG));&lt;BR&gt;&amp;nbsp;AfxDeferRegisterClass(AFX_WNDCOMMCTLSNEW_REG);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;// map default CView style to default style&lt;BR&gt;&amp;nbsp;// WS_BORDER is insignificant&lt;BR&gt;&amp;nbsp;if ((cs.style | WS_BORDER) == AFX_WS_DEFAULT_VIEW)&lt;BR&gt;&amp;nbsp;&amp;nbsp;cs.style = m_dwDefaultStyle &amp;amp; (cs.style | ~WS_BORDER);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;return CView::PreCreateWindow(cs);&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;于是我们重载了 CHotTreeCtrl 的 PreCreateWindow 函数！&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;BOOL CHotTreeCtrl::PreCreateWindow(CREATESTRUCT&amp;amp; cs)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;// TODO: 在此添加专用代码和/或调用基类&lt;BR&gt;&lt;FONT color=#ff1493&gt;&amp;nbsp;cs.lpszClass = WC_TREEVIEW;&lt;/FONT&gt;&lt;BR&gt;&amp;nbsp;cs.style |= TVS_SHOWSELALWAYS | TVS_SINGLEEXPAND;// | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT;&lt;BR&gt;&amp;nbsp;return CTreeCtrl::PreCreateWindow(cs);&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;OK~~~ TreeCtrl 成功创建了！！！！ MFC~~ 想说爱你不容易! &lt;/P&gt;&lt;img src ="http://blog.vckbase.com/zaboli/aggbug/5068.html" width = "1" height = "1" /&gt;</description></item></channel></rss>