请教高手,复合文件的读写?

ryebread 2000-06-08 07:05:00
我使用StgCreateDocfile建立一复合文件及存储区结构后(使用DOCFileviewer 可以查看),再用StgOpenStorage获得主存储区对象,但是我使用如下语句打开一指定的存储区时:
ASSERT(pStgRoot!=NULL);
str.LoadString(IDS_DEFAULT_ACCOUNT);
VERIFY(pStgRoot->OpenStorage(T2COLE(str),NULL,
STGM_READWRITE and STGM_SHARE_EXCLUSIVE,NULL,0,&pStgAccount)==S_OK);

其中:IDS_DEFAULT_ACCOUNT为建立存储区结构时使用的字符串资源

总会得到一ASSERT错误,即不能打开指定的存储区。请问如何正确打开一复合文件中指定的存储区对象,
...全文
199 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
jy 2000-06-15
  • 打赏
  • 举报
回复
to horrible! 代码变形了。你还是粘到VC中Alt+F8之后再说吧。
jy 2000-06-15
  • 打赏
  • 举报
回复
用法(请放入COleDocument的继承类的某个方法函数体中):
const TCHAR szDefContents[] = _T("Controls");
const TCHAR szContents[] = _T("Contents");
const TCHAR szStandard[] = _T("Standard");
const TCHAR szExtended[] = _T("TheInfoEx");

CEEStorage oStgPic;
CEEStorage lpContStg;
CEEStorage lpRootStg;
CEEStream lpRootStrm;
CEEStream lpExtdStrm;

//m_lpRootStg为COleDocument成员,这里不再详细解说。你可以通过::StgCreateDocFile()得到和他等价的一个指针对象
lpContStg.Open(szContents, m_lpRootStg);
int i;
oStgPic.Open(_T("图"), lpRootStg);
for(i=0; i<m_pics.GetSize(); i++){
CEEStorage lpStg;
CString sz; sz.Format(_T("%X"), m_pics[i].m_wPicNo);
if( !lpStg.Open(sz, oStgPic)){
TRACE(_T("CreateSubStorage ('%s') failed\n"), m_pics[i]);
throw;
}
if( !lpExtdStrm.Open(szExtended, lpStg) ||
!lpRootStrm.Open(szStandard, lpStg) ){
TRACE(_T("CreateStream ('Standard' or 'Extended') failed\n"));
throw;
}
...
jy 2000-06-15
  • 打赏
  • 举报
回复
赞同!并给出更详细一点的代码:

//$//////////////////////////////////////////////////////////////
#include <ATLCONV.H> //T2OLE macro
//=================================================================
// class CEEStorage: IStorage warpper
//=================================================================
class CEEStorage {
IStorage* m_lpStg;
public:
CEEStorage() { m_lpStg = NULL; }
CEEStorage(LPCTSTR szStgName, LPSTORAGE lpStgParent=NULL)
{Open(szStgName, lpStgParent);}
CEEStorage(LPCTSTR szStgName, CEEStorage* lpStgParent=NULL)
{Open(szStgName, lpStgParent);}
~CEEStorage() {Close();}

//open|create a strorage object
BOOL Open(LPCTSTR szStgName, LPSTORAGE lpStgParent=NULL){
USES_CONVERSION; // for T2A
OLECHAR* lpName;
LPSTORAGE lpStg;
lpName = T2OLE(szStgName);
if( FAILED(lpStgParent->OpenStorage(lpName, NULL,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
0,0, &lpStg)) ){
//TRACE(_T("OpenSubStorage ('%s') failed\n"), m_pics[i]);
if( FAILED(lpStgParent->CreateStorage(lpName,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
0,0, &lpStg)) ){
//TRACE(_T("CreateSubStorage ('%s') failed\n"), szStgName);
//AfxThrowArchiveException(CArchiveException::generic);
return FALSE;
}
}
Close(); m_lpStg = lpStg;
return TRUE;
}
BOOL Open(LPCTSTR szStgName, CEEStorage* lpStgParent=NULL)
{return Open(szStgName, lpStgParent);}
void Close(){if(m_lpStg){ m_lpStg->Release(); m_lpStg = NULL; }}

operator LPSTORAGE (){ return m_lpStg; }
BOOL operator ()(){ return m_lpStg!=NULL; }
BOOL operator ! (){ return m_lpStg==NULL; }

void Enumerate();
};

//=================================================================
// class CEEStream: IStream warpper
//=================================================================
class CEEStream {
IStream* m_lpStrm;
public:
CEEStream() {m_lpStrm = NULL;}
CEEStream(LPCTSTR szStrmName, LPSTORAGE lpStgParent)
{Open(szStrmName,lpStgParent);}
CEEStream(LPCTSTR szStrmName, CEEStorage* lpStgParent)
{Open(szStrmName,lpStgParent);}
~CEEStream(){ Close(); }

//open|create a stream object
BOOL Open(LPCTSTR szStrmName, LPSTORAGE lpStgParent){
USES_CONVERSION; // for T2A
OLECHAR* lpName;
LPSTREAM lpStrm;
ASSERT(lpStgParent);
lpName = T2OLE(szStrmName);
if( FAILED(lpStgParent->OpenStream(lpName, NULL,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &lpStrm)) ){
//TRACE(_T("OpenStream ('Standard' or 'Extended') failed\n"));
if( FAILED(lpStgParent->CreateStream(lpName,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
0,0, &lpStrm)) ){
//TRACE(_T("CreateStream ('Standard' or 'Extended') failed\n"));
//AfxThrowArchiveException(CArchiveException::generic);
return FALSE;
}
}
Close(); m_lpStrm = lpStrm;
return TRUE;
}
BOOL Open(LPCTSTR szStrmName, CEEStorage* lpStgParent)
{return Open(szStrmName, (LPSTORAGE)lpStgParent);}
void Close(){ if(m_lpStrm){ m_lpStrm->Release(); m_lpStrm = NULL; }}

operator LPSTREAM (){ return m_lpStrm; }
BOOL operator ()(){ return m_lpStrm!=NULL; }
BOOL operator ! (){ return m_lpStrm==NULL; }

BOOL Read(LPVOID lpBuf, size_t size){
ULONG cb;
ASSERT(lpBuf);
return (S_OK==m_lpStrm->Read((LPVOID)lpBuf, size, &cb)) &&
(cb == size);
}
BOOL Write(LPVOID lpBuf, size_t size){
ULONG cb;
return (S_OK==m_lpStrm->Write((LPVOID)lpBuf, size, &cb)) &&
(cb == size);
}
BOOL Read(CString& sz){
WORD w; size_t s;
if(!Read(w)) return FALSE;
TCHAR* lp = sz.GetBuffer(w+1);
s = (w+1)*sizeof(TCHAR); memset(lp, 0, s);
BOOL b = Read(lp, s);
sz.ReleaseBuffer();
return b;
}
BOOL Write(CString sz){
WORD w = sz.GetLength();
if(!Write(w)) return FALSE;
return Write((LPVOID)(LPCTSTR)sz, w);
}
BOOL Read(int& i){ return Read(&i, sizeof(int)); }
BOOL Write(int i){ return Write(&i, sizeof(int)); }
BOOL Read(WORD& i){ return Read(&i, sizeof(WORD)); }
BOOL Write(WORD i){ return Write(&i, sizeof(WORD)); }
BOOL Read(DWORD& i){ return Read(&i, sizeof(DWORD)); }
BOOL Write(DWORD i){ return Write(&i, sizeof(DWORD)); }

//某些情况下可能不需要在释放对象时调用Release(),例如
//m_lpStrm被CArchieve::Attach()时。
//这时通过SetEmpty()方法可以避免重复调用导致异常
void SetEmpty(){ m_lpStrm = NULL; }
};
//=================================================================
//$//////////////////////////////////////////////////////////////

上面是一个较为简单的封装,即可参考,也可实际使用。
windoze 2000-06-13
  • 打赏
  • 举报
回复
首先,在文件前面加上:
#include <afxpriv.h>
建议加入stdafx.h

然后这样写:

USES_CONVERSION; //这是一个MFC宏
ASSERT(pStgRoot!=NULL);
str.LoadString(...);
HRESULT hr=StgOpenStorage(T2OLE(str), ...);
ASSERT(hr==NOERROR);

上面使用了T2OLE这个宏,原因在于所有OLE函数输入的字符串必须是WideChar,直接使用CString不行。

这个宏在afxpriv.h中声明,使用这个宏的每一个函数必须在函数开头加上
USES_CONVERSION;
注意,是每一个函数,不是每一个文件。

16,467

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧