﻿<?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++博客-时间的痕迹-随笔分类-ADO</title><link>http://www.cppblog.com/ivenher/category/3332.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 12:33:50 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 12:33:50 GMT</pubDate><ttl>60</ttl><item><title>VC6.0中使用Stream Object读取数据中流文件并显示Bmp,JPG等图片 （转）</title><link>http://www.cppblog.com/ivenher/archive/2007/01/13/17591.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Sat, 13 Jan 2007 08:47:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/archive/2007/01/13/17591.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/17591.html</wfw:comment><comments>http://www.cppblog.com/ivenher/archive/2007/01/13/17591.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/17591.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/17591.html</trackback:ping><description><![CDATA[在VC6.0中我们通常用Ado的Field 对象的GetChuck和AppendChunk来读写Blob对象，但是这样做要写很多的代码，其实ado给我们提供了一个更易操作的对象那就是Stream Object，通过它我们可以更容易的操作数据库中的Blob对象，而且可以直接把Blob对象从数据库保存到本地文件，或者直接读取文件写入到数据库中。下面就详细描述如何操作。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;首先申明Stream对象<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _ StreamPtr&nbsp; pStm;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pStm.CreateInstance("ADODB.Stream");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; variant_t varOptional(DISP_E_PARAMNOTFOUND,VT_ERROR);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pStm-&gt;PutType(adTypeBinary);//类型为二进制<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到字段内容的大小<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp; long lDataSize = m_pRecordset-&gt;GetFields()-&gt;GetItem("photo")-&gt;ActualSize;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //m_pRecordset为一个打开的纪录集对象，含有photo这个blob字段<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pStm-&gt;Open( varOptional,&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adModeUnknown, adOpenStreamUnspecified, _bstr_t(), _bstr_t());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //打开pStm<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pStm-&gt;Write(_variant_t(m_pRecordset-&gt;GetFields()-&gt;GetItem("photo")-&gt;Value));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //把photo字段的内容写入pStm<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pStm-&gt;SaveToFile("c:\\publogo.jpg", adSaveCreateOverWrite);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pStm-&gt;Close();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //直接保存为文件,如果是别的格式只要保存的时候改变后缀就可以了<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下面是如果不保存成文件可以直接通过Com对象来绘制该图片，IPicture 可以显示多种格式图片.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, pStm-&gt;GetSize());&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LPVOID pvData = NULL;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IStream *ps;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (hGlobal != NULL)&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;if ((pvData = GlobalLock(hGlobal)) != NULL)&nbsp; <br>&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char * m_pBMPBuffer = new char[pStm-&gt;GetSize()+1];//分配必要的存储空间<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char *pBuf = NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;SafeArrayAccessData(varBLOB.parray,(void **)&amp;pBuf);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(pvData,pBuf,pStm-&gt;GetSize());&nbsp;//复制数据到缓冲 区&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_pBMPBuffer<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SafeArrayUnaccessData (varBLOB.parray);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GlobalUnlock(hGlobal);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CreateStreamOnHGlobal(hGlobal, TRUE, &amp;ps);<br>&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; }
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color=#3d11ee>IPicture *pPic;</font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color=#1a6be6>if(SUCCEEDED(OleLoadPicture(ps,pStm-&gt;GetSize() ,TRUE,IID_IPicture,(LPVOID*)&amp;pPic))) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { </font></p>
<p><font color=#1a6be6>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OLE_XSIZE_HIMETRIC hmWidth;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OLE_YSIZE_HIMETRIC hmHeight;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pPic-&gt;get_Width(&amp;hmWidth);&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pPic-&gt;get_Height(&amp;hmHeight);&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double fX,fY;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CDC *pDC = GetClientDC();//这里根据具体请况来取<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fX=(double)pDC-&gt;GetDeviceCaps(HORZRES)*(double)hmWidth/((double)pDC-&gt;GetDeviceCaps(HORZSIZE)*100.0);&nbsp; <br>fY =(double)pDC-&gt;GetDeviceCaps(VERTRES)*(double)hmHeight/((double)pDC-&gt;GetDeviceCaps(VERTSIZE)*100.0);&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(FAILED(pPic-&gt;Render(*pDC,0,0,(DWORD)fX,(DWORD)fY,0,hmHeight,hmWidth,-hmHeight,NULL)))&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AfxMessageBox("图像绘制失败！");&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pPic-&gt;Release();&nbsp; <br></font>}&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这样就完成了对图片文件从数据库读出和显示的过程。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于从文件写入数据库就相对的容易多了,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _StreamPtr&nbsp; pStm;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pStm.CreateInstance("ADODB.Stream");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; variant_t varOptional(DISP_E_PARAMNOTFOUND,VT_ERROR);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp; &nbsp;long lDataSize = m_pRecordset-&gt;GetFields()-&gt;GetItem("photo")-&gt;ActualSize;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pStm-&gt;PutType(adTypeBinary；</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pStm-&gt;Open( varOptional,&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adModeUnknown, adOpenStreamUnspecified, _bstr_t(), _bstr_t());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pStm-&gt;LoadFromFile("c:\\book.gif");//读入文件<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; variant_t&nbsp; varBLOB=pStm-&gt;Read(adReadAll);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_pRecordset-&gt;GetFields()-&gt;GetItem("photo")-&gt;Value= varBLOB;//保存到数据集对象。<br>以上就是关于ADO的Stream对象操作数据库中的blob字段的具体方法，主要是对图片我们还可对它进行改造成其他的，比如读者可以改造成读取XMl文件，并保存等等。<br></p>
<img src ="http://www.cppblog.com/ivenher/aggbug/17591.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2007-01-13 16:47 <a href="http://www.cppblog.com/ivenher/archive/2007/01/13/17591.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用MFC + ADO 把jpg图象文件放入ACCESS库中 （转）</title><link>http://www.cppblog.com/ivenher/archive/2007/01/13/17590.html</link><dc:creator>爱饭盒</dc:creator><author>爱饭盒</author><pubDate>Sat, 13 Jan 2007 08:42:00 GMT</pubDate><guid>http://www.cppblog.com/ivenher/archive/2007/01/13/17590.html</guid><wfw:comment>http://www.cppblog.com/ivenher/comments/17590.html</wfw:comment><comments>http://www.cppblog.com/ivenher/archive/2007/01/13/17590.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ivenher/comments/commentRss/17590.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ivenher/services/trackbacks/17590.html</trackback:ping><description><![CDATA[网上好象这个例子还没有样，如果你用VC做一个人事部管理系统，不可能没有人员照片吧！能找到的例子中都是用BMP，不敢用!<br>这个例子用到了VC6.0和access2002(officeXP),涉及到ADO的用法,文件对话框的使用,一个CPicture类和一个buffer缓冲区。<br><br><strong><img height=16 alt="" src="http://www.vckbase.com/document/image/paragraph.gif" width=14 twffan="done"> 一、我的ADO用法整理</strong><br><br>1.　stdafx.h头文件中加入:
<pre>#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF","adoEOF")</pre>
2.　应用程序初始化中加入:
<pre>AfxOleInit();HRESULT hr;try{	hr = m_pConnection.CreateInstance("ADODB.Connection");///创建Connection对象	if(SUCCEEDED(hr))	{	hr = m_pConnection-&gt;Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=wy.mdb","","",adModeUnknown);///连接数据库	///上面一句中连接字串中的Provider是针对ACCESS2000环境的，对于ACCESS97,需要改为:Provider=Microsoft.Jet.OLEDB.3.51;	}}catch(_com_error e)///捕捉异常{	CString errormessage;	errormessage.Format("打开 wy.mdb 数据库失败!\r\n错误信息:%s",e.ErrorMessage());	AfxMessageBox(errormessage);///显示错误信息}</pre>
3.　应用程序EXIT中加入:
<pre>if (m_pConnection-&gt;State) 	    m_pConnection-&gt;Close(); </pre>
4.　应用程序中加入:
<pre>_ConnectionPtr m_pConnection;</pre>
5.　对话框类中加入:
<pre>_RecordsetPtr m_pRecordset;</pre>
6. 注意使用:
<pre>extern CWYApp theApp;</pre>
7. 使用纪录集:
<pre>try{	m_pRecordset.CreateInstance("ADODB.Recordset");	m_pRecordset-&gt;Open("SELECT * FROM 客户 ORDER BY 客户id",				_variant_t((IDispatch*)theApp.m_pConnection,true),				adOpenStatic,adLockOptimistic,adCmdText);}catch(_com_error e)///捕捉异常{	AfxMessageBox("读取数据库失败!");///显示错误信息}</pre>
CPicture类(它能够显示JPG.GIF等等图片，详情请看CPicture.h头文件)
<p>CPicture.h<br>CPicture.cpp<br><br><strong><img height=16 alt="" src="http://www.vckbase.com/document/image/paragraph.gif" width=14 twffan="done"> 二、流程图</strong><br><br><img height=92 alt="" src="http://www.vckbase.com/document/journal/vckbase23/images/ADO_JPG.gif" width=322 twffan="done"><br><br>你一看便知： ADO作用在buffer内存和ACCESS2002数据库之间,而CPicture作用在buffer内存和显示窗口之间. <br><br><strong><img height=16 alt="" src="http://www.vckbase.com/document/image/paragraph.gif" width=14 twffan="done"> 三、将jpg存入库并显示</strong></p>
<pre>void COneDlg::OnButton1()      {	CFile f;	CString  FilePathName;	CFileException e;	CFileDialog dlg(TRUE,NULL,NULL,0,"jpg Files (*.jpg)|*.jpg||",this);	if(dlg.DoModal()==IDOK)	{		FilePathName=dlg.GetPathName();		if(m_Pic.m_IPicture != NULL) m_Pic.FreePictureData(); // Important - Avoid Leaks...		if(f.Open(FilePathName, Cfile::modeRead | Cfile::typeBinary, &amp;e)) //打开了一个jpg文件		{ 			int nSize = f.GetLength();          //先得到jpg文件长度			BYTE * pBuffer = new BYTE [nSize];  //按文件的大小在堆上申请一块内存  			if (f.Read(pBuffer, nSize) &gt; 0 )    //把jpg文件读到pBuffer(堆上申请一块内存)			{				BYTE *pBuf = pBuffer;     ///下面这一大段是把pBuffer里的jpg数据放到库中				VARIANT   varBLOB;				SAFEARRAY  *psa;				SAFEARRAYBOUND rgsabound[1];    				m_pRecordset-&gt;AddNew();         				if(pBuf)				{    					rgsabound[0].lLbound = 0;					rgsabound[0].cElements = nSize;					psa = SafeArrayCreate(VT_UI1, 1, rgsabound);					for (long i = 0; i &lt; (long)nSize; i++)					SafeArrayPutElement (psa, &amp;i, pBuf++);					varBLOB.vt = VT_ARRAY | VT_UI1;					varBLOB.parray = psa;					m_pRecordset-&gt;GetFields()-&gt;GetItem("j")-&gt;AppendChunk(varBLOB);				}				m_pRecordset-&gt;Update();      			(m_Pic.LoadPictureData(pBuffer, nSize));//接作调用函数读pBuffer的jpg数据准备显示			delete [] pBuffer;     //删掉堆上申请的那一块内存			pBuf=0;                //以防二次乱用			}			f.Close();		}		CClientDC dc(this);        		m_Pic.UpdateSizeOnDC(&amp;dc); // Get Picture Dimentions In Pixels		m_Pic.Show(&amp;dc, CRect(200,0,200+m_Pic.m_Width,m_Pic.m_Height) );//显示出来看看	} }.......</pre>
完整的例子中有较多的中文说明，对你有用吗!?，有什么不妥之处请高手指教&nbsp;<br>
<img src ="http://www.cppblog.com/ivenher/aggbug/17590.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ivenher/" target="_blank">爱饭盒</a> 2007-01-13 16:42 <a href="http://www.cppblog.com/ivenher/archive/2007/01/13/17590.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>