起因是我在ocx中封装了一个 richedit2.0 控件,并自己写了一个
用于显示图片
ole 对象 。在我的ocx中插入大量的ole对象,大约3000个,然后保存为rtf。再使用我的ocx控件打开这个rtf时,会提示 内存不足。跟踪代码时发现在我实现的 IRichEditOleCallback 接口的 GetNewStorage(LPSTORAGE* lplpstg) 中报错。
我的程序中创建 IStorage的思路是,在 IRichEditOleCallback 接口初始化时调用 StgCreateDocfile 创建一个根 Istorage,以后每个对象插入的时候 IRichEditOleCallback 的 GetNewStorage 接口被调用,在
GetNewStorage
方法中 在 根 Istorage 下建立一个subStroage。
HRESULT hResult = ::StgCreateDocfile(NULL,STGM_TRANSACTED|STGM_READWRITE | STGM_SHARE_EXCLUSIVE |STGM_CREATE ,
0, &m_pStorage );
//建立一个sub storage
WCHAR tName[50] = {0};
swprintf(tName, L"substorage%d", m_iNumStorages);
HRESULT hResult = pStorage->CreateStorage(tName,
STGM_TRANSACTED|STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE ,
0, 0, lplpstg );
后来发现 把 STGM_TRANSACTED 标识去掉就可以了。有点莫名其妙,估计是事务的处理会导致内存的占用增加的缘故吧。
另外 在msdn 中 搜索 STGM ,注意红色的字体,也就是收 使用com中的 IStorage 接口,是不能创建具有 STGM_TRANSACTED 表示的 IStream对象的
- STGM_TRANSACTED
- In transacted mode, changes are buffered and written only if an explicit
commit operation is called. To ignore the changes, call the Revert method
in the IStream, IStorage, or IPropertyStorage interface.
The COM compound file implementation of IStorage does not support
transacted streams, which means that streams can be opened only in direct mode,
and you cannot revert changes to them, however transacted storages are
supported. The compound file, stand-alone, and NTFS file system implementations
of IPropertySetStorage similarly do not support transacted, simple
property sets because these property sets are stored in streams. However,
transactioning of nonsimple property sets, which can be created by specifying
the PROPSETFLAG_NONSIMPLE flag in the grfFlags parameter of
IPropertySetStorage::Create, are supported.