MFC中改复合文档里的对象
复合文档中的基本单位是流(stream),文档中每个OLE对象都是按树形结构存放的,每个对象由若干个流组成,文档本身也是一个对象,因此它也有流,用来描述该对象(即该文档)的。一个典型的复合文档结构如下:
root(document)
|----stream1
|----streamN
|----object1
| |----stream1
| |----streamN
....
每个对象包含的流数目与对象有关,如paintbrush对象有三个流,其中位图存放在名为“\1Ole10Native”(“\1”ASCII码为1的字符)的流中。流的起始4字节为DWORD型,用来记录流内容的大小,大小需以16字节的节对齐。
以下为改变paintbrush中位图的代码(假设paintbrush对象在第一个object):
POSITION pos=GetDocument()->GetStartPosition(); COleClientItem*m_pSelection=GetDocument()->GetNextClientItem(pos); if(!m_pSelection) AfxThrowMemoryException(); // any exception will do IStream *pStm; HRESULT hr=m_pSelection->m_lpStorage->OpenStream(L"\1Ole10Native", 0, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &pStm); if(FAILED(hr)) AfxThrowMemoryException(); // any exception will do CFile file; DWORD size; if(!file.Open("c:\\a.bmp",CFile::modeRead)){ AfxMessageBox("Can't open file!"); AfxThrowMemoryException(); // any exception will do } size=file.GetLength(); size=(size+15)/16*16; //must be multiple of 16 bytes HGLOBAL hGbl=GlobalAlloc(GHND,size); LPVOID pBuf=GlobalLock(hGbl); file.Read(pBuf,file.GetLength()); file.Close(); ULARGE_INTEGER uli; uli.QuadPart=size+4; pStm->SetSize(uli); LARGE_INTEGER li; li.QuadPart=0; pStm->Seek(li,STREAM_SEEK_SET,0); pStm->Write(&size,4,0); pStm->Write(pBuf,size,0); pStm->Release(); GlobalUnlock(hGbl); GlobalFree(hGbl); GetDocument()->SetModifiedFlag(); m_pSelection->m_lpObject->Update();至于文档的流分布状况,可以用VC自带的工具DFView来看