Solved

From Disk File to IStream through OleSaveToStream

Posted on 2004-10-22
1,178 Views
Last Modified: 2013-11-20


I am trying to convert a disk file to an IStream through the OleSaveToStream function.  But I seem to need an IPersistStream object, and I can't figure out how to get one.

Here is my function:

void FileToOleData(HWND hWndParent, LPCTSTR szFileName)
{
  CComPtr<IOleObject>    pOleObject = NULL;
  CComPtr<IStream>    pStream = NULL;
  CComPtr<IOleClientSite>    pClientSite = NULL;

      HRESULT hr;
      WCHAR szWideFileName[255];
      
#ifdef _UNICODE
      _tcsncpy(szWideFileName, szFileName, 254);
#else
      USES_CONVERSION;
      wcsncpy(szWideFileName, T2W(szFileName), 254);
#endif

      //  Open a compound storage document
      IStorage *pStorage = NULL;
      hr = StgOpenStorageEx(
            szWideFileName,
            STGM_READ | STGM_SHARE_DENY_NONE | STGM_TRANSACTED,
            STGFMT_ANY,
            0,
            0, NULL,
            IID_IStorage,
            reinterpret_cast<void**>(&pStorage));
      
      if (FAILED(hr))
      {      
            // error handler here
      }


      hr = OleCreateFromFile(CLSID_NULL,
            szWideFileName, IID_IOleObject, OLERENDER_ASIS, NULL,
            pClientSite, pStorage, (LPVOID*)&pOleObject);
      if (FAILED(hr))
      {      
            // error handler here
      }

      // How do I get pOleObject to an IStream?
}


By the end of the function, I have an IOleObject created from the file.  I want to convert it to a stream using the OleSaveToStream function, but this requires an IPersistStream interface.  So how do I get an IPersistStream interface from IOleObject?

The ultimate goal is to go from a disk file to the OleSaveToStream functions as would be done to insert an OLE Object in a document.  Is there some better way to do this?




0
Question by:Baewolfe
    8 Comments
     
    LVL 86

    Expert Comment

    by:jkr
    You'd use

        IPersistStream* pps = NULL;

        hr = pOleObject ->QueryInterface(IID_IPersistStream, (void**)&pps);

         if (FAILED(hr))
        {    
              // error handler here
        }
    0
     

    Author Comment

    by:Baewolfe
    Yes, that would seem to be the obvious solution, but hr returns with E_NOINTERFACE.  The file is a PowerPoint file.  Why would a PowerPoint file not support the IPersistStream Interface?
    0
     
    LVL 86

    Expert Comment

    by:jkr
    Hm, another Idea would be to

    COleStreamFile osf;

    osf.CreateStream(pStorage);

    instead...
    0
     

    Author Comment

    by:Baewolfe
    That creates a stream, but it doesn't take me through the OleSaveToStream, which is a requirement.

    You may also want to check out my related question "Problems extracting an OLE Object from a Rich-Text (RTF) File by parsing the file".  



    0
     
    LVL 6

    Expert Comment

    by:Amritpal Singh
    have a look at the following article
    may be of any help
    http://support.microsoft.com/default.aspx?scid=kb;EN-US;242249
    0
     
    LVL 9

    Accepted Solution

    by:
    You could obtain a moniker for the OleObject, and use it's PersistStream:

    -----------------x-----------------
    IOleObject *pOleObject = ...;

    IMoniker *pMoniker = NULL;
    if (SUCCEEDED(pOlePbject->GetMoniker(OLEGETMONIKER_FORCEASSIGN, OLEWHICHMK_CONTAINER, &pMoniker)))
    {
        IPersistStream *pPersistStream = NULL;
        if (SUCCEEDED(pMoniker->QueryInterface(IID_IPersistStream, reinterpret_cast<void**>(&pPersistStream)))
        {
        //    a persist stream we have

            pPersistStream->Release();
        }

        pMoniker->Release();
    }
    -----------------x-----------------
    0
     

    Author Comment

    by:Baewolfe
    In response to amrit_82...

    Borrowing from the MSDN code you referenced, I implement the following function and call it after OleCreateFromFile in my code from the original question.  pPersist is NULL so the function returns E_NOINTERFACE.

    My main problem from the original question is that my pOleObject is not supporting the IPersistStream interface.  I have tested it with both Excel and PowerPoint files.





    HRESULT SaveObjectHelper(IOleObject* pObject, IStream* * ppStream)
    {
          HRESULT hr=S_OK;
          try
          {
                *ppStream=NULL;

                // QI and return IPersistStream
                IPersistStreamPtr pIPersist(pObject);

                                    //  pPersist is NULL here

                if (pIPersist)
                {
                      //Create a standard stream in memory
                      if (FAILED(hr=CreateStreamOnHGlobal(0, TRUE, (IStream **)ppStream)))
                            return hr;

                      // Persist the pRS
                      if (FAILED(hr=OleSaveToStream(pIPersist, *ppStream)))
                            return hr;

                }
                else
                      return E_NOINTERFACE;
          }
          catch (_com_error & e)
          {
                return e.Error();
          }
          return S_OK;

    }      
    0
     

    Author Comment

    by:Baewolfe
    In response to YR, pOleObject->GetMoniker returns E_FAIL.
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How to improve team productivity

    Quip adds documents, spreadsheets, and tasklists to your Slack experience
    - Elevate ideas to Quip docs
    - Share Quip docs in Slack
    - Get notified of changes to your docs
    - Available on iOS/Android/Desktop/Web
    - Online/Offline

    Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
    Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
    This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
    Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

    933 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    22 Experts available now in Live!

    Get 1:1 Help Now