描述:
LRESULT CDlg::OnBnClickedRead(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
// TODO: 在此添加控件通知处理程序代码
CISSHelper css;//接口类,继承了ISequentialStream
char* fn = "f:\\first.jpeg";
HRESULT hr;
CBB rs;//数据库的数据格式,本人是用ATL中的OLEDB使用者向导打开的.
BYTE m_blob[8000];//文件在内存中形式
size_t len;
//打开数据库
hr = rs.OpenAll();
hr = rs.MoveFirst();
if(FAILED(hr))
{
ATLTRACE("MoveFirst Failed!\n");
}
//读文件
FILE* file;
file = fopen( fn, "rb");
len = fread( m_blob, sizeof(BYTE), 8000, file);
m_blob[ len + 1] = '\0';
fclose( file);
//向ISequentialStream接口继承类写数据
hr = css.Write( m_blob, len, NULL);
rs.m_BLOB = (ISequentialStream*)&css;
rs.m_dwBLOBStatus = DBSTATUS_S_OK;
rs.m_dwBLOBLength = css.m_ulLength;
//>>-------------------------------------------------------------->>
// 向数据库插入数据
hr = rs.Insert();// 返回值hr= E_UNEXPECTED
//此处报错. 请高手给看看.
//<<--------------------------------------------------------------<<
if(FAILED(hr))
{
ATLTRACE("SaveToDb Failed!\n");
}
//关闭数据库
rs.CloseAll();
return 0;
}
class CISSHelper : public ISequentialStream
{
public:
// Constructor/destructor.
CISSHelper();
virtual ~CISSHelper();
// Helper function to clean up memory.
virtual void Clear();
// ISequentialStream interface implementation.
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
STDMETHODIMP Read(
/* [out] */ void __RPC_FAR *pv,
/* [in] */ ULONG cb,
/* [out] */ ULONG __RPC_FAR *pcbRead);
STDMETHODIMP Write(
/* [in] */ const void __RPC_FAR *pv,
/* [in] */ ULONG cb,
/* [out] */ ULONG __RPC_FAR *pcbWritten);
public:
void* m_pBuffer; // Buffer
ULONG m_ulLength; // Total buffer size.
ULONG m_ulStatus; // Column status.
private:
ULONG m_cRef; // Reference count (not used).
ULONG m_iReadPos; // Current index position for reading from the buffer.
ULONG m_iWritePos; // Current index position for writing to the buffer.
};
CISSHelper::CISSHelper()
{
m_cRef = 0;
m_pBuffer = NULL;
m_ulLength = 0;
m_ulStatus = DBSTATUS_S_OK;
m_iReadPos = 0;
m_iWritePos = 0;
}
CISSHelper::~CISSHelper()
{
Clear();
}
void CISSHelper::Clear()
{
CoTaskMemFree( m_pBuffer );
m_cRef = 0;
m_pBuffer = NULL;
m_ulLength = 0;
m_ulStatus = DBSTATUS_S_OK;
m_iReadPos = 0;
m_iWritePos = 0;
}
ULONG CISSHelper::AddRef(void)
{
return ++m_cRef;
}
ULONG CISSHelper::Release(void)
{
return --m_cRef;
}
HRESULT CISSHelper::QueryInterface( REFIID riid, void** ppv )
{
*ppv = NULL;
if ( riid == IID_IUnknown ) *ppv = this;
if ( riid == IID_ISequentialStream ) *ppv = this;
if ( *ppv )
{
( (IUnknown*) *ppv )->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
HRESULT CISSHelper::Read( void *pv, ULONG cb, ULONG* pcbRead )
{
// Check parameters.
if ( pcbRead ) *pcbRead = 0;
if ( !pv ) return STG_E_INVALIDPOINTER;
if ( 0 == cb ) return S_OK;
// Calculate bytes left and bytes to read.
ULONG cBytesLeft = m_ulLength - m_iReadPos;
ULONG cBytesRead = cb > cBytesLeft ? cBytesLeft : cb;
// If no more bytes to retrive return S_FALSE.
if ( 0 == cBytesLeft ) return S_FALSE;
// Copy to users buffer the number of bytes requested or remaining
memcpy( pv, (void*)((BYTE*)m_pBuffer + m_iReadPos), cBytesRead );
m_iReadPos += cBytesRead;
// Return bytes read to caller.
if ( pcbRead ) *pcbRead = cBytesRead;
if ( cb != cBytesRead ) return S_FALSE;
return S_OK;
}
HRESULT CISSHelper::Write( const void *pv, ULONG cb, ULONG* pcbWritten )
{
// Check parameters.
if ( !pv ) return STG_E_INVALIDPOINTER;
if ( pcbWritten ) *pcbWritten = 0;
if ( 0 == cb ) return S_OK;
// Enlarge the current buffer.
m_ulLength += cb;
// Grow internal buffer to new size.
//m_pBuffer = CoTaskMemRealloc( m_pBuffer, m_ulLength );
m_pBuffer = CoTaskMemAlloc ( m_ulLength );
// Check for out of memory situation.
if ( NULL == m_pBuffer )
{
Clear();
return E_OUTOFMEMORY;
}
// Copy callers memory to in