From Disk File to IStream through OleSaveToStream



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?




BaewolfeAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
You'd use

    IPersistStream* pps = NULL;

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

     if (FAILED(hr))
    {    
          // error handler here
    }
0
BaewolfeAuthor Commented:
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
jkrCommented:
Hm, another Idea would be to

COleStreamFile osf;

osf.CreateStream(pStorage);

instead...
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

BaewolfeAuthor Commented:
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
Amritpal SinghCommented:
have a look at the following article
may be of any help
http://support.microsoft.com/default.aspx?scid=kb;EN-US;242249
0
_ys_Commented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
BaewolfeAuthor Commented:
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
BaewolfeAuthor Commented:
In response to YR, pOleObject->GetMoniker returns E_FAIL.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.