﻿<?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>C++博客-渴望飞翔-随笔分类-MFC</title><link>http://www.cppblog.com/duguguiyu/category/5431.html</link><description>Fly in the C++ Sky...</description><language>zh-cn</language><lastBuildDate>Thu, 22 May 2008 14:40:50 GMT</lastBuildDate><pubDate>Thu, 22 May 2008 14:40:50 GMT</pubDate><ttl>60</ttl><item><title>MFC中制作一个似命令行的输入框</title><link>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34748.html</link><dc:creator>duguguiyu</dc:creator><author>duguguiyu</author><pubDate>Sat, 21 Jul 2007 13:43:00 GMT</pubDate><guid>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34748.html</guid><wfw:comment>http://www.cppblog.com/duguguiyu/comments/34748.html</wfw:comment><comments>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34748.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/duguguiyu/comments/commentRss/34748.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/duguguiyu/services/trackbacks/34748.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1">在做一个MFC软件的时候有一个这样的需求，就是要有类似与AutoCad的命令输入框，如下图所示：</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="51">&nbsp;</p>
<p style="FONT-SIZE: 10pt" align=center goog_ds_charIndex="52"><img src="http://docs.google.com/File?id=ddwgxw9r_171cd6n7gnz" goog_ds_charIndex="53"></p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="55">本着不重写已有功能的原则，在MFC中发掘了一圈，没发现有可用的现成控件，上网搜了一下，发现有人做过，但竟然还收费出售，so faint，只能自己动手做一个。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="135">其实思路还是蛮简单的，就是放个Edit控件处理它的键盘输入事件，防止删除之前的记录和提示信息，还要处理结束命令，比如回车、空格之类的。主要有以下几个步骤：</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="214">1. 将输入框内的字符串分段，比如分成三段log, tip和command，前两段都不能被修改，command的内容为可修改的。在结束了command输入后，要同步各字符串，示例代码如下：</p>
<blockquote goog_ds_charIndex="310">
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="311">void CMainFrame::InitCommand(CString tip)<br goog_ds_charIndex="353">{<br goog_ds_charIndex="355">&nbsp;//&nbsp;记录老字符串，类似于UpdateData(true)</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="387">&nbsp;this-&gt;GetText();</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="407">&nbsp;//&nbsp;设置新的log<br goog_ds_charIndex="419">&nbsp;if(this-&gt;m_log != "")<br goog_ds_charIndex="442">&nbsp;&nbsp;this-&gt;m_log += "\r\n";<br goog_ds_charIndex="467">&nbsp;this-&gt;m_log += tip;</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="490">&nbsp;//&nbsp;更新字符串，类似与UpdataData(false)<br goog_ds_charIndex="521">&nbsp;this-&gt;SetText();</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="541">&nbsp;//&nbsp;将光标置于字符串的尾部（否则光标会在一开始的位置）</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="572">&nbsp;((CEdit *)m_commandDialogBar.GetDlgItem(IDC_COMMAND))-&gt;SetSel(this-&gt;m_log.GetLength(), <br goog_ds_charIndex="661">&nbsp;&nbsp;this-&gt;m_log.GetLength());<br goog_ds_charIndex="689">}</p>
</blockquote>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="693">2. 重载PreTranslateMessage事件，处理键盘信息，示例代码如下：</p>
<blockquote goog_ds_charIndex="736">
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="737">&nbsp;BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)<br goog_ds_charIndex="786">{<br goog_ds_charIndex="788">&nbsp;if(pMsg-&gt;message == WM_KEYDOWN)&nbsp;// 处理键盘按下事件<br goog_ds_charIndex="833">&nbsp;{<br goog_ds_charIndex="836">&nbsp;&nbsp;//&nbsp;判断是否是在脚本输入框上输入的</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="858">&nbsp;&nbsp;if(GetFocus() == m_commandDialogBar.GetDlgItem(IDC_COMMAND))<br goog_ds_charIndex="921">&nbsp;&nbsp;{<br goog_ds_charIndex="925">&nbsp;&nbsp;&nbsp;//&nbsp;如果选择的是非正在输入的文字，抛弃这个事件</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="954">&nbsp;&nbsp;&nbsp;DWORD selectedRegion = ((CEdit *)m_commandDialogBar.GetDlgItem(IDC_COMMAND))-&gt;GetSel();<br goog_ds_charIndex="1045">&nbsp;&nbsp;&nbsp;int selectedStart = LOWORD(selectedRegion);<br goog_ds_charIndex="1092">&nbsp;&nbsp;&nbsp;int selectedEnd&nbsp;&nbsp; = HIWORD(selectedRegion);</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1140">&nbsp;&nbsp;&nbsp;if(selectedStart != selectedEnd &amp;&amp; selectedStart &lt; m_log.GetLength())<br goog_ds_charIndex="1213">&nbsp;&nbsp;&nbsp;&nbsp;return true;</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1231">&nbsp;&nbsp;&nbsp;if(pMsg-&gt;wParam == 8 &amp;&amp; selectedStart &lt;= m_log.GetLength()) //&nbsp;阻止删除之前的文字<br goog_ds_charIndex="1307">&nbsp;&nbsp;&nbsp;&nbsp;return true;</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1325">&nbsp;&nbsp;&nbsp;if(pMsg-&gt;wParam == 13 || pMsg-&gt;wParam == 32) //&nbsp;当输入空格或回车是发送消息<br goog_ds_charIndex="1390">&nbsp;&nbsp;&nbsp;&nbsp;this-&gt;SendCommand();<br goog_ds_charIndex="1415">&nbsp;&nbsp;}<br goog_ds_charIndex="1419">&nbsp;}</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1423">&nbsp;return CMDIFrameWnd::PreTranslateMessage(pMsg);<br goog_ds_charIndex="1472">}</p>
</blockquote>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1476">其中SendCommand的内容可自定义，处理完成后不要忘记执行1的操作，同步一下字符串就OK。实现效果如下：</p>
<p style="FONT-SIZE: 10pt" align=center goog_ds_charIndex="1533"><img src="http://docs.google.com/File?id=ddwgxw9r_1727cn3nmc7" goog_ds_charIndex="1534"></p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1536">当然，这是一个最简单的实现，还有很多问题没有处理，比如自定义菜单，屏蔽系统菜单等；还有很多工作可以做，比如封装成一个自定义控件，做更好的显示效果等等。但基本的思路还是一样的，恩，如果谁有更好的实现方案，也欢迎留言，谢谢先：）</p>
<img height=1 src="http://www.cnblogs.com/duguguiyu/aggbug/826901.html" width=1><br><br>
<div align=right><a style="TEXT-DECORATION: none" href="http://duguguiyu.cnblogs.com/" target=_blank>duguguiyu</a> 2007-07-21 21:43 <a style="TEXT-DECORATION: none" href="http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826901.html#Feedback" target=_blank>发表评论</a></div>
<br>文章来源:<a href="http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826901.html">http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826901.html</a> 
<img src ="http://www.cppblog.com/duguguiyu/aggbug/34748.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/duguguiyu/" target="_blank">duguguiyu</a> 2007-07-21 21:43 <a href="http://www.cppblog.com/duguguiyu/archive/2007/07/21/34748.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MFC中的字符串转换</title><link>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34749.html</link><dc:creator>duguguiyu</dc:creator><author>duguguiyu</author><pubDate>Sat, 21 Jul 2007 13:04:00 GMT</pubDate><guid>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34749.html</guid><wfw:comment>http://www.cppblog.com/duguguiyu/comments/34749.html</wfw:comment><comments>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34749.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/duguguiyu/comments/commentRss/34749.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/duguguiyu/services/trackbacks/34749.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1">在VC++中有着一大把字符串类型。从传统的char*到std::string到CString，简直是多如牛毛。期间的转换相信也是绕晕了许多的人，我曾就是其中的一个。还好，MS还没有丧失功德心，msdn的一篇文章详细的解析了各种字符串的转换问题，链接如下：<a href="http://msdn2.microsoft.com/zh-cn/library/ms235631(VS.80).aspx" goog_ds_charIndex="129"><font color=#551a8b>http://msdn2.microsoft.com/zh-cn/library/ms235631(VS.80).aspx</font></a>。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="194">参照这篇文章，可以搞定同码制的字符串转换，如果有unicode到非unicode的转换问题，还需要另寻高招。我通常就是归一化，把工程属性--&gt;General中的Character set统一选为no set或unicode。每每此时，我都会出奇的想念C#。。。</p>
<img height=1 src="http://www.cnblogs.com/duguguiyu/aggbug/826869.html" width=1><br><br>
<div align=right><a style="TEXT-DECORATION: none" href="http://duguguiyu.cnblogs.com/" target=_blank>duguguiyu</a> 2007-07-21 21:04 <a style="TEXT-DECORATION: none" href="http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826869.html#Feedback" target=_blank>发表评论</a></div>
<br>文章来源:<a href="http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826869.html">http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826869.html</a> 
<img src ="http://www.cppblog.com/duguguiyu/aggbug/34749.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/duguguiyu/" target="_blank">duguguiyu</a> 2007-07-21 21:04 <a href="http://www.cppblog.com/duguguiyu/archive/2007/07/21/34749.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MFC的非模态对话框资源管理</title><link>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34750.html</link><dc:creator>duguguiyu</dc:creator><author>duguguiyu</author><pubDate>Sat, 21 Jul 2007 12:56:00 GMT</pubDate><guid>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34750.html</guid><wfw:comment>http://www.cppblog.com/duguguiyu/comments/34750.html</wfw:comment><comments>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34750.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/duguguiyu/comments/commentRss/34750.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/duguguiyu/services/trackbacks/34750.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1">非模态对话框比模态对话框更难使用这是众所周知的，这是由于模态对话框运行时，阻塞了其父窗口的消息循环，使其能自成一派，所以能够怡然自得。但非模态对话框只相当于一个由父窗体创建的一个同级的Hwnd，就像一个长大了的孩子，可以和父母并驾齐驱了，需要父母管又不能管的太厉害，其资源管理、通信都会比模态的更为复杂。&nbsp;&nbsp;</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1">很多时候，能用模态对话框的情况下，都会用模态的。虽然<a title=Copper href="http://www.cnblogs.com/duguguiyu/archive/2007/06/03/769138.html" target=_blank><font color=#551a8b>Copper</font></a> 老先生指着鼻子苦口婆心的教导了我们，但有时候人懒脸皮也就厚了，无所谓了。但，世界总是很残酷，很多时候（比如需要在处理对话框事件的时候也能响应窗体事件），我们不得不去面对非模态对话框。其实了解了资源管理的模式，就像扒开了非模态对话框半遮的琵琶，可以很坦然的面对了。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="159">模态对话框的资源分成两种，一种是内存资源，一种是非内存资源。单看非内存资源的管理，其实和内存资源的管理原理是一样的。在C++中，内存资源的管理讲究new和delete配对，同理，非内存资源的管理需要create和destroy出双入对。在<a title=这篇文章 href="http://www.vckbase.com/study/article/vc_chap/chap5_4.htm" target=_blank><font color=#551a8b>这篇文章</font></a>中，基本体现了非模态对话框资源管理的一个基本模式，即内存资源管理和非内存资源同步。 </p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="405">这样通过判断内存资源是否占用（即指针是否为空）就可以判断非内存资源的使用状况。当指针为空，说明对话框还未创建（非内存资源未申请）；当指针不为空，对话框已创建，正处于可见或不可见状态。这样将两部分资源管理合并在一起了，只需要判断指针是否为空就可以了解对话框资源的状态。一些内存管理的手段，比如类管理思想（将delete和destroy放到类的析构函数中），可以实现资源的自动管理。 </p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="597">为了实现这种管理模式，要注意以下几点： </p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="619">1. 在堆上分配非模态对话框的内存资源，通俗一点的描述就是不要用这种方式：CXXDialog t;而是用这种方式：CXXDialog *t = new CXXDialog();来分配内存。 </p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="714">2. 同步构造和析构过程，就是说有new一定配上个create，delete一定要勾搭一个destroy。 </p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="770">3. 被delete的内存指针一定要置空，也就是下面两句要接踵而至：delete xx;和xx == null;。其实这也是普通的内存管理需要遵循的一个良好习惯。 </p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="770">了解了这些，非模态对话框也会只有温柔没有狰狞。</p>
<img height=1 src="http://www.cnblogs.com/duguguiyu/aggbug/826858.html" width=1><br><br>
<div align=right><a style="TEXT-DECORATION: none" href="http://duguguiyu.cnblogs.com/" target=_blank>duguguiyu</a> 2007-07-21 20:56 <a style="TEXT-DECORATION: none" href="http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826858.html#Feedback" target=_blank>发表评论</a></div>
<br>文章来源:<a href="http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826858.html">http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826858.html</a> 
<img src ="http://www.cppblog.com/duguguiyu/aggbug/34750.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/duguguiyu/" target="_blank">duguguiyu</a> 2007-07-21 20:56 <a href="http://www.cppblog.com/duguguiyu/archive/2007/07/21/34750.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>互引头文件的一种解决策略</title><link>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34751.html</link><dc:creator>duguguiyu</dc:creator><author>duguguiyu</author><pubDate>Sat, 21 Jul 2007 11:37:00 GMT</pubDate><guid>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34751.html</guid><wfw:comment>http://www.cppblog.com/duguguiyu/comments/34751.html</wfw:comment><comments>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34751.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/duguguiyu/comments/commentRss/34751.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/duguguiyu/services/trackbacks/34751.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1">在C++中经常会涉及到处于不同头文件的类互相引用的情况，有时候头文件引用（include）会搞得很乱，导致报一堆的错。其实遵循一定规则，可以避免大部分的混乱。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="82">首先，要对头文件进行处理，保证不会出现重定义的错误。这个应该每个人都会，通常有两种做法：</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="128">1. 在.cpp文件中添加保护，比如在.cpp文件中添加：</p>
<blockquote goog_ds_charIndex="159">
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="160">#ifndef _XX_H_<br goog_ds_charIndex="175">#define _XX_H_<br goog_ds_charIndex="190">#include "xx.h"<br goog_ds_charIndex="206">#endif</p>
</blockquote>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="215">2. 在.h中添加保护，比如在xx.h文件中添加：</p>
<blockquote goog_ds_charIndex="242">
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="243">#ifndef _XX_H_<br goog_ds_charIndex="258">#define _XX_H_<br goog_ds_charIndex="273">// 头文件声明内容<br goog_ds_charIndex="284">#endif</p>
</blockquote>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="293">_XX_H_是我比较习惯的命名方式，其他的命名方式，比如__XX__H__，XX_H等等，只要足够Unique就好。建议使用第二种方式进行重定义的保护，一劳永逸而且具有通用性，任何人拿来就能用，不需要考虑保护问题。当然，如果在VS（03以上吧？）下，最好的解决方案是用#pragma once，更为简单有效。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="449">其次，最好将所有头文件需要用到的自定义类（或函数）都在定义前声明一下，比如在xx.h的类xx中需要用到yy.h中的yy类，那么最好做以下的处理：</p>
<blockquote goog_ds_charIndex="523">
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="524">class yy;</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="535">class xx<br goog_ds_charIndex="544">{<br goog_ds_charIndex="546">&nbsp;// 实现内容<br goog_ds_charIndex="555">};</p>
</blockquote>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="560">这样就可以保证头文件引用的次序不会对结果造成影响。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="587">通常，保证以上两点，通常涉及到类互指的问题都可以解决。当然如果天生就有设计问题，无论如何都是没有办法的，比如：</p>
<blockquote goog_ds_charIndex="644">
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="645">// xx.h <br goog_ds_charIndex="654">class xx<br goog_ds_charIndex="663">{<br goog_ds_charIndex="665">&nbsp;yy t;<br goog_ds_charIndex="672">};</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="676">// yy.h<br goog_ds_charIndex="684">class yy<br goog_ds_charIndex="693">{<br goog_ds_charIndex="695">&nbsp;xx t;<br goog_ds_charIndex="702">};</p>
</blockquote>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="707">不难看出，这是个递归定义，编译器无法确定类xx和yy的大小，就无法通过编译。一种解决策略是采用指针，比如：</p>
<blockquote goog_ds_charIndex="762">
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="763">// xx.h <br goog_ds_charIndex="772">class xx<br goog_ds_charIndex="781">{<br goog_ds_charIndex="783">&nbsp;yy* t;<br goog_ds_charIndex="791">};</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="795">// yy.h<br goog_ds_charIndex="803">class yy<br goog_ds_charIndex="812">{<br goog_ds_charIndex="814">&nbsp;xx* t;<br goog_ds_charIndex="822">};</p>
</blockquote>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="827">当然，具体情况具体分析，提取一个更高层的类等手段都可以考虑。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="859">还有一个问题，我一直也心存疑问，就是头文件组织问题。在VS中建立一个MFC工程，都会产生一对stdafx文件，按照这种思想我们把工程下通用的头文件都放入stdafx.h中，在.cpp文件的最开始统一#include "stdafx.h"，这样就可以在.h文件中引用很少的头文件。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1000">这种策略在单工程时很好用，相当于做了头文件组织级别的重用，但它违反了我一直恪守的一个原则即谁的头文件谁负责，指.h和.cpp各自负责各自所需的头文件。于是在跨工程的时候会出现一些问题。比如在B工程B的某个.h中引用了工程B中的一个头文件，由于编译次序问题，这个头文件可能无法被编译。不知道大家都如何处理头文件组织问题的，望指教。</p>
<img height=1 src="http://www.cnblogs.com/duguguiyu/aggbug/826821.html" width=1><br><br>
<div align=right><a style="TEXT-DECORATION: none" href="http://duguguiyu.cnblogs.com/" target=_blank>duguguiyu</a> 2007-07-21 19:37 <a style="TEXT-DECORATION: none" href="http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826821.html#Feedback" target=_blank>发表评论</a></div>
<br>文章来源:<a href="http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826821.html">http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826821.html</a> 
<img src ="http://www.cppblog.com/duguguiyu/aggbug/34751.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/duguguiyu/" target="_blank">duguguiyu</a> 2007-07-21 19:37 <a href="http://www.cppblog.com/duguguiyu/archive/2007/07/21/34751.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MFC控件之CControlBar</title><link>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34752.html</link><dc:creator>duguguiyu</dc:creator><author>duguguiyu</author><pubDate>Sat, 21 Jul 2007 11:35:00 GMT</pubDate><guid>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34752.html</guid><wfw:comment>http://www.cppblog.com/duguguiyu/comments/34752.html</wfw:comment><comments>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34752.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/duguguiyu/comments/commentRss/34752.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/duguguiyu/services/trackbacks/34752.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1">有时候我们经常把对话框和视图结合起来，做成AutoCAD命令输入框、PhotoShop浮动框之类的效果。但很奇怪的是我看过的MFC的书上都没有特别说明过这样的工作该如何去做，我刚接触MFC的时候都是通过控制非模态对话框来模拟的，后来才知道这些工作是通过CControlBar的派生类来完成的。比如CDialogBar就是加载一个已有的对话框资源，嵌入Frame中，和视图配合使用。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="193">其实知道了有这么个东西，剩下的问题都不能称做问题了，其使用和CToolBar类似，可以通过<a href="http://msdn2.microsoft.com/zh-cn/library/wc9sxcw1(VS.80).aspx" goog_ds_charIndex="239"><font color=#551a8b>http://msdn2.microsoft.com/zh-cn/library/wc9sxcw1(VS.80).aspx</font></a>下载MSDN示例，当然也可以在本机的MSDN搜索CDialogBar获得。</p>
<img height=1 src="http://www.cnblogs.com/duguguiyu/aggbug/826819.html" width=1><br><br>
<div align=right><a style="TEXT-DECORATION: none" href="http://duguguiyu.cnblogs.com/" target=_blank>duguguiyu</a> 2007-07-21 19:35 <a style="TEXT-DECORATION: none" href="http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826819.html#Feedback" target=_blank>发表评论</a></div>
<br>文章来源:<a href="http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826819.html">http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826819.html</a> 
<img src ="http://www.cppblog.com/duguguiyu/aggbug/34752.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/duguguiyu/" target="_blank">duguguiyu</a> 2007-07-21 19:35 <a href="http://www.cppblog.com/duguguiyu/archive/2007/07/21/34752.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MFC动态菜单全攻略</title><link>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34753.html</link><dc:creator>duguguiyu</dc:creator><author>duguguiyu</author><pubDate>Sat, 21 Jul 2007 11:34:00 GMT</pubDate><guid>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34753.html</guid><wfw:comment>http://www.cppblog.com/duguguiyu/comments/34753.html</wfw:comment><comments>http://www.cppblog.com/duguguiyu/archive/2007/07/21/34753.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/duguguiyu/comments/commentRss/34753.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/duguguiyu/services/trackbacks/34753.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1">做一个MFC程序的时候碰到一个需求。就是需要根据定制情况，动态生成菜单，菜单的具体结构和信息是之前不知道的（因此不能利用工具构造），点击不同类型的菜单会触发特定的一类事件（需要动态绑定事件）。这种需求实际是蛮不BT的，很多场合下都可能会有，用C#写了个Demo花了不到半个小时。但转到MFC下来写，就费尽周折。其实这个问题代表了在MFC中动态创建资源绑定事件的一般性问题，所以总结一下。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="196">动态创建菜单需要先了<strong style="FONT-WEIGHT: normal" goog_ds_charIndex="207">解</strong>CMenu类。通常我们利用工具绘制一个菜单，每一个菜单项下都可以视为有一个CMenu类。它们联系在一起，形成树状。典型的一个菜单对应过来是如下图这个样子：</p>
<div style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; FONT-SIZE: 10pt; PADDING-BOTTOM: 1em; PADDING-TOP: 1em; TEXT-ALIGN: center" goog_ds_charIndex="288"><img src="http://docs.google.com/File?id=ddwgxw9r_170cj6hf7c3" goog_ds_charIndex="289"></div>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="291">&nbsp;</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="292">如上，CMenu可以分成三种，一个是Popup（黄色），一个是Separator（灰色），一个是Item（红色）。前两种都是没有ID信息的，Popup有一个指针，指向其SubMenu；Item保存各种信息有ID可以响应事件；Separator，恩，基本是一穷二白的。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="427">CMenu的CreateMenu方法可以创建一个菜单资源，用DeleteMenu（包含所有子菜单）或DestoryMenu可以销毁菜单资源，用AppendMenu可以添加一个菜单。了解这些内容，就可以开工了，现实现上图所示的MainSubMenu1下菜单的动态创建，代码如下：<br goog_ds_charIndex="566"></p>
<blockquote goog_ds_charIndex="568">
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="569">&nbsp;&nbsp;&nbsp; // 假设在ChildFrm中，调用该方法获得当前的主菜单指针<br goog_ds_charIndex="605">&nbsp;&nbsp;&nbsp; CMenu* mainMenu = AfxGetMainWnd()-&gt;GetMenu();<br goog_ds_charIndex="655">&nbsp;&nbsp;&nbsp; CMenu* subMenu = NULL;</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="683"><br goog_ds_charIndex="684"></p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="686">&nbsp;&nbsp;&nbsp; // 遍历主菜单下的各级菜单寻找名为MainSubMenu1的菜单<br goog_ds_charIndex="724"></p>
&nbsp;&nbsp;&nbsp; int menuCount = mainMenu-&gt;GetMenuItemCount();<br goog_ds_charIndex="775">
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="776">&nbsp;&nbsp;&nbsp; for(int i = 0; i &lt; menuCount; i++)<br goog_ds_charIndex="815">&nbsp;&nbsp;&nbsp; {<br goog_ds_charIndex="821">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CString menuName;<br goog_ds_charIndex="847">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(mainMenu-&gt;GetMenuStringA(i, menuName, MF_BYPOSITION)<br goog_ds_charIndex="911">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &amp;&amp; menuName == "&amp;MainSubMenu1")<br goog_ds_charIndex="955">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br goog_ds_charIndex="965">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; drawingMenu = mainMenu-&gt;GetSubMenu(i);<br goog_ds_charIndex="1016">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br goog_ds_charIndex="1035">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br goog_ds_charIndex="1045">&nbsp;&nbsp;&nbsp; }<br goog_ds_charIndex="1051"><br goog_ds_charIndex="1052">&nbsp;&nbsp;&nbsp; // 移除原有的菜单项<br goog_ds_charIndex="1068">&nbsp;&nbsp;&nbsp; int subMenu1Count = subMenu-&gt;GetMenuItemCount();<br goog_ds_charIndex="1121">&nbsp;&nbsp;&nbsp; for(int i = subMenu1Count - 1; i &gt;= 0; i--)<br goog_ds_charIndex="1169">&nbsp;&nbsp;&nbsp; {<br goog_ds_charIndex="1175">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; subMenu-&gt;DeleteMenu(i, MF_BYPOSITION);<br goog_ds_charIndex="1222">&nbsp;&nbsp;&nbsp; }<br goog_ds_charIndex="1228"><br goog_ds_charIndex="1229">&nbsp;&nbsp;&nbsp; // 动态添加Item菜单项<br goog_ds_charIndex="1248">&nbsp;&nbsp;&nbsp; for(int i = 0; i &lt; 2; i++)<br goog_ds_charIndex="1279">&nbsp;&nbsp;&nbsp; {</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1286">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CString message = "";<br goog_ds_charIndex="1316"></p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1318">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; subMenu-&gt;AppendMenuA(MF_STRING, ID_BEGIN + i, message.Format("SubSubMenu%i", i);</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1408">&nbsp;&nbsp;&nbsp; }</p>
<br goog_ds_charIndex="1415">
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1416">&nbsp;&nbsp;&nbsp; // 添加分隔符<br goog_ds_charIndex="1429"></p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1431">&nbsp;&nbsp;&nbsp; subMenu-&gt;AppendMenuA(MF_SEPARATOR);</p>
<br goog_ds_charIndex="1472">
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1473">&nbsp;&nbsp;&nbsp; // 添加弹出式子菜单<br goog_ds_charIndex="1489"></p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1491">&nbsp;&nbsp;&nbsp; CMenu * popupMenu = new CMenu();<br goog_ds_charIndex="1528">&nbsp;&nbsp;&nbsp; popupMenu-&gt;CreateMenu();<br goog_ds_charIndex="1557">&nbsp;&nbsp;&nbsp; for(int i = 0; i &lt; 2; i++)<br goog_ds_charIndex="1588">&nbsp;&nbsp;&nbsp; {</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1595">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CString message = "";<br goog_ds_charIndex="1625"></p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1627">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; popupMenu-&gt;AppendMenuA(MF_STRING, ID_BEGIN + 2 + i, message.Format("PopupSubMenu%i", i));</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1726">&nbsp;&nbsp;&nbsp; }<br goog_ds_charIndex="1732">&nbsp;&nbsp;&nbsp; subMenu-&gt;AppendMenuA(MF_POPUP, (UINT_PTR)popupMenu-&gt;operator HMENU(), "PopupMenu");<br goog_ds_charIndex="1820"></p>
</blockquote>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1823">有几个需要注意的地方，一个是主菜单的指针获得，可以参考<a href="http://www.cnblogs.com/duguguiyu/archive/2007/06/22/792511.html" target=_blank>《MFC框架各部分指针获取方式》</a>一文。另一个是Popup的菜单建立，策略是分成两部分，先new出内存在Create出资源，缺一不可。最后一个是为每个Item菜单合理分配ID，这些ID须事先预留出来，在MFC中，至少40000到49000通常都是没人用。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1978">这也就引出下一个问题，即菜单事件的动态绑定。我们知道在.net中，事件是真正动态绑定的，而MFC中的事件都是只能静态绑定，这是由两者的编译方式决定的。所以，在MFC中需要定义菜单事件，你需要先挖好坑（预留足够ID），规定每个坑种什么罗卜（将不同类型的ID绑定到不同类别的事件处理函数上），最后才能按坑种罗卜（为执行相应事件的菜单设置相应的ID）。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="2153">可以有两种方式来绑定对应ID处理的事件，一个是通过ON_COMMAND_RANGE宏（想一下ON_COMMAND宏会不会派上用场？）在MessageMap里绑定批量处理事件的函数；另一个是重载PreTranslateMessage函数，截获并判断ID来进行处理。思想都是类似的。值得注意的是，通常还需要配套使用ON_UPDATE_COMMAND_UI_RANGE来保证动态创建的菜单Enable为True，否则很可能菜单不可以点击（我就被郁闷过很久：（）。<br goog_ds_charIndex="2382"></p>
<img height=1 src="http://www.cnblogs.com/duguguiyu/aggbug/826816.html" width=1><br><br>
<div align=right><a style="TEXT-DECORATION: none" href="http://duguguiyu.cnblogs.com/" target=_blank>duguguiyu</a> 2007-07-21 19:34 <a style="TEXT-DECORATION: none" href="http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826816.html#Feedback" target=_blank>发表评论</a></div>
<br>文章来源:<a href="http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826816.html">http://www.cnblogs.com/duguguiyu/archive/2007/07/21/826816.html</a> 
<img src ="http://www.cppblog.com/duguguiyu/aggbug/34753.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/duguguiyu/" target="_blank">duguguiyu</a> 2007-07-21 19:34 <a href="http://www.cppblog.com/duguguiyu/archive/2007/07/21/34753.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MFC框架各部分指针获取方式</title><link>http://www.cppblog.com/duguguiyu/archive/2007/06/22/34754.html</link><dc:creator>duguguiyu</dc:creator><author>duguguiyu</author><pubDate>Thu, 21 Jun 2007 17:33:00 GMT</pubDate><guid>http://www.cppblog.com/duguguiyu/archive/2007/06/22/34754.html</guid><wfw:comment>http://www.cppblog.com/duguguiyu/comments/34754.html</wfw:comment><comments>http://www.cppblog.com/duguguiyu/archive/2007/06/22/34754.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/duguguiyu/comments/commentRss/34754.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/duguguiyu/services/trackbacks/34754.html</trackback:ping><description><![CDATA[<span style="FONT-SIZE: 10pt">前人在CSDN总结的，曾经帮助过我，整理总结一下，希望也能帮助一下别人。</span><br goog_ds_charIndex="37">&nbsp;&nbsp;&nbsp;&nbsp;
<div style="FONT-SIZE: 10pt" goog_ds_charIndex="43">
<table cellSpacing=0 cellPadding=3 width=580 border=1 goog_ds_charIndex="44">
    <tbody goog_ds_charIndex="45">
        <tr goog_ds_charIndex="46">
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="47">
            <p style="FONT-SIZE: 10pt" align=center goog_ds_charIndex="48">&nbsp;</p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="50">
            <p style="FONT-SIZE: 10pt" align=center goog_ds_charIndex="51"><strong goog_ds_charIndex="52">获得CWinApp </strong></p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="66">
            <p style="FONT-SIZE: 10pt" align=center goog_ds_charIndex="67"><strong goog_ds_charIndex="68">获得CMainFrame </strong></p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="85">
            <p style="FONT-SIZE: 10pt" align=center goog_ds_charIndex="86"><strong goog_ds_charIndex="87">获得CChildFrame </strong></p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="105">
            <p style="FONT-SIZE: 10pt" align=center goog_ds_charIndex="106"><strong goog_ds_charIndex="107">获得CDocument </strong></p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="123">
            <p style="FONT-SIZE: 10pt" align=center goog_ds_charIndex="124"><strong goog_ds_charIndex="125">获得CView</strong> </p>
            </td>
        </tr>
        <tr goog_ds_charIndex="138">
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="139"><strong goog_ds_charIndex="140">在CWinApp中</strong> </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="153">
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="154">&nbsp;</p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="156">
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="157">AfxGetMainWnd() </p>
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="175">m_pMainWnd </p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="189">
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="190">AfxGetMainWnd()-&gt;MDIGetActive() </p>
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="224">AfxGetMainWnd()-&gt;GetActiveFrame()</p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="260">
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="261">SDI:AfxGetMainWnd()-&gt;GetActiveView()-&gt;GetDocument()</p>
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="314">MDI:AfxGetMainWnd()-&gt;MDIGetActive()-&gt;GetActiveView()-&gt;GetDocument()</p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="384">SDI:AfxGetMainWnd()-&gt;GetActiveView()&nbsp;&nbsp;<br goog_ds_charIndex="423">MDI:AfxGetMainWnd()-&gt;MDIGetActive()-&gt;GetActiveView()&nbsp;</td>
        </tr>
        <tr goog_ds_charIndex="479">
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="480"><strong goog_ds_charIndex="481">在CMainFrame中</strong> </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="497">
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="498">AfxGetApp() </p>
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="512">theApp </p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="522"></td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="523">
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="524">MDIGetActive() </p>
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="541">GetActiveFrame()</p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="560">SDI:GetActiveView()-&gt;GetDocument()&nbsp;&nbsp;<br goog_ds_charIndex="597">MDI:MDIGetActive()-&gt;GetActiveView()-&gt;GetDocument()&nbsp;&nbsp;</td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="651">SDI:GetActiveView()&nbsp;&nbsp;<br goog_ds_charIndex="673">MDI:MDIGetActive()-&gt;GetActiveView()&nbsp;</td>
        </tr>
        <tr goog_ds_charIndex="712">
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="713"><strong goog_ds_charIndex="714">在CChildFrame中</strong> </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="731">
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="732">AfxGetApp() </p>
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="746">theApp </p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="756">GetParentFrame()&nbsp; </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="776">
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="777">&nbsp;</p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="779">GetActiveView()-&gt;GetDocument()&nbsp;&nbsp;</td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="813">GetActiveView()</td>
        </tr>
        <tr goog_ds_charIndex="831">
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="832"><strong goog_ds_charIndex="833">在CDocument中</strong> </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="848">
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="849">AfxGetApp() </p>
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="863">theApp </p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="873">AfxGetMainWnd()&nbsp;&nbsp; </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="893">
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="894">AfxGetMainWnd()-&gt;MDIGetActive() </p>
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="928">AfxGetMainWnd()-&gt;GetActiveFrame()</p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="964"></td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="965">POSITION&nbsp;&nbsp; pos&nbsp;&nbsp; =&nbsp;&nbsp; GetFirstViewPosition();GetNextView(pos)&nbsp;&nbsp;</td>
        </tr>
        <tr goog_ds_charIndex="1030">
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="1031"><strong goog_ds_charIndex="1032">在CView中</strong> </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="1043">
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="1044">AfxGetApp() </p>
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="1058">theApp </p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="1068">AfxGetMainWnd()&nbsp;&nbsp; </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="1088">GetParentFrame()&nbsp;&nbsp; </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="1109">GetDocument()</td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="1124"></td>
        </tr>
        <tr goog_ds_charIndex="1126">
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="1127"><strong goog_ds_charIndex="1128">在其他类中</strong> </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="1137">
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="1138">AfxGetApp() </p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="1153">AfxGetMainWnd()&nbsp;&nbsp; </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="1173">
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="1174">AfxGetMainWnd()-&gt;MDIGetActive() </p>
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="1208">AfxGetMainWnd()-&gt;GetActiveFrame()&nbsp;</p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="1245">
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="1246">SDI:AfxGetMainWnd()-&gt;GetActiveView()-&gt;GetDocument()</p>
            <p style="FONT-SIZE: 10pt" goog_ds_charIndex="1299">MDI:AfxGetMainWnd()-&gt;MDIGetActive()-&gt;GetActiveView()-&gt;GetDocument()</p>
            </td>
            <td style="FONT-SIZE: 10pt" width="16.66%" goog_ds_charIndex="1369">SDI:AfxGetMainWnd()-&gt;GetActiveView()&nbsp;&nbsp;<br goog_ds_charIndex="1408">MDI:AfxGetMainWnd()-&gt;MDIGetActive()-&gt;GetActiveView()&nbsp;</td>
        </tr>
    </tbody>
</table>
</div>
<div style="FONT-SIZE: 10pt" goog_ds_charIndex="1467">&nbsp;</div>
<div style="FONT-SIZE: 10pt" goog_ds_charIndex="1468">理一理MFC的这几个类的关系，可以很容易明白上面的这些乱七八糟的逻辑。</div>
<div style="FONT-SIZE: 10pt" goog_ds_charIndex="1505">App是应用域，所有的域中的东西都可以通过全局函数访问到它。</div>
<div style="FONT-SIZE: 10pt" goog_ds_charIndex="1537">MainFrame是主框架，也基本可以用全局函数访问到。</div>
<div style="FONT-SIZE: 10pt" goog_ds_charIndex="1567">MainFrame下是若干个ChildFrame，ChildFrame中若干个View和Document（可能不成对），ChildFrame管理着View，View和Document进行互操作。</div>
<div style="FONT-SIZE: 10pt" goog_ds_charIndex="1666">因此整体框架就出来了，一般除了直接应用的关系都可以通过MainFrame--&gt;Active ChildFrame--&gt;Active View--&gt;Document这条线进行访问，这应该叫什么来自？万能方法吧^_^。</div>
<div style="FONT-SIZE: 10pt" goog_ds_charIndex="1775">恕我懒惰，不愿意画一个更详细的图解，凑合着看看吧。</div>
<br goog_ds_charIndex="1802"><img height=1 src="http://www.cnblogs.com/duguguiyu/aggbug/792511.html" width=1><br><br>
<div align=right><a style="TEXT-DECORATION: none" href="http://duguguiyu.cnblogs.com/" target=_blank>duguguiyu</a> 2007-06-22 01:33 <a style="TEXT-DECORATION: none" href="http://www.cnblogs.com/duguguiyu/archive/2007/06/22/792511.html#Feedback" target=_blank>发表评论</a></div>
<br>文章来源:<a href="http://www.cnblogs.com/duguguiyu/archive/2007/06/22/792511.html">http://www.cnblogs.com/duguguiyu/archive/2007/06/22/792511.html</a> 
<img src ="http://www.cppblog.com/duguguiyu/aggbug/34754.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/duguguiyu/" target="_blank">duguguiyu</a> 2007-06-22 01:33 <a href="http://www.cppblog.com/duguguiyu/archive/2007/06/22/34754.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>令我头疼的MFC命名</title><link>http://www.cppblog.com/duguguiyu/archive/2007/06/21/34755.html</link><dc:creator>duguguiyu</dc:creator><author>duguguiyu</author><pubDate>Thu, 21 Jun 2007 15:18:00 GMT</pubDate><guid>http://www.cppblog.com/duguguiyu/archive/2007/06/21/34755.html</guid><wfw:comment>http://www.cppblog.com/duguguiyu/comments/34755.html</wfw:comment><comments>http://www.cppblog.com/duguguiyu/archive/2007/06/21/34755.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/duguguiyu/comments/commentRss/34755.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/duguguiyu/services/trackbacks/34755.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1">最近在写一些关于MFC的东西，是因为做了些MFC的项目，一些零散的东西需要总结一下。但这并不代表我有些喜欢他了，其实还是蛮讨厌的。毕竟看了.Net Framework，再看N多年前的MFC，多少是有些不顺眼的。机理上的东西不敢多说，有些变量和方法名字的设置，站在FCL的设计角度看了，多少觉得有些不爽。也许是我太弱，也许是因为它的设计上考虑还是没有足够的经验，列举一些，娱乐娱乐。 </p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="194">1. 在构造一个自定义的Dialog对象时，我们会传入一个CWnd的指针进去，那个名为pParent的对象。但当我在Dialog中调用GetParent函数的时候，无论传进的是什么指针（比如CYourView），得到的返回值都是指向CMainFrame的指针。曾经由于这个我调了N久的程序，我承认这是由于我对MFC的了解不够造成的，但这名字也太具有迷惑性了吧。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="194">2. 当然还有臭名昭著的UpdateData函数，很荣幸在这点上我和大师一样，每次用到的时候都要停下来查看一下才能分清楚那个诡异的bool变量的意义。也许这在有IDE的时候不是问题，但问题是我看书的时候就会很麻烦了。分离成两个明确命名的函数，也许会好很多。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="194">3. ShowWindow。恩就是它。看到这个名字，不熟悉MFC的人应该都会觉得它是用来显示一个窗口的。但...，其实它兼有显示和隐藏窗口的功能，决定这一切的又是一个诡异的bool量...</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="194">4. MoveWindow和SetWindowPos。这一对不够专注的兄弟。它们太强大了，所能做的事远不止Move和SetPos那么简单，当我想改变一个窗体大小的时候，我翻来覆去的找函数，万万没想到，原来是这对名不副实的兄弟的工作，Faint...</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="194">5. GetWindowRect和GetClientRect。其实他们也许没有问题，有问题的是我，我不喜欢用引用量代替一个貌似应该由返回值完成的东西...</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="194">6. SelectObject。为什么你传入一个新的Object，它返回一个老的Object呢？不止我一个人，很多人都被这个搞晕过，其实我也不明白，一个函数做两个函数的事，这确实有点热心过度了吧...</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="194">7. afx_msg。一个永远都没被用到的预留量，这样的东西在MFC中有很多...</p>
<img height=1 src="http://www.cnblogs.com/duguguiyu/aggbug/792426.html" width=1><br><br>
<div align=right><a style="TEXT-DECORATION: none" href="http://duguguiyu.cnblogs.com/" target=_blank>duguguiyu</a> 2007-06-21 23:18 <a style="TEXT-DECORATION: none" href="http://www.cnblogs.com/duguguiyu/archive/2007/06/21/792426.html#Feedback" target=_blank>发表评论</a></div>
<br>文章来源:<a href="http://www.cnblogs.com/duguguiyu/archive/2007/06/21/792426.html">http://www.cnblogs.com/duguguiyu/archive/2007/06/21/792426.html</a> 
<img src ="http://www.cppblog.com/duguguiyu/aggbug/34755.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/duguguiyu/" target="_blank">duguguiyu</a> 2007-06-21 23:18 <a href="http://www.cppblog.com/duguguiyu/archive/2007/06/21/34755.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>了解VS2005为你的MFC程序做的一些事</title><link>http://www.cppblog.com/duguguiyu/archive/2007/06/21/34756.html</link><dc:creator>duguguiyu</dc:creator><author>duguguiyu</author><pubDate>Wed, 20 Jun 2007 16:20:00 GMT</pubDate><guid>http://www.cppblog.com/duguguiyu/archive/2007/06/21/34756.html</guid><wfw:comment>http://www.cppblog.com/duguguiyu/comments/34756.html</wfw:comment><comments>http://www.cppblog.com/duguguiyu/archive/2007/06/21/34756.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/duguguiyu/comments/commentRss/34756.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/duguguiyu/services/trackbacks/34756.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 10pt" goog_ds_charIndex="1">利用MFC向导建立一个工程，然后开始编码。这就是我通常做一个MFC工程的开始。但向导可不是一个守规矩的东西，它会为你添加很多的代码，为你设置大量的编译和链接选项。大部分时候这种工作是善意的，但是好心不一定办好事，你不好好了解它，它会给你带来很多的麻烦。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="129">在配置一个基于OpenCasCade的程序中，我就遇到了很多麻烦。MFC向导在它所生成的View, Document等架构类中都添加了一段如下代码：</p>
<blockquote goog_ds_charIndex="203">
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="204">#ifdef _DEBUG<br goog_ds_charIndex="218">#define new DEBUG_NEW<br goog_ds_charIndex="240">#endif</p>
</blockquote>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="249">在Debug状态下（VS会为你默认添加一个_DEBUG的预编译项），你在该类中调用的new操作符都会被DEBUG_NEW所取代，请警惕这个行为，如果你重载过某个类的new，很可能就会由于它导致无法编译通过或运行不正确。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="360">除此之外一些默认的设置也要注意，在VS2005中是默认支持Unicode的，它会在你的编译选项中加入/D "_UNICODE" /D "UNICODE"。这就会使得CString和你可能用到的std::string存在很麻烦的转换问题。你需要修改项目属性中General--&gt;Character Set为not set，将其设为ununicode，保证与std::string的一致（当然你还可以运用其他的解决方法满足你的需求）。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="360">有时候IDE也会&#8220;好心办坏事&#8221;，比如在一个解决方案中有两个工程，你为A添加B的编译依赖，在A的链接选项中就会悄悄加上对B生成的dll的引用。当你某天整理代码取消了这个依赖的时候，你突然发现莫名的出现了很多link错误。不要慌张，在A中添加上B链接项就好了，这项工作其实是你必须自己做的，只是你添加了依赖编译器非常主动的帮你完成了。</p>
<p style="FONT-SIZE: 10pt" goog_ds_charIndex="360">也许你看上面的错误都很简单，但如果不小心，也许有天也会像我一样深陷其中半天爬不出来。总之，在天天用VS2005建MFC工程的时候，提前做好两件事。一件是通读一遍系统默认生成的代码，做到心中有数，每一条莫名其妙的东西都要了解一下它的用途；另一件是在刚开始和改变了工程属性之后查看一下你的编译和链接命令，搞清楚它做了什么事，有时候命令行虽然难记一点，但确实是一目了然，你可以不必每天用命令行编译程序，但一定要对这些命令心如明镜，了如指掌才好。</p>
<img height=1 src="http://www.cnblogs.com/duguguiyu/aggbug/791161.html" width=1><br><br>
<div align=right><a style="TEXT-DECORATION: none" href="http://duguguiyu.cnblogs.com/" target=_blank>duguguiyu</a> 2007-06-21 00:20 <a style="TEXT-DECORATION: none" href="http://www.cnblogs.com/duguguiyu/archive/2007/06/21/791161.html#Feedback" target=_blank>发表评论</a></div>
<br>文章来源:<a href="http://www.cnblogs.com/duguguiyu/archive/2007/06/21/791161.html">http://www.cnblogs.com/duguguiyu/archive/2007/06/21/791161.html</a> 
<img src ="http://www.cppblog.com/duguguiyu/aggbug/34756.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/duguguiyu/" target="_blank">duguguiyu</a> 2007-06-21 00:20 <a href="http://www.cppblog.com/duguguiyu/archive/2007/06/21/34756.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>