Load a TOleContainer from a stream which contains a file image, without using CreateObjectFromFile

Hi,
I have a database which contains blobs loaded from file of various MS doc types such as Word and Excel.  I'm trying to load these into a TOleContainer in much the same way that CreateObjectFromFile() works, however, without having to write the contents out to disk, etc.  I've tried a number of combinations to no avail.  Below is a code snippet which may at least help in conveying what I am trying to accomplish.

Any help would be greatly appreciated!

...
      try
        Stream:=TMemoryStream.Create; {Creation memory stream and saving content from database}
        TBlobField(FDataLink.Field).SaveToStream(Stream);
        Stream.Seek(0,soFromBeginning);
        S := GetAssociatedClassname(ExtractFileExt(aOriginalFileName));  // Returns, for example, "Excel.Sheet.8" or "Word.Document.8"
        CreateObject(S, False);
        // LoadFromStream(Stream);  // doesn't work!!!!  ...Invalid Stream format
        if Assigned(Stream) then
          begin
            Stream.Free;
            Stream:=nil;
          end;
      except
        on E:exception do begin
          if Assigned(Stream) then Stream.Free;
          Raise;
        end;
      end;
...
WBreadAsked:
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.

JaccoCommented:
If you add this method to the OleCntrs unit

procedure TOleContainer.LoadAsDocument(const Stream: TStream);
var
  DataHandle: HGLOBAL;
  Buffer: Pointer;
begin
  DataHandle := GlobalAlloc(GMEM_MOVEABLE, Stream.Size);
  if DataHandle = 0 then OutOfMemoryError;
  try
    Buffer := GlobalLock(DataHandle);
    try
      Stream.Read(Buffer^, Stream.Size);
    finally
      GlobalUnlock(DataHandle);
    end;
    OleCheck(CreateILockBytesOnHGlobal(DataHandle, True, FLockBytes));
    DataHandle := 0;
    OleCheck(StgOpenStorageOnILockBytes(FLockBytes, nil, STGM_READWRITE or
      STGM_SHARE_EXCLUSIVE, nil, 0, FStorage));
    OleCheck(OleLoad(FStorage, IOleObject, self, FOleObject));
    FDrawAspect := DVASPECT_CONTENT;
    InitObject;
    FOleObject.SetExtent(DVASPECT_CONTENT, PixelsToHimetric(Point(ClientWidth, ClientHeight)));
    SetDrawAspect(False, 0);
    UpdateView;
  except
    if DataHandle <> 0 then GlobalFree(DataHandle);
    DestroyObject;
    raise;
  end;
end;

the following code will work:

  lContainer := TOleContainer.Create(Self);
  with lContainer do
  begin
    Parent := Form1;
    lFS := TFileStream.Create('test.doc', fmOpenRead);
    try
      LoadAsDocument(lFS);
      DoVerb(ovPrimary);
    finally
      lFS.Free;
    end;
  end;

I don't like pathcing the VCL but sometimes you can't do things otherwise. You can also make a copy of the whole unit.

Regards Jacco
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
WBreadAuthor Commented:
Hi Jacco,
This works great.  Thanks!!

I'm still trying to figured out how to make the document show up in the "viewing" mode, i.e. visible but without the toolbars/menus, that I initially see using CreateObjectFromFile.  If you happen to know this, I'd be glad to see it :)

Either way, this answer is complete and very welcome.

Thanks again
-Todd
0
JaccoCommented:
I have tried getting that result but was not able to find it. I added the GetVerb(...) to have something similar...

Regards Jacco
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
Delphi

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.