﻿<?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++博客-geforceX的编程小苑-文章分类-VC/MFC</title><link>http://www.cppblog.com/geforcex/category/419.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 23 May 2008 18:52:33 GMT</lastBuildDate><pubDate>Fri, 23 May 2008 18:52:33 GMT</pubDate><ttl>60</ttl><item><title>BitBlt()双缓冲解决图象闪烁(转)</title><link>http://www.cppblog.com/geforcex/articles/12199.html</link><dc:creator>geforceX</dc:creator><author>geforceX</author><pubDate>Sat, 09 Sep 2006 09:23:00 GMT</pubDate><guid>http://www.cppblog.com/geforcex/articles/12199.html</guid><wfw:comment>http://www.cppblog.com/geforcex/comments/12199.html</wfw:comment><comments>http://www.cppblog.com/geforcex/articles/12199.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/geforcex/comments/commentRss/12199.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/geforcex/services/trackbacks/12199.html</trackback:ping><description><![CDATA[
		<h4 class="TextColor1" id="subjcns!739F846ACAA71FAF!140" style="MARGIN-BOTTOM: 0px"> </h4>
		<div id="msgcns!739F846ACAA71FAF!140">
				<div>
						<font size="3">显示图形如何避免闪烁，如何提高显示效率是问得比较多的问题。而且多数人认为MFC的绘图函数效率很低，总是想寻求其它的解决方案。<br />MFC的绘图效率的确不高但也不差，而且它的绘图函数使用非常简单，只要使用方法得当，再加上一些技巧，用MFC可以得到效率很高的绘图程序。<br />我想就我长期（呵呵当然也只有2年多）使用MFC绘图的经验谈谈我的一些观点。<br /><br />1、显示的图形为什么会闪烁？<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 />   说到这里可能又有人要说了，为什么一个简单图形看起来没有复杂图形那么闪呢？这是因为复杂图形占的面积大，重画时造成的反差比较大，所以感觉上要闪得厉害一些，但是闪烁频率要低。那为什么动画的重画频率高，而看起来却不闪？这里，我就要再次强调了，闪烁是什么？闪烁就是反差，反差越大，闪烁越厉害。因为动画的连续两个帧之间的差异很小所以看起来不闪。如果不信，可以在动画的每一帧中间加一张纯白的帧，不闪才怪呢。<br /><br /><br />2、如何避免闪烁<br />   在知道图形显示闪烁的原因之后，对症下药就好办了。首先当然是去掉MFC提供的背景绘制过程了。实现的方法很多，<br />* 可以在窗口形成时给窗口的注册类的背景刷付NULL<br />* 也可以在形成以后修改背景<br />   static CBrush brush(RGB(255,0,0));<br />   SetClassLong(this-&gt;m_hWnd,GCL_HBRBACKGROUND,(LONG)(HBRUSH)brush);<br />* 要简单也可以重载OnEraseBkgnd(CDC* pDC)直接返回TRUE<br />   这样背景没有了，结果图形显示的确不闪了，但是显示也象前面所说的一样，变得一团乱。怎么办？这就要用到双缓存的方法了。双缓冲就是除了在屏幕上有图形进行显示以外，在内存中也有图形在绘制。我们可以把要显示的图形先在内存中绘制好，然后再一次性的将内存中的图形按照一个点一个点地覆盖到屏幕上去（这个过程非常快，因为是非常规整的内存拷贝）。这样在内存中绘图时，随便用什么反差大的背景色进行清除都不会闪，因为看不见。当贴到屏幕上时，因为内存中最终的图形与屏幕显示图形差别很小（如果没有运动，当然就没有差别），这样看起来就不会闪。<br /><br /><br /></font>3、如何实现双缓冲<br />   首先给出实现的程序，然后再解释，同样是在OnDraw(CDC *pDC)中：<br /><br />CDC MemDC; //首先定义一个显示设备对象<br />CBitmap MemBitmap;//定义一个位图对象<br /><br />//随后建立与屏幕显示兼容的内存显示设备<br />MemDC.CreateCompatibleDC(NULL);<br />//这时还不能绘图，因为没有地方画 ^_^<br />//下面建立一个与屏幕显示兼容的位图，至于位图的大小嘛，可以用窗口的大小<br />MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight);<br /><br />//将位图选入到内存显示设备中<br />//只有选入了位图的内存显示设备才有地方绘图，画到指定的位图上<br />CBitmap *pOldBit=MemDC.SelectObject(&amp;MemBitmap);<br /><br />//先用背景色将位图清除干净，这里我用的是白色作为背景<br />//你也可以用自己应该用的颜色<br />MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255));<br /><br />//绘图<br />MemDC.MoveTo(……);<br />MemDC.LineTo(……);<br /><br />//将内存中的图拷贝到屏幕上进行显示<br />pDC-&gt;BitBlt(0,0,nWidth,nHeight,&amp;MemDC,0,0,SRCCOPY);<br /><br />//绘图完成后的清理<br />MemBitmap.DeleteObject();<br />MemDC.DeleteDC();<br /><br />上面的注释应该很详尽了，废话就不多说了。<br /><h4 class="TextColor1" id="subjcns!739F846ACAA71FAF!140" style="MARGIN-BOTTOM: 0px"> </h4></div>
		</div>
<img src ="http://www.cppblog.com/geforcex/aggbug/12199.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/geforcex/" target="_blank">geforceX</a> 2006-09-09 17:23 <a href="http://www.cppblog.com/geforcex/articles/12199.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC 6操作技巧</title><link>http://www.cppblog.com/geforcex/articles/1844.html</link><dc:creator>geforceX</dc:creator><author>geforceX</author><pubDate>Sat, 17 Dec 2005 05:36:00 GMT</pubDate><guid>http://www.cppblog.com/geforcex/articles/1844.html</guid><wfw:comment>http://www.cppblog.com/geforcex/comments/1844.html</wfw:comment><comments>http://www.cppblog.com/geforcex/articles/1844.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/geforcex/comments/commentRss/1844.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/geforcex/services/trackbacks/1844.html</trackback:ping><description><![CDATA[1.检测程序中的括号是否匹配 <BR>&nbsp;把光标移动到需要检测的括号（如大括号{}、方括号[]、圆括号（）和尖括号&lt;&gt;）前面，键入快捷键“Ctrl＋]”。如果括号匹配正确，光标就跳到匹配的括号处，否则光标不移动，并且机箱喇叭还会发出一声警告声。 <BR><BR>2.查看一个宏（或变量、函数）的宏定义 <BR>&nbsp;把光标移动到你想知道的一个宏上，就比如说最常见的DECLARE_MAP_MESSAGE上按一下F12(或右键菜单中的Go To Defition Of …),如果没有建立Browse files，会出现提示对话框，确定，然后就会跳到定义那些东西的地方。 <BR><BR>3.格式化一段乱七八糟的源代码 <BR>&nbsp;选中那段源代码，按ATL+F8。 <BR><BR>4.在编辑状态下发现成员变量或函数不能显示 <BR>&nbsp;删除该项目扩展名为.ncb文件，重新打开该项目。 <BR><BR>5.如何整理ClassView视图中大量的类 <BR>&nbsp;可以在classview 视图中右键新建文件夹（new folder），再把具有相近性质的类拖到对应的文件夹中，使整个视图看上去清晰明了. <BR><BR>6.定位预处理指定 <BR>在源文件中定位光标到对称的#if, #endif,使用Ctrl+K. <BR><BR>7.如何添加系统中Lib到当前项目 <BR>&nbsp;在Project | Settings | Link | Object/library modules：输入Lib名称，不同的Lib之间用空格格开. <BR><BR>8.如何添加系统中的头文件(.h)到当前项目. <BR>&nbsp;#include <FILENAME.H />,告诉编译到VC系统目录去找;使用#include "FileName.h"，告诉编译在当前目录找. <BR><BR>9.如何在Studio使用汇编调试 <BR>&nbsp;在WorkBench的Debugger状态下按CTRL+F7. <BR><BR>10.怎样处理ClassZiard找不到的系统消息 <BR>&nbsp;如果要在ClassWizard中处理WM_NCHITTEST等系统消息，请在ClassWizard中Class Info页中将Message filter改为Window就有了. <BR><BR>11.如何干净的删除一个类 <BR>&nbsp;先从Workspace中的FileView中删除对应的.h和.cpp文件,再关闭项目，从实际的文件夹中删除对应的.h和.cpp文件与.clw文件。 <BR><BR>12.如果让控制台应用程序支持mfc类库 <BR>&nbsp;可以在控制台应用程序中include 来引入mfc库，但是控制台应用程序缺省是单线程的，mfc是多线程的，为解决该矛盾，在project setting-&gt;c/c++ 选项，选择code generation,在use run-time library 下拉框中选择debug multithread。 <BR><BR>13.如何汉化只有可执行代码的.exe 文件 <BR>&nbsp;在nt 下利用vc open file 以resources方式打开*.exe 文件，直接修改资源文件，然后保存即可。 <BR><BR>附：VC项目文件说明 <BR>.opt 工程关于开发环境的参数文件。如工具条位置等信息； <BR><BR>.aps (AppStudio File),资源辅助文件,二进制格式,一般不用去管他. <BR><BR>.clw ClassWizard信息文件,实际上是INI文件的格式,有兴趣可以研究一下.有时候ClassWizard出问题,手工修改CLW文件可以解决.如果此文件不存在的话,每次用ClassWizard的时候绘提示你是否重建. <BR><BR>.dsp (DeveloperStudio Project):项目文件,文本格式,不过不熟悉的话不要手工修改.DSW(DeveloperStudio Workspace)是工作区文件,其他特点和DSP差不多. <BR><BR>.plg 是编译信息文件,编译时的error和warning信息文件（实际上是一个html文件）,一般用处不大.在Tools-&gt;Options里面有个选项可以控制这个文件的生成. <BR><BR>.hpj (Help Project)是生成帮助文件的工程,用microsfot &nbsp;Help Compiler可以处理. <BR><BR>.mdp (Microsoft DevStudio Project)是旧版本的项目文件,如果要打开此文件的话,会提示你是否转换成新的DSP格式. <BR><BR>.bsc 是用于浏览项目信息的,如果用Source Brower的话就必须有这个文件.如果不用这个功能的话,可以在Project Options里面去掉Generate Browse Info File,可以加快编译速度. <BR><BR>.map 是执行文件的映像信息纪录文件,除非对系统底层非常熟悉,这个文件一般用不着. <BR><BR>.pch (Pre-Compiled File)是预编译文件,可以加快编译速度,但是文件非常大. <BR><BR>.pdb (Program Database)记录了程序有关的一些数据和调试信息,在调试的时候可能有用. <BR><BR>.exp 只有在编译DLL的时候才会生成,记录了DLL文件中的一些信息.一般也没什么用. <BR><BR>.ncb 无编译浏览文件(no compile browser)。当自动完成功能出问题时可以删除此文件。build后会自动生成。 <img src ="http://www.cppblog.com/geforcex/aggbug/1844.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/geforcex/" target="_blank">geforceX</a> 2005-12-17 13:36 <a href="http://www.cppblog.com/geforcex/articles/1844.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struct多种声明定义写法的小结</title><link>http://www.cppblog.com/geforcex/articles/1308.html</link><dc:creator>geforceX</dc:creator><author>geforceX</author><pubDate>Fri, 25 Nov 2005 07:04:00 GMT</pubDate><guid>http://www.cppblog.com/geforcex/articles/1308.html</guid><wfw:comment>http://www.cppblog.com/geforcex/comments/1308.html</wfw:comment><comments>http://www.cppblog.com/geforcex/articles/1308.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/geforcex/comments/commentRss/1308.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/geforcex/services/trackbacks/1308.html</trackback:ping><description><![CDATA[<P>详细讲解struct这个容易混淆的写法的书是有的，《C专家编程》中就有详细的描述。可惜大家喜欢问问题有甚于喜欢看书，于是BBS上泛滥着前人早已经解决、说明清楚的问题。哎，中国勤学好问者的悲哀。这里简要说明一下struct，为大家省钱。</P><PRE><DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG id=Codehighlighter1_0_93_Open_Image onclick="this.style.display='none'; Codehighlighter1_0_93_Open_Text.style.display='none'; Codehighlighter1_0_93_Closed_Image.style.display='inline'; Codehighlighter1_0_93_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_0_93_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_0_93_Closed_Text.style.display='none'; Codehighlighter1_0_93_Open_Image.style.display='inline'; Codehighlighter1_0_93_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top><SPAN id=Codehighlighter1_0_93_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</SPAN><SPAN id=Codehighlighter1_0_93_Open_Text><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">&nbsp;struct.c<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>*&nbsp;&nbsp;本程序演示了struct的种种写法。注意，所有这些写法都能编译通过<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>*&nbsp;&nbsp;author:&nbsp;smileonce<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>*&nbsp;&nbsp;date&nbsp;&nbsp;:&nbsp;2005-01-14<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top></SPAN><SPAN style="COLOR: #008000">*/</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;这种写法是最要命的，但是它却可以通过,&nbsp;最后面那个foo是结构体的实例</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;foo<BR><IMG id=Codehighlighter1_147_162_Open_Image onclick="this.style.display='none'; Codehighlighter1_147_162_Open_Text.style.display='none'; Codehighlighter1_147_162_Closed_Image.style.display='inline'; Codehighlighter1_147_162_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_147_162_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_147_162_Closed_Text.style.display='none'; Codehighlighter1_147_162_Open_Image.style.display='inline'; Codehighlighter1_147_162_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_147_162_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_147_162_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;foo;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;foo;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;有了typedef，意义明显与上面不同，注意的是struct后面那个标签可以不写，最后面那个bar是匿名结构体的别名</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;<BR><IMG id=Codehighlighter1_248_263_Open_Image onclick="this.style.display='none'; Codehighlighter1_248_263_Open_Text.style.display='none'; Codehighlighter1_248_263_Closed_Image.style.display='inline'; Codehighlighter1_248_263_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_248_263_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_248_263_Closed_Text.style.display='none'; Codehighlighter1_248_263_Open_Image.style.display='inline'; Codehighlighter1_248_263_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_248_263_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_248_263_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;bar;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;bar;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;这种写法是最没人用的，因为它的定义是一次性的,struct1是一个匿名struct的实例</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;<BR><IMG id=Codehighlighter1_327_342_Open_Image onclick="this.style.display='none'; Codehighlighter1_327_342_Open_Text.style.display='none'; Codehighlighter1_327_342_Closed_Image.style.display='inline'; Codehighlighter1_327_342_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_327_342_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_327_342_Closed_Text.style.display='none'; Codehighlighter1_327_342_Open_Image.style.display='inline'; Codehighlighter1_327_342_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_327_342_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_327_342_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;aaa;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;mystruct1;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">最常用的写法，清晰不言自明，my_struct_tag是结构体标签，my_struct_type是struct&nbsp;my_struct_tag的别名</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;my_struct_tag<BR><IMG id=Codehighlighter1_460_475_Open_Image onclick="this.style.display='none'; Codehighlighter1_460_475_Open_Text.style.display='none'; Codehighlighter1_460_475_Closed_Image.style.display='inline'; Codehighlighter1_460_475_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_460_475_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_460_475_Closed_Text.style.display='none'; Codehighlighter1_460_475_Open_Image.style.display='inline'; Codehighlighter1_460_475_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_460_475_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_460_475_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;aaa;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;my_struct_type;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;下面两种定义的写法都可以，当然使用typedef定义的写法更简洁些</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000">my_struct_type&nbsp;mystruct2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">通过typedef定义的结构别名来定义变量</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;my_struct_tag&nbsp;mystruct3;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">通过结构标签定义变量</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;argc,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">argv[])<BR><IMG id=Codehighlighter1_679_692_Open_Image onclick="this.style.display='none'; Codehighlighter1_679_692_Open_Text.style.display='none'; Codehighlighter1_679_692_Closed_Image.style.display='inline'; Codehighlighter1_679_692_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_679_692_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_679_692_Closed_Text.style.display='none'; Codehighlighter1_679_692_Open_Image.style.display='inline'; Codehighlighter1_679_692_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_679_692_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_679_692_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN></DIV></PRE>
<P>-------------</P><img src ="http://www.cppblog.com/geforcex/aggbug/1308.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/geforcex/" target="_blank">geforceX</a> 2005-11-25 15:04 <a href="http://www.cppblog.com/geforcex/articles/1308.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Visual C++中为普通程序添加ODBC应用</title><link>http://www.cppblog.com/geforcex/articles/1288.html</link><dc:creator>geforceX</dc:creator><author>geforceX</author><pubDate>Thu, 24 Nov 2005 05:42:00 GMT</pubDate><guid>http://www.cppblog.com/geforcex/articles/1288.html</guid><wfw:comment>http://www.cppblog.com/geforcex/comments/1288.html</wfw:comment><comments>http://www.cppblog.com/geforcex/articles/1288.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/geforcex/comments/commentRss/1288.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/geforcex/services/trackbacks/1288.html</trackback:ping><description><![CDATA[一、 引言<BR><BR>　　数据库属于最流行的应用程序之一，几乎每个商业部门都使用数据库来记录、管理各种各样的数据。在VC下我们可以在创建工程时选择数据库支持，并选定数据源和相关的表，并选择CRecordView作为我们这个程序的基类，这样做可以毫不费力的将应用程序和数据库建立了关联，而几乎不用编什么代码，但这样做的前提是在新建工程时已明确知道用到哪个数据库，并且有相关的数据库。事实上我们往往有许多已做好的应用程序和类，其功能除了未和数据源建立关联外以基本满足要求，我们只要在其基础上添加ODBC接口，使之与数据库建立关联即可，这样做避免了与数据库无关部分代码的重新编写所造成的重复性操作，大大提高了代码的重用性和利用率。所以在普通程序上通过添加ODBC应用而与数据库建立关联的方法是完全行之有效的。<BR><BR>　　二、 ODBC技术<BR><BR>　　ODBC（Open Database Conectivity 开放式数据库互联）技术，作为Microsoft公司对数据库进行访问的标准应用程序接口(API)和Windows开放式服务体系结构OSA的一个重要组成部分已广为众多的Windows程序员所熟悉、认可。ODBC的工作依赖于数据库制造商提供的驱动程序，使用ODBC API的时候，Windows的ODBC管理程序，把数据库访问的请求传递给正确的驱动程序，驱动程序再使用SQL语句指示DBMS完成数据库访问工作，因此，ODBC的存在为我们开发应用数据库程序提供了非常强大的能力和灵活性。 <BR><BR>　　三、 程序示例<BR><BR>　　(一)打开Visual C++，在"File"菜单上点选"New…"，然后在弹出的"New"对话框中选定"MFC AppWizard(exe)"类的项目，"Project name"为Normal，按下OK键，下一Step 1屏幕中选"Single document"单文档支持，用到后面的选项除在最后一步选择"CFormView"作为本工程视类的基类外均为确省值，此时即可按下Finish键，结果系统将生成一个新的项目Normal。<BR><BR>　　我们就将此工程当做原有的工程，接下来我们便在此工程基础上对其添加ODBC应用，使该工程能同数据源建立关联，能对数据库中的数据进行操作和管理。<BR><BR>　　(二)打开"控制面板"上的"ODBC (32bits)"，对数据源进行注册。为了使ODBC能与数据库一起工作，就必须把数据库注册到ODBC驱动程序管理器，这项工作可以通过定义一个DSN或数据源名字来完成。在弹出的"ODBC数据源管理器"中选择"User DSN"属性页，点击"Add…"按钮。选择"Microsoft Access Driver(*.mdb)"作为数据源的驱动器，点击"完成"按钮。在弹出的"ODBC Microsoft Access 97 Setup"对话框中在"Data Source Name:"栏添入RP97,"Description:"栏只起注释说明的作用，可以不填，然后点击"Select…"按钮，选择所要注册的数据源，然后点击"OK"就完成了对数据源的注册，到这一步，本机上的任意程序只要通过ODBC接口和数据源名"RP97"就能完成对数据库的访问了。<BR><BR>　　(三)在VC的"Workspace"活动窗口中选择"FileView"属性页，打开标准框架头文件"StdAfx.h",并在最后一个#include后面添加对"afxdb.h"的引用：#include &lt;afxdb.h&gt;<BR><BR>　　(四) 在"Workspace"活动窗口中选择"ClassView"属性页，在"Normal Classes"上右键，选"New Class…",在弹出的"New Class"对话框的"Base Class"栏选择"CRecordSet"做为新添加的类的基类，在"Name"栏填写类名"CODBCSet",点击"OK"，在随后弹出的对话框的"ODBC"栏选择刚注册的"RP97"数据源，点击"OK"后选择该数据库的一个表，点击"OK"在"ClassView"里就多了一个以CRecordSet为基类的新类"CODBCSet"。下面三个函数完成了数据库各级元素的绑定工作：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">CString&nbsp;CODBCSet::GetDefaultConnect()<BR><IMG id=Codehighlighter1_38_69_Open_Image onclick="this.style.display='none'; Codehighlighter1_38_69_Open_Text.style.display='none'; Codehighlighter1_38_69_Closed_Image.style.display='inline'; Codehighlighter1_38_69_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_38_69_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_38_69_Closed_Text.style.display='none'; Codehighlighter1_38_69_Open_Image.style.display='inline'; Codehighlighter1_38_69_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_38_69_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_38_69_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;_T(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">ODBC;DSN=RP97</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>CString&nbsp;CODBCSet::GetDefaultSQL()<BR><IMG id=Codehighlighter1_106_129_Open_Image onclick="this.style.display='none'; Codehighlighter1_106_129_Open_Text.style.display='none'; Codehighlighter1_106_129_Closed_Image.style.display='inline'; Codehighlighter1_106_129_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_106_129_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_106_129_Closed_Text.style.display='none'; Codehighlighter1_106_129_Open_Image.style.display='inline'; Codehighlighter1_106_129_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_106_129_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_106_129_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;_T(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">[单据表]</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;CODBCSet::DoFieldExchange(CFieldExchange</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;pFX)<BR><IMG id=Codehighlighter1_184_406_Open_Image onclick="this.style.display='none'; Codehighlighter1_184_406_Open_Text.style.display='none'; Codehighlighter1_184_406_Closed_Image.style.display='inline'; Codehighlighter1_184_406_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_184_406_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_184_406_Closed_Text.style.display='none'; Codehighlighter1_184_406_Open_Image.style.display='inline'; Codehighlighter1_184_406_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_184_406_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_184_406_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">{{AFX_FIELD_MAP(CODBCSet)</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">　pFX</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">SetFieldType(CFieldExchange::outputColumn);<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　RFX_Text(pFX,&nbsp;_T(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">[单据ID]</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">),&nbsp;m_column1);<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　RFX_Text(pFX,&nbsp;_T(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">[单据名称]</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">),&nbsp;m_column2);<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　RFX_Text(pFX,&nbsp;_T(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">[报帐人]</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">),&nbsp;m_column3);<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">}}AFX_FIELD_MAP</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top></SPAN><SPAN style="COLOR: #000000">}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN></DIV><BR>　　(五)按同样的方法再添加一个基于"generic CWnd"的新类"CConnectDB"。在该类的源文件里添加对"ODBCSet.h"的引用：#include "ODBCSet.h"。在该类的头文件的"class CconnectDB"前添加class CODBCSet；并在该类里添加公有型成员变量和函数：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">CDatabase&nbsp;m_dbData;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>CODBCSet</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;m_pSet;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;CConnectDB::Initial()<BR><IMG id=Codehighlighter1_65_288_Open_Image onclick="this.style.display='none'; Codehighlighter1_65_288_Open_Text.style.display='none'; Codehighlighter1_65_288_Closed_Image.style.display='inline'; Codehighlighter1_65_288_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_65_288_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_65_288_Closed_Text.style.display='none'; Codehighlighter1_65_288_Open_Image.style.display='inline'; Codehighlighter1_65_288_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_65_288_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_65_288_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">打开数据源RP97</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">　CString&nbsp;os</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">_T(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">odbc;&nbsp;dsn=RP97</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　m_dbData.Open(NULL,FALSE,FALSE,</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　m_pSet</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;CODBCSet(</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">m_dbData);<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">通过SQL结构化查询语言打开RP97里的单据表</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">　CString&nbsp;sql</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">SELECT&nbsp;*&nbsp;FROM&nbsp;单据表</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　m_pSet</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">Open(AFX_DB_USE_DEFAULT_TYPE,sql);<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN></DIV><BR><BR>　　(六)在Form上添加一个"测试"按钮及其响应函数OnTest()：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;CNormalView::OnTest()&nbsp;<BR><IMG id=Codehighlighter1_28_245_Open_Image onclick="this.style.display='none'; Codehighlighter1_28_245_Open_Text.style.display='none'; Codehighlighter1_28_245_Closed_Image.style.display='inline'; Codehighlighter1_28_245_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_28_245_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_28_245_Closed_Text.style.display='none'; Codehighlighter1_28_245_Open_Image.style.display='inline'; Codehighlighter1_28_245_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_28_245_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_28_245_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　CConnectDB&nbsp;connectDB;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">执行完Initial()后m_pSet指针才不为空，方可安全使用。</SPAN><SPAN style="COLOR: #008000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></SPAN><SPAN style="COLOR: #000000">　connectDB.Initial();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(connectDB.m_pSet</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">NULL)<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　　</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　connectDB.m_pSet</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">MoveFirst();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　CString&nbsp;str</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">connectDB.m_pSet</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">m_column3;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>　AfxMessageBox(str);<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN></DIV><BR>　　最后在该文件开始处添加两个引用：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">ConnectDB.h</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">ODBCSet.h</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN></DIV><BR>　　四、 运行与测试<BR><BR>　　编译运行程序，点击"测试"按钮，就会将"RP97"数据库的"单据表"的第一条记录的"报帐人"字段所在的内容通过对话框弹出来。<BR><BR>　　小结：<BR><BR>　　本程序的关键在于对数据库指针m_pSet的获取，当类CConnectDB 的成员函数Initial()被执行完时，m_pSet就已被获取到了，而在此之前该指针是空的，是不能使用的，所以在实际应用中必须保证在使用m_pSet之前调用过函数Initial()。当m_pSet被获取到之后，就可以想其他ODBC应用程序一样使用CrecordSet类里的各种函数对数据库进行各种需要的操作和管理了。 </TD><img src ="http://www.cppblog.com/geforcex/aggbug/1288.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/geforcex/" target="_blank">geforceX</a> 2005-11-24 13:42 <a href="http://www.cppblog.com/geforcex/articles/1288.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>