﻿<?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++博客-rebol-随笔分类-Final work LOG</title><link>http://www.cppblog.com/rebol/category/4287.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 28 May 2008 16:58:25 GMT</lastBuildDate><pubDate>Wed, 28 May 2008 16:58:25 GMT</pubDate><ttl>60</ttl><item><title>无闪烁刷屏技术的实现（文章来自：http://www.vchelp.net）</title><link>http://www.cppblog.com/rebol/archive/2007/05/30/25100.html</link><dc:creator>rebol</dc:creator><author>rebol</author><pubDate>Tue, 29 May 2007 18:13:00 GMT</pubDate><guid>http://www.cppblog.com/rebol/archive/2007/05/30/25100.html</guid><wfw:comment>http://www.cppblog.com/rebol/comments/25100.html</wfw:comment><comments>http://www.cppblog.com/rebol/archive/2007/05/30/25100.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/rebol/comments/commentRss/25100.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/rebol/services/trackbacks/25100.html</trackback:ping><description><![CDATA[<p></p> <p>这篇文章帮了我大忙，不过现在还是不知道消除MFC预设的背景色，前两种方法如何实现？我对MFC的框架还不是很了解  <p>&nbsp;  <p>无闪烁刷屏技术的实现(文章来自:http://www.vchelp.net)  <p>在实现绘图的过程中，显示的图形总是会闪烁，笔者曾经被这个问题折磨了好久，通过向高手请教，搜索资料，问题一基本解决，现将文档整理出来以供大家参考.<br>1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 显示的图形为什么会闪烁？<br>我们的绘图过程大多放在OnDraw或者OnPaint函数中，OnDraw在进行屏幕显示时是由OnPaint进行调用的。当窗口由于任何原因需要重绘时，总是先用背景色将显示区清除，然后才调用OnPaint，而背景色往往与绘图内容反差很大，这样在短时间内背景色与显示图形的交替出现，使得显示窗口看起来在闪。如果将背景刷设置成NULL，这样无论怎样重绘图形都不会闪了。当然，这样做会使得窗口的显示乱成一团，因为重绘时没有背景色对原来绘制的图形进行清除，而又叠加上了新的图形。有的人会说，闪烁是因为绘图的速度太慢或者显示的图形太复杂造成的，其实这样说并不对，绘图的显示速度对闪烁的影响不是根本性的。例如在OnDraw(CDC *pDC)中这样写：<br>pDC-&gt;MoveTo(0,0);<br>pDC-&gt;LineTo(100,100);<br>这个绘图过程应该是非常简单、非常快了吧，但是拉动窗口变化时还是会看见闪烁。其实从道理上讲，画图的过程越复杂越慢闪烁应该越少，因为绘图用的时间与用背景清除屏幕所花的时间的比例越大人对闪烁的感觉会越不明显。比如：清楚屏幕时间为1s绘图时间也是为1s，这样在10s内的连续重画中就要闪烁5次；如果清楚屏幕时间为1s不变，而绘图时间为9s，这样10s内的连续重画只会闪烁一次。这个也可以试验，在OnDraw(CDC *pDC)中这样写：<br>for(int i=0;i&lt;100000;i++)<br>{<br>pDC-&gt;MoveTo(0,i);<br>pDC-&gt;LineTo(1000,i);<br>}<br>呵呵，程序有点变态，但是能说明问题。<br>&nbsp;&nbsp;&nbsp;&nbsp; 说到这里可能又有人要说了，为什么一个简单图形看起来没有复杂图形那么闪呢？这是因为复杂图形占的面积大，重画时造成的反差比较大，所以感觉上要闪得厉害一些，但是闪烁频率要低。那为什么动画的重画频率高，而看起来却不闪？这里，我就要再次强调了，闪烁是什么？闪烁就是反差，反差越大，闪烁越厉害。因为动画的连续两个帧之间的差异很小所以看起来不闪。如果不信，可以在动画的每一帧中间加一张纯白的帧，不闪才怪呢。<br>2、如何避免闪烁<br>&nbsp;&nbsp;&nbsp;&nbsp; 在知道图形显示闪烁的原因之后，对症下药就好办了。首先当然是去掉MFC提供的背景绘制过程了。实现的方法很多，<br>* 可以在窗口形成时给窗口的注册类的背景刷付NULL<br>* 也可以在形成以后修改背景<br>&nbsp;&nbsp;&nbsp;&nbsp; static CBrush brush(RGB(255,0,0));<br>&nbsp;&nbsp;&nbsp;&nbsp; SetClassLong(this-&gt;m_hWnd,GCL_HBRBACKGROUND,(LONG)(HBRUSH)brush);<br>* 要简单也可以重载OnEraseBkgnd(CDC* pDC)直接返回TRUE<br>&nbsp;&nbsp;&nbsp;&nbsp; 这样背景没有了，结果图形显示的确不闪了，但是显示也象前面所说的一样，变得一团乱。怎么办？这就要用到双缓存的方法了。双缓冲就是除了在屏幕上有图形进行显示以外，在内存中也有图形在绘制。我们可以把要显示的图形先在内存中绘制好，然后再一次性的将内存中的图形按照一个点一个点地覆盖到屏幕上去（这个过程非常快，因为是非常规整的内存拷贝）。这样在内存中绘图时，随便用什么反差大的背景色进行清除都不会闪，因为看不见。当贴到屏幕上时，因为内存中最终的图形与屏幕显示图形差别很小（如果没有运动，当然就没有差别），这样看起来就不会闪。<br>3、如何实现双缓冲<br>&nbsp;&nbsp;&nbsp;&nbsp; 首先给出实现的程序，然后再解释，同样是在OnDraw(CDC *pDC)中：<br>CDC MemDC; //首先定义一个显示设备对象<br>CBitmap MemBitmap;//定义一个位图对象<br>//随后建立与屏幕显示兼容的内存显示设备<br>MemDC.CreateCompatibleDC(NULL);<br>//这时还不能绘图，因为没有地方画 ^_^<br>//下面建立一个与屏幕显示兼容的位图，至于位图的大小嘛，可以用窗口的大小<br>MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight);<br>//将位图选入到内存显示设备中<br>//只有选入了位图的内存显示设备才有地方绘图，画到指定的位图上<br>CBitmap *pOldBit=MemDC.SelectObject(&amp;MemBitmap);<br>//先用背景色将位图清除干净，这里我用的是白色作为背景<br>//你也可以用自己应该用的颜色<br>MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255));<br>//绘图<br>MemDC.MoveTo(……);<br>MemDC.LineTo(……);<br>//将内存中的图拷贝到屏幕上进行显示<br>pDC-&gt;BitBlt(0,0,nWidth,nHeight,&amp;MemDC,0,0,SRCCOPY);<br>//绘图完成后的清理<br>MemBitmap.DeleteObject();<br>MemDC.DeleteDC();<br>上面的注释应该很详尽了，废话就不多说了。<br>4、如何提高绘图的效率<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实际上，在OnDraw(CDC *pDC)中绘制的图并不是所有都显示了的，例如：你在OnDraw中画了两个矩形，在一次重绘中虽然两个矩形的绘制函数都有执行，但是很有可能只有一个显示了，这是因为MFC本身为了提高重绘的效率设置了裁剪区。裁剪区的作用就是：只有在这个区内的绘图过程才会真正有效，在区外的是无效的，即使在区外执行了绘图函数也是不会显示的。因为多数情况下窗口重绘的产生大多是因为窗口部分被遮挡或者窗口有滚动发生，改变的区域并不是整个图形而只有一小部分，这一部分需要改变的就是pDC中的裁剪区了。因为显示（往内存或者显存都叫显示）比绘图过程的计算要费时得多，有了裁剪区后显示的就只是应该显示的部分，大大提高了显示效率。但是这个裁剪区是MFC设置的，它已经为我们提高了显示效率，在进行复杂图形的绘制时如何进一步提高效率呢？那就只有去掉在裁剪区外的绘图过程了。可以先用pDC-&gt;GetClipBox()得到裁剪区，然后在绘图时判断你的图形是否在这个区内，如果在就画，不在就不画。<br>如果你的绘图过程不复杂，这样做可能对你的绘图效率不会有提高。</p><img src ="http://www.cppblog.com/rebol/aggbug/25100.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/rebol/" target="_blank">rebol</a> 2007-05-30 02:13 <a href="http://www.cppblog.com/rebol/archive/2007/05/30/25100.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>程序的雏形写好了</title><link>http://www.cppblog.com/rebol/archive/2007/05/30/25099.html</link><dc:creator>rebol</dc:creator><author>rebol</author><pubDate>Tue, 29 May 2007 18:01:00 GMT</pubDate><guid>http://www.cppblog.com/rebol/archive/2007/05/30/25099.html</guid><wfw:comment>http://www.cppblog.com/rebol/comments/25099.html</wfw:comment><comments>http://www.cppblog.com/rebol/archive/2007/05/30/25099.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/rebol/comments/commentRss/25099.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/rebol/services/trackbacks/25099.html</trackback:ping><description><![CDATA[<p>终于完成了A阶段，下面可以进入B阶段了，主要集中在程序的UI上，另外考虑如何提升速度。</p> <p>我的临时文档，看起来好乱，程序里的标识符也没完全按文档里的来，真是乱套了，明天好好修改修改。</p> <p>&nbsp;</p> <p>&nbsp;</p> <p><a href="http://www.cppblog.com/images/cppblog_com/rebol/WindowsLiveWriter/ef59db1c8210_19BB/B27A7E048ED84794ACCF5F6A7AC516997.jpg" atomicselection="true"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="680" src="http://www.cppblog.com/images/cppblog_com/rebol/WindowsLiveWriter/ef59db1c8210_19BB/B27A7E048ED84794ACCF5F6A7AC51699_thu.jpg" width="708" border="0"></a>  <p>放入MyDefine.h,MyDefine.cpp文件  <p><b>1． </b><b>河的边线</b><b></b>  <p>Doc里放入：  <p>//num of ctrl pnt,nodal pnt,display style,  <p>//wave speed wave distance and wave num  <p>int ctrlNum,ndlNum,style,wSpeed,wDistance,wNum;  <p>//the pnt array represent ctrl pnts and nodal pnts.  <p>CArray &lt;CPoint,CPoint&amp;&gt; c_PntsL,c_PntR,n_PntsL,n_PntsR;  <p><b>视图类和文档类都要引用</b><b>MyDefine.h</b><b>，用＃</b><b>ifndef</b><b>吧</b><b></b>  <p>以下内容放在视图类里的OnCreate函数中，先为<b>CView</b><b>的派生类</b>声明一个图元文件的数据成员HMETAFILE m_hMetaFile;  <p>CArray &lt;CPoint,CPoint&amp;&gt; initL,initR;  <p>//预先输入的控制点，自定义  <p>Int const Max=60;  <p>//CArray &lt;CPointPartner,CPointPartner&amp;&gt; init_CPntPtr,final_CPntPtr;  <p>//CPointPartner作为TYPE有问题，还是用数组  <p>//改为:  <p>CPointPartner init_CPntPtr[Max],final_CPntPtr[Max];  <p><b>//</b><b>最后的点对数组final_CPntPtr</b><b>给CCurve</b><b>类用</b>  <p>While(i&lt;Num)  <p>{  <p>CPointPartner temp_CPntPtr (initL[i],initR[i]);  <p>init_CPntPtr.Add(temp_CPntPtr);  <p>i++;  <p>}  <p>//鼠标点击或预先指定控制点，即一些点对  <p>//以及处理后得到的点对  <p>CSpline spL (initL);  <p>CSpline spR (initR);  <p>//两边的样条曲线  <p>CArray&lt;CPoint,CPoint&amp;&gt; finalL,finalR;  <p>//处理后得到的样条曲线上的点  <p>spL.GetPoints(finalL);  <p>spR.GetPoints(finalR);  <p>Count=finalL.GetSize();  <p>For(int i=0;i&lt;count;i++)  <p>{  <p>CPointPartner Temp_finalP (finalL[i],finalR[i])  <p>Final_CPntPtr[i]=temp_finalP;//重载＝运算符  <p>}  <p>//将样条对象spL，spR里的点放入finalL和finalR,之后又放入点对数组final_CPntPtr;  <p>//共count个点对  <p>CMetaFileDC metaFileDC;  <p>metaFileDC.Create();  <p><b>这里画出边线（通过finalL</b><b>和finalR</b><b>）</b>  <p>m_hMetaFile=metaFileDC.Close();  <p>5．23晚19：30以上程序的调试已完成（未加鼠标控制）  <p><b>2． </b><b>一道道波纹（</b><b>CCurve</b><b>类）</b><b></b>  <p>在视图类中声明数据：CArray&lt;Points,Points&amp;&gt; mPntsCurve;  <p>在OnDraw里  <p>先确定水波位置：  <p>WavePL[i]和WavePR[i]  <p>For（int i=0,i&lt;WaveN;i++）  <p>{  <p>CCurve tempCurve (final_CPntPtr[i]);  <p>tempCurve.ComputePnts(mPntsCurve);  <p>连这些点成线  <p>}  <p>详细设计：  <p>Doc里定义两个点，  <p>View里定义一个函数BOOL ComputePnts(CArray&lt;CPoint,CPoint&amp;&gt;&amp; m_Pnts,CPoint m_LPnt,CPoint m_RPnt)  <p>OnDraw里给两个点赋值，调用ComputePnts，再绘图  <p><b>与</b><b>MFC</b><b>的联系</b><b></b>  <p><b>//</b><b>用图元文件保存边线，中间的curve</b><b>即时画出来</b>  <p>//要描绘的点，每两点画条线连接LineTO  <p><b>或者将点集的计算都放在文档类中，给文档类新建两个函数</b>  <p><b></b> <p><b>数据的放置位置还得琢磨琢磨</b>  <p><b></b> <p><b>5</b><b>．21 </b><b>晚12</b><b>：00</b><b>此文档完成</b>  <p><b></b> <p><b>Spline</b><b>的计算在CDoc</b><b>里，Curve</b><b>的计算在CView</b><b>里</b>  <p><b></b> <p><b>5. 29 </b><b>晚1</b><b>：47 </b><b>添加（明天再修改）</b></p> <p>&nbsp;</p> <p><b>5.30</b> <p><b>Q: Spline</b><b>里的temp</b><b>值使得数组越界问题</b> <p><b>A: </b><b>精度造成的，两个float</b><b>型变量t</b><b>和T1[j1+1]</b><b>都为0.90000,</b><b>但t&gt;T1[j1+1]</b><b>为true,</b> <p><b></b> <p><b>Tips</b><b>：</b> <p><b>1． </b><b>查找类型强制转换以及精度丢失的知识</b> <p><b>2． </b><b>看林锐的《高质量C++</b><b>编程》，注意这些细节。</b> <p><b></b> <p><b>5.31</b> <p><b>已完成：位图作为背景。</b> <p>&nbsp; <p><b></b> <p><b>Q:</b><b>鼠标控制的问题</b></p><img src ="http://www.cppblog.com/rebol/aggbug/25099.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/rebol/" target="_blank">rebol</a> 2007-05-30 02:01 <a href="http://www.cppblog.com/rebol/archive/2007/05/30/25099.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows编程几个知识点</title><link>http://www.cppblog.com/rebol/archive/2007/05/16/24248.html</link><dc:creator>rebol</dc:creator><author>rebol</author><pubDate>Wed, 16 May 2007 14:48:00 GMT</pubDate><guid>http://www.cppblog.com/rebol/archive/2007/05/16/24248.html</guid><wfw:comment>http://www.cppblog.com/rebol/comments/24248.html</wfw:comment><comments>http://www.cppblog.com/rebol/archive/2007/05/16/24248.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/rebol/comments/commentRss/24248.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/rebol/services/trackbacks/24248.html</trackback:ping><description><![CDATA[<p>1、大致说来windows编程有两种方法：<br>a.windwos c方式(SDK),SDK编程就是直接调用windows的API进行编程;<br>b.c++方式:即对SDK函数进行包装，如VC的MFC,BCB的OWL等。MFC把这些API封闭起来，共有一百多个类组成.</p>
<p>2、API,全称application program interface,意思是应用程序编程接口(说起API并不仅仅指windows而言， windows支持的API叫winapi)。winapi就是应用程序和windows之间通讯的一个编程界面。windows提供了上千个API函数，以方便程序员来编写应用程序。</p>
<p>3、WinSDK程序设计就是API方式的windows程序设计。SDK,全称Software Developers Kit,意思是软件开发工具箱。</p>
<p>4、MFC,全称Microsoft Foundation Classes,伪软把WinAPI进行封装的类库。它是一个类的集合，通过覆盖WinAPI，为编程提供了一个面向对象的界面。它使windows程序员能够利用C++面象对象的特性进行编程，类似BCB的OWL，Delphi的VCL组件。它把那些进行SDK编程时最繁琐的部分提供给程序员，使之专注于功能的实现。你不妨把它想象成类似TC提供的函数库吧。</p>
<p>5、dos下的C编程的main()一样，windows下的入口是WinMain()函数。</p>
<p>6、WinMain()所起的作用：初始化，展示，销毁应用程序等。<br>第一个参数：应用程序的当前实例句柄。<br>第二个参数：应用程序的前一个实例句柄，别管它，对于Win32位而言，它一般是NULL.<br>第三个参数：指向任何传给程序的命令行参数。PSTR代表"指向字符串的指针"。<br>第四个参数：它告诉应用程序如何初始化窗口，如最大化，最小化等状态。</p>
<p>7、句柄(handle)：<br>在标准C库中句柄用来对文件输入输出。<br>在Windows环境中，句柄是用来标识项目的，这些项目包括：<br>*.模块(module)<br>*.任务(task)<br>*.实例(instance)<br>*.文件(file)<br>*.内存块(block of memory)<br>*.菜单(menu)<br>*.控制(control)<br>*.字体(font)<br>*.资源(resource),包括图标(icon)，光标(cursor)，字符串(string)等<br>*.GDI对象(GDI object),包括位图(bitmap),画刷(brush),元文件(metafile),调色板(palette),画 笔(pen),区域(region),以及设备描述表(device context)。<br>WINDOWS程序中并不是用物理地址来标识一个内存块，文件，任务或动态装入模块的，相反的，WINDOWS API给这些项目分配确定的句柄，并将句柄返回给应用程序，然后通过句柄来进行操作。</p>
<p>窗口句柄：<br>系统通过窗口句柄来在整个系统中唯一标识一个窗口，发送一个消息时必须指定一个窗口句柄表明该消息由那个窗口接收。而每个窗口都会有自己的窗口过程，所以用户的输入就会被正确的处理。</p>
<p>8、所有的命名采用了匈牙利表示法。如消息的前缀使用msg.句柄使用h.函数使用fn等。</p>
<p>9、MainFrm.cpp、MainFrm.h：<br>这两个文件将从CFrameWnd(SDI应用程序)或CMDIFrameWnd(MDI应用程序)派生CMainFrame类。如果在AppWizard的Application Options页（6步中的第4步）中选择了对应的可选项的话，CMainFrame类将处理工具条按钮和状态条的创建。MAINFRM.CPP文件还含有MFC应用程序提供的默认工具条按钮的对象ID——叫做buttons数组。</p>
<p>10、DOS程序主要使用顺序的，过程驱动的程序设计方法。顺序的，过程驱动的程序有一个明显的开始，明显的过程及一个明显的结束，因此程序能直接控制程序事件或过程的顺序。虽然在顺序的过程驱动的程序中也有很多处理异常的方法，但这样的异常处理也仍然是顺序的，过程驱动的结构。</p>
<p>11、Windows的驱动方式是事件驱动，就是不由事件的顺序来控制，而是由事件的发生来控制，所有的事件是无序的。做为一个程序员，在你编写程序时，你并不知道用户先按哪个按纽，也不知道程序先触发哪个消息。你的任务就是对正在开发的应用程序要发出或要接收的消息进行排序和管理。事件驱动程序设计是密切围绕消息的产生与处理而展开的，一条消息是关于发生的事件的消息。</p>
<p>12、Windows程序则至少两个主程序，<br>一个是WinMain(),<br>int WINAPI WinMain( <br>　　　　　　　　　　HINSTANCE hInstance, 　　 // handle to current instance<br>　　　　　　　　　　HINSTANCE hPrevInstance, 　// handle to previous instance <br>　　　　　　　　　　LPSTR lpCmdLine, 　　　　 // command line <br>　　　　　　　　　　int nCmdShow 　　　　 // show state <br>　　　　　　　　　);<br>另一个是窗口过程函数WndProc,它的函数原型为:<br>long FAR PASCAL WndProc(HWND hWnd,WORD message,WORD wParam,LONG lParam);</p>
<p>13、窗口函数与回调函数:<br>在Windows中，应用程序通过要求Windows完成指定操作，而承担这项通信任务的API函数就是Windows的相应窗口函数WndProc。应用程序不直接调用任何窗口函数，而是等待Windows调用窗口函数，请求完成任务或返回信息。为保证Windows调用这个窗口函数，这个函数必须先向Windows登记，然后在Windows实施相应操作时回调，所以窗口函数又称为回调函数。WndProc是一个主回调函数，Windows至少有一个回调函数。典型的回调函数有窗口过程、对话框过程和钩子函数。实际上，也许有不止一个的窗口过程。例如，每一个不同的窗口类都有一个与之相对应的窗口过程。</p>
<p>15、实例:在Windows中，能多次同时运行同一个应用程序，即运行多个副本，每个副本叫做一个&#8220;实例&#8221;。</p>
<p>16、C runtime函数库：</p>
<p>就跟它的名字一样,运行类型信息<br>主要有COject类和CRuntimeClass类来实现,用来存贮COject类和派生类的运行类型信息,<br>1.类的基本情况:如类的名字,存贮空间大小,用于运行类的类型确定.<br>2.ms在C++的标准上,添加动态创建的类对象功能,也就是时时提到的动态创建<br>3.串行化处理.<br>The OS does not know main(), so C-runtime is first called and transfer control to main<br>it also provide library for common usage, such as math functions</p>
<p>17、WinMain()函数的调用约定是PASCAL。</p>
<p>在这里PASCAL是一个调用约定，由于这种方式最早由PASCAL采用，所以这么叫。<br>在MSDN中的C++ Language Reference中，Calling Conventions这一章都是讲调用约定的。</p>
<p>约定：微软重定义了许多约定类型，为的是可以让代码更容易跨平台或者跨编译器。<br>其实，调用约定要解决两个问题，都是针对堆栈操作：<br>1。参数传递的顺序（本质是压栈的顺序）<br>2。谁负责平栈（调用者还是调用对象）<br>一个函数的声明、定义和实现中的调用方式一般都一致。</p>
<p>WINAPI标识符的定义是：#define WINAPI __stdcall, __stdcall指Window调用函数的一种方式，也就是如何在堆中存取函数参数的方式。许多Windows Api函数调用声明为__stdcall方式。</p>
<p>18、用位的&#8220;或&#8221;操作（操作符&#8220;|&#8221;）把若干个常数组合起来控制消息窗口显示的按钮和图标等。</p>
<p>19、在Windows应用程序中，每一个窗口都必须从属于一个窗口类，窗口类定义了窗口所具有的属性，如它的样式、图标、鼠标指针、菜单名称及窗口过程名等。<br>窗口种类是定义窗口属性的模板,这些属性包括窗口式样,鼠标形状,菜单等等,窗口种类也指定处理该类中所有窗口消息的窗口函数.只有先建立窗口种类,才能根据窗口种类来创建Windows应用程序的一个或多个窗口.创建窗口时,还可以指定窗口独有的附加特性.窗口种类简称窗口类,窗口类不能重名.在建立窗口类后,必须向Windows登记.建立窗口类就是用WNDCLASS结构定义一个结构变量.</p>
<p>20、Visual C++提供Alt+F8功能键，进行文件规格化，根据周围的代码行，正确缩进选定的代码行。常使用该按键可使得文件保持规格化(注，Alt+F8功能键对连续两个CASE语句则会发生处理错误，不能规格化)。 </p>
<p>21、消息：<br>一个消息由一个消息名称(UINT)，和两个参数(WPARAM，LPARAM)。当用户进行了输入或是窗口的状态发生改变时系统都会发送消息到某一个窗口。</p>
<p>22、一个典型的应用程序应该活动在称为&#8220;框架窗口&#8221;中。一个框架窗口是一个全功能的主窗口，用户可以改变尺寸、最小化、最大化等。</p>
<p>23、消息机制：<br>系统将会维护一个或多个消息队列，所有产生的消息都回被放入或是插入队列中。系统会在队列中取出每一条消息，根据消息的接收句柄而将该消息发送给拥有该窗口的程序的消息循环。每一个运行的程序都有自己的消息循环，在循环中得到属于自己的消息并根据接收窗口的句柄调用相应的窗口过程。而在没有消息时消息循环就将控制权交给系统所以Windows可以同时进行多个任务。</p>
<p>24、预编译头文件:<br>VC++程序一般包含的头文件都比较复杂，如果每次都逐行分析可能会花很多时间，所以VC++默认设置是第一次编译时分析所有头文件，生成.pch文件，这个文件很大，但以后每次编译时就可以节省很多时间。如果删除了这个文件，下次编译时VC++会自动生成它。 <br>StdAfx.h是每个MFC程序的类中必须包括的文件，它一般由AppWizard自动生成，包括编译MFC类所必须的定义。</p>
<p>25、Windows支持两种类型的对话框：模式和无模式对话框。<br>模式对话框一旦出现在屏幕上，只有当它退出时，屏幕上该应用程序的其余部分才能响应。<br>无模式对话框出现在屏幕上时，程序的其余部分也可以作出响应，它就象浮动在上面一样。</p>
<p>26、单文档界面(SDI)，只有一个框架窗口。<br>MDI 系统允许用户在同一应用程序中同时可以查看多个文档。</p>
<img src ="http://www.cppblog.com/rebol/aggbug/24248.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/rebol/" target="_blank">rebol</a> 2007-05-16 22:48 <a href="http://www.cppblog.com/rebol/archive/2007/05/16/24248.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows SDK编程(窗口示例程序)</title><link>http://www.cppblog.com/rebol/archive/2007/05/16/24247.html</link><dc:creator>rebol</dc:creator><author>rebol</author><pubDate>Wed, 16 May 2007 14:46:00 GMT</pubDate><guid>http://www.cppblog.com/rebol/archive/2007/05/16/24247.html</guid><wfw:comment>http://www.cppblog.com/rebol/comments/24247.html</wfw:comment><comments>http://www.cppblog.com/rebol/archive/2007/05/16/24247.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/rebol/comments/commentRss/24247.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/rebol/services/trackbacks/24247.html</trackback:ping><description><![CDATA[<p>/*****************************************************<br>&nbsp;Windows SDK编程之一&nbsp; 窗口示例程序<br>******************************************************/</p>
<p>/*Win32应用程序框架主要由"初始化窗口类"，"窗口注册类"，"窗口的创建"以"窗口消息函数"等组成*/<br>#include "stdafx.h"</p>
<p><br>LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);&nbsp; //窗口函数说明</p>
<p>/*<br>&nbsp; WinMain函数是所有windows应用程序的入口，类似于C语言中的Main函数，其功能是完成一系列的定义和初始化工作，并产生消息循环。消息循环是整个程序运行的核心。WinMain函数实现以下功能。<br>&nbsp; 1. 注册窗口类，建立窗口及执行其它必要的初始化工作；<br>&nbsp; 2. 进入消息循环，根据从应用程序消息队列接受的消息，调用相应的处理过程<br>&nbsp; 3. 当消息循环检索到WM_QUIT消息时终止程序运行。</p>
<p>&nbsp; WinMain函数有三个基本的组成部份：函数说明、初始化和消息循环。</p>
<p>&nbsp;WinMain函数的说明如下：<br>&nbsp;int WINAPI WinMain(&nbsp; //WinMain函数说明<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HINSTANCE hInstance, //程序当前实例句柄&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HINSTANCE hPrevInstance,&nbsp; //应用程序其它实例句柄<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPSTR&nbsp;&nbsp;&nbsp;&nbsp; lpCmdLine, //指向程序命令行参数的指针<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; nCmdShow&nbsp; //应用程序开始执行时窗口显示方式的整数值标识<br>)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 由于Window操作系统是多任务的操作系统，能进行多任务的管理，因此，windows应用程序可能被并行的多次执行，因而可能出现同一个程序的多个窗口同时存在的情况，Windows系统将应用程序每一次执行称为该应用程序的一个实例（Instance），并用一个实例句柄唯一的标识它。</p>
<p>*/<br>int APIENTRY WinMain(HINSTANCE hInstance,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //WinMain函数说明 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HINSTANCE hPrevInstance,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPSTR&nbsp;&nbsp;&nbsp;&nbsp; lpCmdLine,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nCmdShow)<br>{<br>&nbsp;&nbsp;// TODO: Place code here.<br>&nbsp;/*<br>&nbsp;建议采用Pascal的变量定义风格，即在程序（函数）开始处定义所有变量<br>&nbsp;虽然C＋＋的变量定义比较灵活，本程序为了使程序易于理解,未采用这种方法<br>&nbsp;*/<br>&nbsp; &nbsp;<br>&nbsp;char lpszClassName[]="窗口";&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //窗口类名<br>&nbsp;char lpszTitle[]="Windows SDK编程之一&nbsp; 窗口示例程序";&nbsp;&nbsp; //窗口标题名</p>
<p>&nbsp;//---------------窗口类定义-------------------------------------<br>&nbsp;/*<br>&nbsp;窗口类的定义<br>&nbsp;&nbsp;&nbsp; 在Windows应用程序中，窗口害定义了窗口的形式与功能。窗口类定义通过给窗口类数据结构WNDCLASS赋值完成，该数据结构中包括窗口类的各种属性，在窗口类定义过程中常用到以下函数：<br>&nbsp;*/<br>&nbsp;WNDCLASS wndclass;<br>&nbsp;wndclass.style=0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //窗口类型为缺省类型<br>&nbsp;wndclass.lpfnWndProc=WndProc;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //窗口处理函数为WndProc<br>&nbsp;wndclass.cbClsExtra=0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //窗口类无扩展<br>&nbsp;wndclass.cbWndExtra=0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //窗口实例无扩展<br>&nbsp;wndclass.hInstance=hInstance;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //当前实例句柄<br>&nbsp;<br>&nbsp;wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //使用缺省图标<br>&nbsp;/*<br>&nbsp; LoadIcon（）：在应用程序中加载一个窗口图标<br>&nbsp;&nbsp;&nbsp;&nbsp; LoadIcon（）函数原型为：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HICON LoadIcon（<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HINSTANCE hInstance,//图标资源所在的模块句柄，为NULL则使用系统预定义图标<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPCTSTR lpIconName //图标资源名或系统预定义图标标识名<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br>&nbsp;*/</p>
<p><br>&nbsp;wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //窗口采用箭头光标<br>&nbsp;&nbsp;&nbsp; /*<br>&nbsp;LoadCursor():在应用程序中加载一个窗口光标<br>&nbsp;&nbsp;&nbsp; LoadCursor()函数原型为：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HCURSOR LoadCursor（<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HINSTANCE hInstance,//光标资源所在的模块句柄，为NULL则使用系统预定义光标<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPCTSTR lpCursorName //光标资源名或系统预定义光标标识名<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br>&nbsp;*/</p>
<p>&nbsp;wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);&nbsp;&nbsp;&nbsp; //窗口背景为白色<br>&nbsp;/*<br>&nbsp; GetStockObject（）：获取已经定义的画笔、画刷、字体等对象的句柄<br>&nbsp;&nbsp;&nbsp;&nbsp; GetStockObject（）函数原型为：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HGDIOBJ GetStockObject（int fnObject）; //fnObject为对象的标识名</p>
<p>&nbsp;*/</p>
<p>&nbsp;wndclass.lpszMenuName=NULL;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //窗口中无菜单<br>&nbsp;wndclass.lpszClassName=lpszClassName;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //窗口类名为'窗口实例'</p>
<p>&nbsp;//------------------以下是进行窗口类的注册---------------------------<br>&nbsp;<br>&nbsp;/*<br>&nbsp;&nbsp;&nbsp; 注册窗口类<br>&nbsp;&nbsp;&nbsp; Windows系统本身提供部份预定义的窗口类，程序员也可以自定义窗口类，窗口类必须先注册后使用。窗口类的注册由注册函数RegisterClass（）实现。其形式为:<br>&nbsp;&nbsp;&nbsp; RegisterClass(&amp;wndclass) <br>&nbsp;&nbsp; &amp;wndclass为窗口类结构<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RegisterClass函数的返回值为布尔值,注册成功则返回真<br>&nbsp;*/<br>&nbsp;if (! RegisterClass(&amp;wndclass))&nbsp;&nbsp;&nbsp;&nbsp; //注册窗口，若失败，则发出声音<br>&nbsp;{ MessageBeep(0);<br>&nbsp;&nbsp; return FALSE;<br>&nbsp;}<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;/*<br>&nbsp;创建窗口实例<br>&nbsp;创建一个窗口类的实例由函数CreateWindow()实现,该函数的原型为:<br>&nbsp;&nbsp;&nbsp; HWND&nbsp; CreateWindow(LPCTSTR lpszClassName,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //创建窗口，窗口类名<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPCTSTR lpszTitle,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //窗口实例的标题名<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwStyle,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //窗口的风格<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int x,&nbsp;&nbsp; //窗口左上角坐标<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int y,&nbsp;&nbsp; //窗口左上角坐标<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nWidth,&nbsp;&nbsp; //窗口的宽度<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nHeight,&nbsp;&nbsp; //窗口的高度<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HWND hwndParent,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //此窗口父窗口<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HWENU hMenu,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //此窗口主菜单<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HINSTANCE hInstance, //应用程序当前句柄<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPVOID lpParam);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //指向一个传递给窗口的参数值的指针<br>&nbsp;*/<br>&nbsp;<br>&nbsp;//创建窗口操作<br>&nbsp;HWND hwnd; //窗口结构<br>&nbsp;&nbsp;&nbsp; hwnd=CreateWindow(lpszClassName,&nbsp;&nbsp; //创建窗口，窗口类名<br>&nbsp;&nbsp;lpszTitle,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //窗口实例的标题名<br>&nbsp;&nbsp;WS_OVERLAPPEDWINDOW,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //窗口的风格<br>&nbsp;&nbsp;CW_USEDEFAULT,CW_USEDEFAULT,&nbsp;&nbsp; //窗口左上角坐标为缺省值<br>&nbsp;&nbsp;CW_USEDEFAULT,CW_USEDEFAULT,&nbsp;&nbsp; //窗口的高度和宽度为缺省值<br>&nbsp;&nbsp;NULL,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //此窗口无父窗口<br>&nbsp;&nbsp;NULL,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //此窗口无主菜单<br>&nbsp;&nbsp;hInstance,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //应用程序当前句柄<br>&nbsp;&nbsp;NULL);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //不使用该值</p>
<p>&nbsp;ShowWindow(hwnd,nCmdShow);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //显示窗口</p>
<p>&nbsp;UpdateWindow(hwnd);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //绘制用户区<br>&nbsp;</p>
<p>&nbsp;&nbsp; &nbsp;/*<br>&nbsp; 消息循环<br>&nbsp; windows应用程序的运行以消息为核心。windows将产生的消息放入应用程序的消息队列中而应用程序WinMain函数的消息循环提取消息队列中的消息，并将其传递给窗口函数为相应处理过程处理。<br>&nbsp;&nbsp; &nbsp;MSG msg; //消息结构</p>
<p>&nbsp;while( GetMessage(&amp;msg,NULL,0,0))&nbsp; //消息循环<br>&nbsp;{ TranslateMessage(&amp;msg);<br>&nbsp;&nbsp; DispatchMessage(&amp;msg);<br>&nbsp;}<br>&nbsp;*/</p>
<p>&nbsp;MSG msg; //消息结构<br>&nbsp; /*GetMessage()作用：从消息队列中读取一条消息，并将消息放在一个MSG结构中：<br>&nbsp;&nbsp; BOOL GetMessage(&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPMSG lpMsg,&nbsp; //指向MSG结构的指针<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HWND hWnd,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UINT wMsgFilterMin, //用于消息过滤的最小信息号值<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UINT wMsgFilterMax //用于消息过滤的最大信息号值 如最小值和最大值均为0， 则不过滤消息<br>&nbsp;&nbsp; );<br>&nbsp; 当GetMessage返回0时，即检索到WM_QUIT消息，程序将结束循环并退出</p>
<p>&nbsp;BOOL TranslateMessage(&nbsp; const MSG *lpMsg );&nbsp; 负责把消息的虚拟键值转换为字符信息<br>&nbsp;LRESULT DispatchMessage( const MSG *lpmsg&nbsp; ); 将参数lpmsg指向的消息传递给指定的窗口</p>
<p>&nbsp; */<br>&nbsp;while( GetMessage(&amp;msg,NULL,0,0))&nbsp; //消息循环<br>&nbsp;{ TranslateMessage(&amp;msg);<br>&nbsp;&nbsp; DispatchMessage(&amp;msg);<br>&nbsp;}</p>
<p>&nbsp;return msg.wParam;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //程序终止时，将信息返回操作系统<br>}</p>
<p><br>//-----------------------------窗口函数---------------------------------------<br>/*<br>窗口消息处理函数定义了应用程序对接收到的不同消息的响应，它包含了应用程序对各种可用接收到的消息的处理过程，通常　，窗口函数由一个或多个switch...case语句组成，每一条case语句<br>对应一种消息，当应用程序接收到一个消息时，相应的case语句被　激活并执行相应的响应程序模块。<br>窗口函数的一般形式如下：<br>&nbsp;LRESULT CALLBACK WindowProc(&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HWND hwnd,<br>&nbsp;&nbsp;&nbsp; UINT uMsg,<br>&nbsp;&nbsp;&nbsp; WPARAM wParam,<br>&nbsp;&nbsp;&nbsp; LPARAM lParam<br>);<br>Parameters</p>
<p>hwnd　：[in] Handle to the window. <br>uMsg　：[in] Specifies the message. <br>wParam：[in] Specifies additional message information. The contents of this parameter depend on the value of the uMsg parameter. <br>lParam：[in] Specifies additional message information. The contents of this parameter depend on the value of the uMsg parameter. <br>Return Value　<br>The return value is the result of the message processing and depends on the message sent.</p>
<p>LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)<br>{<br>&nbsp; switch (message)<br>&nbsp; {<br>&nbsp; case ...<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ....<br>&nbsp;&nbsp; break;<br>&nbsp;&nbsp; .........<br>&nbsp; case WM_DESTROY: <br>&nbsp;&nbsp;&nbsp;&nbsp; //void PostQuitMessage(int nExitCode)函数的作用是向程序发送WM＿QUIT消息，nExitCode应用程序退出代码<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PostQuitMessage(0); //调用该函数发出WM_QUIT消息<br>&nbsp; default: //缺省消息处理函数,以保证所的发往窗口的消息都能被处理<br>&nbsp;&nbsp; return DefWindowProc(hwnd,message,wParam,lParam);<br>&nbsp; }</p>
<p>&nbsp; return (0);<br>}</p>
<p>*/<br>LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)<br>{<br>&nbsp; switch (message)<br>&nbsp; {<br>&nbsp; case WM_DESTROY:<br>&nbsp;&nbsp;&nbsp; PostQuitMessage(0); //调用该函数发出WM_QUIT消息<br>&nbsp; default: //缺省消息处理函数<br>&nbsp;&nbsp; return DefWindowProc(hwnd,message,wParam,lParam);<br>&nbsp; }</p>
<p>&nbsp; return (0);<br>}<br>/*<br>注：<br>&nbsp; 事件驱动的特点：<br>&nbsp; Windows程序设计围绕着事件或消息的产生驱动产生运行消息处理函数。Windows程序的执行顺序取决于事件发生的顺序，程序的执行是由顺序产生的消息驱动的，程序员可以针对消息类型编写消息处理程序以处理接收的消息，或者发出其他消息以驱动其他处理程序，但是不必预先确定消息的产生顺序。这是面向对象编程中事件驱动的显著特点。<br>&nbsp; 事件驱动编程方法对于编写交互程序很有用处，用这一方法编写的程序使程序避免了死板的操作模式，从而使用户能够按照自己的意愿采用灵活多变的操作模式。<br>&nbsp; Windows应用程序中的消息传递机制：<br>&nbsp; VC中存在几种系统定义的消息分类，常用的消息由窗口消息、初始化消息、输入消息、系统消息、剪切板消息、文当界面消息、DDE（动态数据交换）消息、应用程序自定义消息等。应用程序发送的消息发送至消息队列，系统根据消息到达的顺序对消息进行处理，并调用响应的消息处理模块代码。<br>*/</p>
<img src ="http://www.cppblog.com/rebol/aggbug/24247.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/rebol/" target="_blank">rebol</a> 2007-05-16 22:46 <a href="http://www.cppblog.com/rebol/archive/2007/05/16/24247.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>