_bstr_t m_strSQL = _T("SELECT Photo FROM CorpEmp WHERE EmpName='") + v_strEmpName + _T("' AND EmpNamePY='") + v_strEmpNamePY + _T("'");
try
{
// 使用ADO创建数据库记录集
ado.m_pRecordset.CreateInstance(__uuidof(Recordset));
ado.m_pRecordset->Open((_variant_t)m_strSQL, _variant_t((IDispatch*)ado.m_pConnection, true), adOpenStatic, adLockOptimistic, adCmdText);
// 判断记录是否为空
if(!ado.m_pRecordset->adoBOF && !ado.m_pRecordset->adoEOF)
{
// 如果不为空,则检查 Photo 是否为空
lDataSize = ado.m_pRecordset->GetFields()->GetItem("Photo")->ActualSize;
if(lDataSize > 0)
{
// 需要绘图
pStm.CreateInstance(_T("ADODB.Stream"));
variant_t varOptional(DISP_E_PARAMNOTFOUND, VT_ERROR);
pStm->PutType(adTypeBinary);// 类型为二进制
// 得到字段内容的大小
// m_pRecordset为一个打开的纪录集对象,含有Photo这个blob字段
pStm->Open( varOptional, adModeUnknown, adOpenStreamUnspecified, _bstr_t(), _bstr_t());
// 打开 pStm
pStm->Write(_variant_t(ado.m_pRecordset->GetFields()->GetItem(_T("Photo"))->Value));
varBLOB = pStm->Read(adReadAll);
// 把 Photo 字段的内容写入pStm
pStm->SaveToFile(_T("pub.jpg"), adSaveCreateOverWrite);// 不知道为什么,这行代码不能去掉,否则 pStm 不正常
// 以下代码用于作图
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, pStm->GetSize());
LPVOID pvData = NULL;
if (hGlobal != NULL)
{
if ((pvData = GlobalLock(hGlobal)) != NULL)
{
char * m_pBMPBuffer = new char[pStm->GetSize()+1];//分配必要的存储空间
char *pBuf = NULL;
SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
memcpy(pvData,pBuf,pStm->GetSize()); // 每次执行到这里出错,提示访问内存冲突 SafeArrayUnaccessData (varBLOB.parray);
GlobalUnlock(hGlobal);
}
c_EmpPhoto.Load(hGlobal, pStm->GetSize());
GlobalFree(hGlobal);
c_EmpPhoto.Draw();
Invalidate();
// 作图完成
}
}
}
if(ado.m_pRecordset != NULL)
ado.m_pRecordset->Close();
}
// 捕捉异常
catch (_com_error e)
{
#ifdef _DEBUG
CATCH_ERROR;
#endif
#ifdef _RELEASE
AfxMessageBox(e.Description());
#endif
return FALSE;
}
try
{
// 使用ADO创建数据库记录集
ado.m_pRecordset.CreateInstance(__uuidof(Recordset));
ado.m_pRecordset->Open((_variant_t)m_strSQL, _variant_t((IDispatch*)ado.m_pConnection, true), adOpenStatic, adLockOptimistic, adCmdText);
// 判断记录是否为空
if(!ado.m_pRecordset->adoBOF && !ado.m_pRecordset->adoEOF)
{
// 如果不为空,则检查 Photo 是否为空
lDataSize = ado.m_pRecordset->GetFields()->GetItem("Photo")->ActualSize;
if(lDataSize > 0)
{
// 需要绘图
pStm.CreateInstance(_T("ADODB.Stream"));
variant_t varOptional(DISP_E_PARAMNOTFOUND, VT_ERROR);
pStm->PutType(adTypeBinary);// 类型为二进制
// 得到字段内容的大小
// m_pRecordset为一个打开的纪录集对象,含有Photo这个blob字段
pStm->Open( varOptional, adModeUnknown, adOpenStreamUnspecified, _bstr_t(), _bstr_t());
// 打开 pStm
pStm->Write(_variant_t(ado.m_pRecordset->GetFields()->GetItem(_T("Photo"))->Value));
varBLOB = pStm->Read(adReadAll);
// 把 Photo 字段的内容写入pStm
pStm->SaveToFile(_T("pub.jpg"), adSaveCreateOverWrite);// 不知道为什么,这行代码不能去掉,否则 pStm 不正常
// 以下代码用于作图
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, pStm->GetSize());
LPVOID pvData = NULL;
if (hGlobal != NULL)
{
if ((pvData = GlobalLock(hGlobal)) != NULL)
{
char * m_pBMPBuffer = new char[pStm->GetSize()+1];//分配必要的存储空间
char *pBuf = NULL;
SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
memcpy(pvData,pBuf,pStm->GetSize()); // 每次执行到这里出错,提示访问内存冲突 SafeArrayUnaccessData (varBLOB.parray);
GlobalUnlock(hGlobal);
}
c_EmpPhoto.Load(hGlobal, pStm->GetSize());
GlobalFree(hGlobal);
c_EmpPhoto.Draw();
Invalidate();
// 作图完成
}
}
}
if(ado.m_pRecordset != NULL)
ado.m_pRecordset->Close();
}
// 捕捉异常
catch (_com_error e)
{
#ifdef _DEBUG
CATCH_ERROR;
#endif
#ifdef _RELEASE
AfxMessageBox(e.Description());
#endif
return FALSE;
}
解决方案 »
- adpcm编码
- 请教关于人脸检测和识别的详细步骤
- 关于用SetPrinter API设置打印机分辨率的古怪问题,高手帮忙啦,100分!
- win32api ? or MFC?
- 如何将内存缓冲中的数据强制写入硬盘
- 在CSysStatusView(CFormView继承来的)中,添加CListCtrlEx(继承自CListCtrl)对象(m_list:公有),初始化后一直正常,跟踪发现地址有变化?
- 求助:如何隐藏命令窗口
- 我用Spy++看一个图形界面的程序她的基类是 AFX:XXXXXX请问Afx:XXXXXXXX是什么东东?怎么编写的?
- 在Dialog中点击一按钮,如何产生类似SDI的框??
- 求!请问那里有开源的FAT文件系统?
- 给列表控件发WM_VSCROLL消息的问题
- 如何控制串口打印机实现打印等操作?
看看pvData的空间是否小于pStm->GetSize(),或pvData是否为空?
memcpy(pvData,pBuf,pStm->GetSize()); ---
check to see whether pBuf is invalid?
check result of pStm->GetSize(),or try GetChunk
where to SafeArrayCreate?
其二:开辟内存问题,把一段缓冲区问题用memcpy给pvData,导致出错!
关于这段代码是也是参考网上利用_ISteamPtr接口来写BLOB对象在数据库中的读写的,其中pStm就是_ISteamPtr接口的实例化。这段代码有时正常,有时不正常,其中pStm->SaveToFile(_T("pub.jpg"), adSaveCreateOverWrite);这一句如果去掉就肯定出问题,不知道是什么原因!
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, pStm->GetSize());
LPVOID pvData = NULL;pBuf 空间:
char * m_pBMPBuffer = new char[pStm->GetSize()+1];//分配必要的存储空间
char *pBuf = NULL;
我这里的IStream 是系统自带的那个与ADO.Stream有些不一样
//
我的习惯是直接用IPicture取出绘图. // 字节流
CPicture& operator = ( VARIANT& var )
{
Release();
if( var.vt == VT_UNKNOWN && var.punkVal != NULL )
var.punkVal->QueryInterface( IID_IPicture, (void**)&m_pp );
else if( var.vt == VT_DISPATCH && var.pdispVal != NULL )
{
var.pdispVal->QueryInterface( IID_IPicture, (void**)&m_pp );
}
else if( ( var.vt & VT_ARRAY ) && (var.parray != NULL ) )
{
LONG lSize = ::SafeArrayGetElemsize( var.parray );
CreateFromVariant( var, lSize );
}
//
return *this;
} BOOL CreateFromVariant( VARIANT& var , LONG lSize )
{
HRESULT hr = S_OK;
HGLOBAL hGb = NULL;
IStreamPtr spStream;
ULARGE_INTEGER uls; Close();
//
if( CreateStreamOnHGlobal( NULL, TRUE,&spStream) != S_OK )
return FALSE; uls.QuadPart = ULONGLONG( lSize+1 ); if( FAILED( spStream->SetSize( uls ))) return FALSE; if( FAILED( GetHGlobalFromStream( spStream, &hGb )) ||
hGb == NULL ) return FALSE;
BYTE* datap = (BYTE*)GlobalLock( hGb );
for( LONG i =0; i < lSize ; i++ )
{
hr = SafeArrayGetElement( var.parray, &i, datap++ );
if( FAILED( hr ) )
{
break;
}
}
GlobalUnlock( hGb ); Release();
return ( (FAILED(::OleLoadPicture( spStream , 0, 0, IID_IPicture, (LPVOID *)&m_pp))) ? FALSE : TRUE);
}