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来看
posted @ 2009-01-19 11:45  巩固  阅读(720)  评论(0编辑  收藏  举报