﻿<?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++博客-空杯子-随笔分类-理解流程</title><link>http://www.cppblog.com/lingling520/category/15564.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 27 Dec 2010 03:32:50 GMT</lastBuildDate><pubDate>Mon, 27 Dec 2010 03:32:50 GMT</pubDate><ttl>60</ttl><item><title>VC设置视图背景颜色方法 </title><link>http://www.cppblog.com/lingling520/archive/2010/12/26/137530.html</link><dc:creator>胡志刚</dc:creator><author>胡志刚</author><pubDate>Sun, 26 Dec 2010 15:18:00 GMT</pubDate><guid>http://www.cppblog.com/lingling520/archive/2010/12/26/137530.html</guid><wfw:comment>http://www.cppblog.com/lingling520/comments/137530.html</wfw:comment><comments>http://www.cppblog.com/lingling520/archive/2010/12/26/137530.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lingling520/comments/commentRss/137530.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lingling520/services/trackbacks/137530.html</trackback:ping><description><![CDATA[<div>
<p><font color=#0000ff size=4>设置视图背景颜色 <br>对于VC＋＋文档、视结构中的视图，从用户的角度来看，只是可以改变大小、位置的普通窗口，同其他基于Windows应用程序的窗口是一样的；从程序员的角度来看，视图并不是普通的窗口，而是从MFC库中CView类派生的类对象。像任何VC＋＋对象一样，视图对象的行为由类的成员函数（数据成员）决定，包括派生类中应用程序定义的函数和从基类继承来的函数。 </font></p>
<p><font color=#0000ff size=4>提出问题 <br>视图的背景一般来说是白色的，在缺省情况下，它和系统定义的颜色COLOR_WINDOW是一致的。设计者一般会希望自己的程序可以让用户轻松地改变窗口背景颜色，或是用漂亮的图片来充填背景。我们可以用Windows函数SetSysColors来重新指定COLOR_WINDOW所对应的实际颜色，来达到改变视图背景颜色的目的。但这样会同时改变其他应用程序的视图窗口背景，使得整个Windows系统的颜色设置产生混乱。另外，我们可能会用以下方法来设置视图的背景颜色，即在CView的OnDraw函数中添写如下一段程序代码： <br>void CTestView::OnDraw(CDC＊ pDC) <br>{ <br>CTestDoc＊ pDoc = GetDocument(); <br>ASSERT_VALID(pDoc); <br>CRect rectClient; <br>CBrush brushBkColor; <br>GetClientRect(rectClient); <br>brushBkColor.CreateSolidBrush(RGB(255,0,0)); <br>pDC－&gt;DPtoLP(rectClient); <br>pDC－&gt;FillRect(rectClient,＆brushBkColor); <br>&#8230; <br>} <br>这样可以达到改变当前应用程序的视图背景的目的，但同时也产生了一些不良影响，使得程序运行效果不尽如人意。 </font></p>
<p><font color=#0000ff size=4>分析问题 <br>我们知道，在VC＋＋的文档、视结构中，CView的OnDraw函数用于实现绝大部分图形绘制的工作。如果用户改变窗口尺寸，或者显示隐藏的区域，OnDraw函数都将被调用来重画窗口。并且，当程序文档中的数据发生改变时，一般必须通过调用视图的Invalidate（或InvalidateRect）成员函数来通知Windows所发生的改变，对Invalidate的调用也会触发对OnDraw函数的调用。正因为OnDraw函数被频繁调用，所以在其执行时，每次都刷新填充一次视图客户区域，便会使屏幕不稳定，产生闪烁现象。 <br>笔者通过对VC＋＋应用程序框架结构和Windows消息映射系统的仔细研究，找到另外一种改变视图背景的方法，其执行效果比上述两种方法都好。其实在程序调用OnDraw函数之前，会触发一个Windows消息：WM_ERASEBKGND，以擦除视图刷新区域。在缺省情况下，Windows系统使用视图窗口注册时窗口类中的成员hbrBackground所描述的画刷来擦除屏幕，这一般会将屏幕刷新成COLOR_WINDOW所对应的颜色。因此，在OnDraw函数中设置背景颜色的执行过程是这样的：先将屏幕刷新成COLOR_WINDOW所对应的颜色，接着又在OnDraw函数中填充其他颜色，这正是产生屏幕闪烁的根本原因。 </font></p>
<p><font color=#0000ff size=4>解决问题 <br>通过上述分析，我们应将视图背景颜色填充移到Windows消息：WM_ERASEBKGND所对应的消息映射函数中，而不是在OnDraw函数中。我们可以通过下列步骤实现这一过程：在文档类中增加一成员变量m_viewBkColor保存当前背景颜色，同时增加两个成员函数GetViewBkColor和SetViewBkColor对其进行读写操作。这样做的好处是可以对m_viewBkColor成员进行序列化，将其和文档联系在一起，打开某一文档时，其背景将和上一次程序操作该文档时的背景保持一致。在视图类中为视图的Windows消息WM_ERASEBKGND增加消息映射函数OnEraseBkgnd，代码如下： <br>BOOL CTestView::OnEraseBkgnd(CDC＊ pDC)&nbsp; <br>{ <br>CRect rect; <br>CBrush brush; <br>brush.CreateSolidBrush(GetDocument()－&gt;GetViewBkColor()); <br>pDC－&gt;GetClipBox(rect); <br>pDC－&gt;FillRect(rect,＆brush); <br>return true; <br>} <br>在该函数中不需要对客户区域矩形进行设备坐标到逻辑坐标的转换，并且Windows在调用该函数时会自动进行裁剪区域的计算，使得需要刷新的屏幕面积达到最小。这样我们可以在程序中通过设计下列菜单函数轻松地改变视图背景的颜色，而且运行效果相当令人满意。 <br>void CTestView::OnChangeViewBkcolor()&nbsp; <br>{ <br>CColorDialog cdlg; <br>if(cdlg.DoModal()==IDOK) <br>{ <br>GetDocument()－&gt;SetViewBkColor <br>(cdlg.GetColor()); <br>InvalidateRect(NULL); <br>} <br>} </font></p>
<p><font color=#0000ff size=4>改变对话框标题 </font></p>
<p><font color=#0000ff size=4>提出问题 <br>在VC＋＋程序设计过程中经常会遇到这样的情况：执行程序的多个地方需要调用同一个对话框，但在不同的情况下希望给对话框加上不同的标题。开始我们可能会用下面的一段程序以达到这一目的： <br>CTestDialog dlg; <br>dlg.SetWindowText(&#8220;标题－1"); <br>dlg.DoModal(); <br>利用上述办法，我们本希望在程序不同的地方，通过设置函数SetWindowText不同的参数，以达到使同一对话框具有不同标题的目的，但这样做是行不通的。 </font></p>
<p><font color=#0000ff size=4>分析问题 <br>利用这种方法，当执行该段程序时，在一个可以忽略的错误之后，对话框的标题不会发生任何改变。这是因为，VC＋＋程序设计中，大部分窗体是动态创建的。比如上述对话框，在对dlg.DoModal的调用之前，虽然已构造了对话框的VC＋＋对象，但窗体对象还没有被创建，显然对一个没有创建窗体对象的对话框设置标题是行不通的。另外，dlg.DoModal的调用结束时，对话框窗体对象将立即被释放，因此在该函数之后设置对话框标题也是不行的。 </font></p>
<p><font color=#0000ff size=4>解决问题 <br>通过对VC＋＋框架结构中函数的调用顺序的分析，我们发现在dlg.DoModal执行的开始时，程序会自动调用对话框的一系列初始化函数，其中包括对对话框成员函数OnInitDialog的调用，从这里入手，将找到改变对话框标题的办法。为此，首先为对话框引进一个类型为CString的公有成员变量m_strCaption,并将上述程序段改为： <br>CTestDialog dlg; <br>dlg.m_strCaption = &#8220;标题－1"; <br>dlg.DoModal(); <br>然后重载对话框的虚成员函数OnInitDialog如下： <br>BOOL CTestDialog::OnInitDialog()&nbsp; <br>{ <br>CDialog::OnInitDialog(); <br>SetWindowText(m_strCaption); <br>&#8230; <br>return TRUE; <br>} <br>通过这种办法，每次在打开对话框之前，只要将对话框公有成员变量m_strCaption设置为一个不同的值，就可使得对话框有不同的标题。</font></p>
</div>
<img src ="http://www.cppblog.com/lingling520/aggbug/137530.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lingling520/" target="_blank">胡志刚</a> 2010-12-26 23:18 <a href="http://www.cppblog.com/lingling520/archive/2010/12/26/137530.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sizeof()小结</title><link>http://www.cppblog.com/lingling520/archive/2010/12/06/135561.html</link><dc:creator>胡志刚</dc:creator><author>胡志刚</author><pubDate>Mon, 06 Dec 2010 02:55:00 GMT</pubDate><guid>http://www.cppblog.com/lingling520/archive/2010/12/06/135561.html</guid><wfw:comment>http://www.cppblog.com/lingling520/comments/135561.html</wfw:comment><comments>http://www.cppblog.com/lingling520/archive/2010/12/06/135561.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lingling520/comments/commentRss/135561.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lingling520/services/trackbacks/135561.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Pascal的一种内存容量度量函数c语言中判断数据类型长度符sizeof有三种语法形式，1）sizeof(object );//对象2）sizeof(type_name);//类型3）sizeof object://对象sizeof( 2 ); // 2的类型为int，所以等价于 sizeof( int );　　sizeof( 2 +&nbsp;3.14&nbsp;); // 3.14的类型为do...&nbsp;&nbsp;<a href='http://www.cppblog.com/lingling520/archive/2010/12/06/135561.html'>阅读全文</a><img src ="http://www.cppblog.com/lingling520/aggbug/135561.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lingling520/" target="_blank">胡志刚</a> 2010-12-06 10:55 <a href="http://www.cppblog.com/lingling520/archive/2010/12/06/135561.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于VC程序启动时函数运行简要说明</title><link>http://www.cppblog.com/lingling520/archive/2010/12/02/135266.html</link><dc:creator>胡志刚</dc:creator><author>胡志刚</author><pubDate>Thu, 02 Dec 2010 06:19:00 GMT</pubDate><guid>http://www.cppblog.com/lingling520/archive/2010/12/02/135266.html</guid><wfw:comment>http://www.cppblog.com/lingling520/comments/135266.html</wfw:comment><comments>http://www.cppblog.com/lingling520/archive/2010/12/02/135266.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lingling520/comments/commentRss/135266.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lingling520/services/trackbacks/135266.html</trackback:ping><description><![CDATA[应有和线程类<br>Windows以事件驱动方式工作，每个Windows应用程序都只是至少包含一个消息循环(::GetMessage,::PeekMessage)和一个消息泵(CWinThread::PumpMessage).消息队列建立在Windows系统提供的内存保留区中，通过消息泵来不断搜寻消息队列，将取得的消息分发给应用程序的各个部分进行处理，这个过程叫做消息循环。<br><br>文档视图类说明<br>1.CDocument类主要任务通常是对数据库进行管理和维护，数据将保存在文档类的成员变量中。CView类通过对这个些变量的访问来获取或送回数据，并能通过这种方式来更新并显示数据，从而把数据管理和显示方法分离开来。<br><br><br>程序运行路线及各个类的说明：<br><br>应用程序编写主线：WinMain()函数是入口点，在该函数里设计窗口类、注册窗口类、创建窗口、显示窗口、更新窗口，然后进入消息循环，将消息路由到窗口过程函数并进行相应的处理。对于MFC框架同样也是需要WinMain()函数，窗口过程函数等来创建一个基于窗口的应用程序。<br>AfxWinInit()函数，是第一个调用的函数，此函数源文件APPINIT.CPP中。<br><br>InitAppIication()函数，是CWinApp类的一个比较陈旧的成员函数，并且还是一个虚函数，现在对于一般的应用程序初始化都通过另一个成员函数InitInstance()来实现。<br><br>InitInstance()是一个虚函数。作为CWinApp类的成员函数，它是一个空函数，因此大多数应用程序都是重载这个函数。当应用程序被第一次调用时，WinMain()函数就会调用InitInstance()；来对应用程序进行初始化，之后每当应用程序启动一个新的实例时，InitInstance()函数数就会对该实例进行初始化。<br><br>
<img src ="http://www.cppblog.com/lingling520/aggbug/135266.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lingling520/" target="_blank">胡志刚</a> 2010-12-02 14:19 <a href="http://www.cppblog.com/lingling520/archive/2010/12/02/135266.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>