说说我想要的功能:
1、我打算从d://test.bmp得到bmp的数据,然后StgCreateStorageEx,通过IPersistStorage的Save函数保存到a.stg中(createStream了一个流“zengraoli”)2、通过读取d://a.stg然后在Load函数中OpenStream流“zengraoli”,从里面得到刚才保存的数据,再写到本地文件1.bmp中不过遇到了一个对于本菜鸟来说很棘手的问题!Save应该是成功了,a.stg也有数据(因为没有Load给我验证,所以也不敢说Save完成没问题!),但是我在测试代码:
hr = ::StgOpenStorage( L"d://a.stg", NULL,
STGM_READ | STGM_SHARE_EXCLUSIVE,
0, 0, &pStg);
assert( SUCCEEDED(hr) ); hr = pStg->OpenStream( (const OLECHAR *)"zengraoli", 0,
 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStm);里面出现问题了,第一个hr(也就是StgOpenStorage)的返回值还是S_OK的,第二个却给我报了个 hr STG_E_FILENOTFOUND The file could not be found. HRESULT然而我也不知道这里为啥会返回这个错误?请大家指点指点!
跪求大家帮我解决解决这个问题啊!不知道为啥,今天连一些简单的问题都不会了。。我晕,是不是因为睡得不够。。泪奔5公里啊!IPersistStorage

解决方案 »

  1.   

    这是我的代码:因为是测试使用的,写得不是很优雅,给大家添麻烦了!
    // CImpIPersist.cpp : 定义控制台应用程序的入口点。
    //#include "stdafx.h"
    #include "windows.h"
    #include "fstream"
    #include "iostream"
    using namespace std;
    #include <initguid.h>
    #include "assert.h"DEFINE_GUID(CLSID_CImpIPersistStorage, 0x00021108, 0, 0, 0xB0,0,0,0,0,0,0,0x47);class CImpIPersistStorage : public IPersistStorage
    {
    protected:
    ULONG m_cRef;
    // LPUNKNOWN m_pUnkOuter;
    LPSTORAGE m_pIStorage;
    LPSTREAM m_pIStream;public:
    CImpIPersistStorage();
    ~CImpIPersistStorage(); STDMETHODIMP QueryInterface(/* [in] */ REFIID riid,
    /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject);
    STDMETHODIMP_(ULONG) AddRef(void);
    STDMETHODIMP_(ULONG) Release(void); STDMETHODIMP GetClassID(LPCLSID); STDMETHODIMP IsDirty(void);
    STDMETHODIMP InitNew(LPSTORAGE);
    STDMETHODIMP Load(LPSTORAGE);
    STDMETHODIMP Save(LPSTORAGE, BOOL);
    STDMETHODIMP SaveCompleted(LPSTORAGE);
    STDMETHODIMP HandsOffStorage(void);
    };CImpIPersistStorage::CImpIPersistStorage()
    {
    m_cRef = 0;
    m_pIStorage = NULL;
    m_pIStream = NULL;
    }CImpIPersistStorage::~CImpIPersistStorage()
    {
    if (0 == m_cRef)
    {
    // delete this;
    }
    }//////////////////////////////////////////////////////////////////////////
    // IUnknown
    //////////////////////////////////////////////////////////////////////////
    STDMETHODIMP CImpIPersistStorage::QueryInterface(/* [in] */ REFIID riid,
     /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject)
    {
    *ppvObject = NULL; if (IsEqualIID(riid, IID_IUnknown))
    *ppvObject=(LPVOID)this; if (IsEqualIID(riid, IID_IPersist)
    || IsEqualIID(riid, IID_IPersistStorage))
    *ppvObject=(LPVOID)this; //AddRef any interface we'll return.
    if (NULL!=*ppvObject)
    {
    ((LPUNKNOWN)*ppvObject)->AddRef();
    return NOERROR;
    } return ResultFromScode(E_NOINTERFACE);
    }STDMETHODIMP_(ULONG) CImpIPersistStorage::AddRef(void)
    {
    ++m_cRef; return (ULONG)m_cRef;
    }STDMETHODIMP_(ULONG) CImpIPersistStorage::Release(void)
    {
    --m_cRef;
    if (0 == m_cRef)
    {
    delete this;
    return 0;
    }
    return (ULONG)m_cRef;
    }
    //////////////////////////////////////////////////////////////////////////
    // IPersistStorage
    //////////////////////////////////////////////////////////////////////////
    STDMETHODIMP CImpIPersistStorage::GetClassID(LPCLSID pClsID)
    {
    *pClsID = CLSID_CImpIPersistStorage;
    return NOERROR;
    }STDMETHODIMP CImpIPersistStorage::IsDirty(void)
    {
    return ResultFromScode(S_OK);
    }STDMETHODIMP CImpIPersistStorage::InitNew(LPSTORAGE pIStorage)
    {
    if (NULL != m_pIStorage)
    {
    return ResultFromScode(E_UNEXPECTED);
    }

    //  HRESULT hr = pIStorage->CreateStream((const OLECHAR *)"zengraoli", STGM_DIRECT
    //  | STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &m_pIStream);
    HRESULT hr = pIStorage->CreateStream((const OLECHAR *)"zengraoli", 
    STGM_DIRECT | STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &m_pIStream); if (FAILED(hr))
    {
    return hr;
    } WriteClassStg(pIStorage, CLSID_CImpIPersistStorage);
    WriteFmtUserTypeStg(pIStorage, 0, 0); pIStorage->AddRef();
    m_pIStorage = pIStorage; return NOERROR;
    }STDMETHODIMP CImpIPersistStorage::Load(LPSTORAGE pIStorage)
    {
    BITMAP bitmap;
    HRESULT hr;
    ULONG           cb = -1;
    ULONG fileLength = 0;
    LPSTREAM pIStream;
    ofstream fout("1.bmp", ios::binary); if (NULL != m_pIStorage)
    return ResultFromScode(E_UNEXPECTED); if (NULL == pIStorage)
    return ResultFromScode(STG_E_INVALIDPOINTER); hr = pIStorage->OpenStream((const OLECHAR *)"zengraoli", 0, STGM_DIRECT
    | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &pIStream); if (FAILED(hr))
    return ResultFromScode(STG_E_READFAULT); // begin read the file length info from IStream
    hr = pIStream->Read((LPVOID)&fileLength, sizeof(ULONG), &cb); if (FAILED(hr) || (sizeof(ULONG) != cb))
    {
    pIStream->Release();
    return ResultFromScode(STG_E_READFAULT); 
    } cout << "read the file length is :" << fileLength << endl; m_pIStream=pIStream; pIStorage->AddRef();
    m_pIStorage=pIStorage; return NOERROR;
    }STDMETHODIMP CImpIPersistStorage::Save( LPSTORAGE pIStorage, BOOL fSameAsLoad )
    {
    HRESULT hr;
    LPSTREAM pIStream;
    ULONG totalWriteBytes = 0;
    if (NULL==pIStorage)
    return ResultFromScode(STG_E_INVALIDPOINTER); // fSameAsLoad is true, mean create a new stream
    if ( fSameAsLoad )
    {
    LARGE_INTEGER li;
    pIStream = m_pIStream; LISet32( li, 0 );
    pIStream->Seek( li, STREAM_SEEK_SET, NULL ); pIStream->AddRef();
    }
    else
    {
    hr = pIStorage->CreateStream( ( const OLECHAR * )"zengraoli", STGM_DIRECT
    | STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pIStream ); if (FAILED(hr))
    {
    return hr;
    } WriteFmtUserTypeStg( pIStorage, 0, 0 );
    } if ( NULL == pIStream )
    {
    return ResultFromScode( STG_E_WRITEFAULT );
    } // read bitmap from local file
    ifstream fin("d://test.bmp", ios::binary);
    if (NULL == fin)
    {
    printf("the file is open fail...");
    return 0;
    }
    fin.seekg(0, ios::end);
    ULONG fileLength = fin.tellg();
    fin.seekg(0, 0);
    int writeLength = fileLength + sizeof(ULONG);
    void *fileData = new char[writeLength + 1];
    *((ULONG*)fileData) = fileLength; // write the bitmap date length to fileDate while (!fin.eof())
    {
    fin.read((char *)fileData + sizeof(ULONG), fileLength);
    } // write fileData to pIStream
    hr = pIStream->Write(fileData, writeLength, &totalWriteBytes);
    pIStream->Release();
    if (FAILED(hr) || totalWriteBytes != writeLength)
    {
    return ResultFromScode(STG_E_WRITEFAULT);
    } return NOERROR;
    }STDMETHODIMP CImpIPersistStorage::SaveCompleted(LPSTORAGE pIStorage)
    {
    HRESULT hr;
    LPSTREAM pIStream; if (NULL != pIStorage)
    {
    hr = pIStorage->OpenStream((const OLECHAR *)"zengraoli", 0, STGM_DIRECT
    | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &pIStream);
    if (FAILED(hr))
    {
    return hr;
    }
    if (NULL != m_pIStream)
    {
    m_pIStream->Release();
    }
    m_pIStream = pIStream;
    if (NULL != m_pIStorage)
    {
    m_pIStorage->Release();
    }
    m_pIStorage = pIStorage;
    m_pIStorage->AddRef();
    } return NOERROR;
    }STDMETHODIMP CImpIPersistStorage::HandsOffStorage(void)
    {
    //Release held pointers
    if (NULL != m_pIStream)
    {
    m_pIStream->Release();
    m_pIStream = NULL;
    }
    if (NULL != m_pIStorage)
    {
    m_pIStorage->Release();
    m_pIStorage = NULL;
    } return NOERROR;
    }int _tmain(int argc, _TCHAR* argv[])
    {
    CImpIPersistStorage test; HRESULT hr;
    IStorage *pStg = NULL; // 根存储指针
    IStorage *pSub = NULL; // 子存储接口指针
    IStream  *pStm = NULL; // 流接口指针//  hr = ::StgCreateStorageEx( L"d://a.stg", 
    //  STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, STGFMT_STORAGE,
    //  0, NULL, NULL, IID_IStorage, (void **)&pStg );
    // 
    //  assert( SUCCEEDED(hr) );
    // 
    //  test.InitNew(pStg);
    //  test.Save(pStg, false);
    //  test.SaveCompleted(pStg);
    hr = ::StgOpenStorage( L"d://a.stg", NULL,
    STGM_READ | STGM_SHARE_EXCLUSIVE,
    0, 0, &pStg);
    assert( SUCCEEDED(hr) ); hr = pStg->OpenStream( (const OLECHAR *)"zengraoli", 0,
     STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStm);
    assert( SUCCEEDED(hr) );
    test.Load(pStg);

    return 0;
    }
      

  2.   

    (const OLECHAR *)的问题。自己修改一下
      

  3.   

    vc6里面的tools目录下有一个DFVIEW.EXE小工具,可以查看你生成的复合文档是否是正确的。
      

  4.   


    嗯,以后得留意一下各种Release才行