Загрузка вывода из TOleContainer.SaveAsDocument - PullRequest
1 голос
/ 13 мая 2011

У меня есть база данных с BLOB-файлами, содержащими составные файлы OLE.У меня есть требование прочитать эти составные файлы OLE и открыть их в элементе управления Delphi 7. TOleContainer.

Обратите внимание, что у меня нет источника приложения, которое читает и записывает в базу данных.База данных остается в активном использовании, поэтому мое решение будет использоваться на постоянной основе, а не только для одноразового извлечения данных.

TOleContainer имеет метод SaveAsDocument, и экспериментально я обнаружил, что дляДля данного файла этот метод создает составные файлы OLE, которые идентичны файлам, созданным в базе данных при добавлении этого файла.

Однако TOleContainer НЕ имеет соответствующего метода LoadFromDocument.У него есть другие методы Load * и Create *, но ни один из них не способен или не подходит для загрузки вывода из SaveAsDocument.

Реализация SaveAsDocument на delphi 7 такова из модуля OleCtnrs.pas:

procedure TOleContainer.SaveAsDocument(const FileName: string);
var
  TempStorage: IStorage;
  PersistStorage: IPersistStorage;
begin
  CheckObject;
  if FModSinceSave then SaveObject;
  FOleObject.QueryInterface(IPersistStorage, PersistStorage);
  if PersistStorage <> nil then
  begin
    OleCheck(StgCreateDocFile(PWideChar(WideString(Filename)), STGM_READWRITE
      or STGM_SHARE_EXCLUSIVE or STGM_CREATE, 0, TempStorage));
    OleCheck(OleSave(PersistStorage, TempStorage, False));
    PersistStorage.SaveCompleted(nil);
  end;
end;

Пожалуйста, предоставьте реализацию LoadFromDocument, которая способна загружать выходные данные из SaveToDocument и которую я могу использовать для исправления OleCtnrs.pas.Или же укажите мне на существующее решение.

Спасибо!

Ответы [ 2 ]

1 голос
/ 13 мая 2011

Вы должны загрузить файл, используя TOleContainer.CreateObjectFromFile. Не используйте TOleContainer.LoadFromStream/File, который работает только с файлами, сохраненными с TOleContainer.SaveToStream/File. Сохраненные таким образом файлы получают специальный заголовок Delphi, содержащий четырехбайтовый код (BDOC) и размер (и, возможно, что-то большее).

0 голосов
/ 13 мая 2011

Согласно документации для Delphi 2007 (должно быть то же самое для), вы можете использовать 'TOleContainer.LoadFromStream'. Из справочного файла Delphi 7 (выделено мое):

Вызовите LoadFromStream, чтобы загрузить объект OLE из потока. Если OldStreamFormat имеет значение true, LoadFromStream загружает объекты OLE, сохраненные объектом TOleContainer , а также объекты OLE, сохраненные в текущем формате; если OldStreamFormat имеет значение false, LoadFromStream не будет загружать объекты OLE, сохраненные библиотекой. Если в контейнере уже есть объект OLE, он уничтожается, и любые изменения, внесенные в него пользователем, отбрасываются.

...