rovershen 阅读(988) 评论(0)

复合文档中的基本单位是流(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来看

发表评论
切换编辑模式