Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Чтение сложных OLE-документов

Автор: John Lam

Не используйте для этого компонент TOleContainer. Создавая приложение с возможностью доступа к файлам OLE Structured Storage (стуктурное хранилище), реально необходима только пара вызовов OLE API, и 5-6 вызовов API для доступа к функциям-членам интерфейсов IStorage, IRootStorage и IStream. Я подозреваю, что функция-член TOleContainer IStorage является указателем на корневое хранилище файла Structured Storage, создаваемого функциями-членами LoadFromFile/SaveToFile TOleContainer.

Необходимые функции API:

StgOpenStorage
StgIsStorageFile

Если у вас есть OLE 2.01 SDK, вы можете найти определения там.

Будьте внимательны, при переносе заголовочных файлов C++ из OLE SDK в Delphi, Borland допустил несколько ошибок. Одна из ошибок при создании апплета обернулась мне тремя бессонными ночами. Вот правильное определение IStorage:


MyIStorage = class(IUnknown)
function CreateStream(const pwcsName: PChar; grfMode: Longint; reserved1: Longint;
reserved2: Longint; var ppstm: IStream): HResult; virtual; cdecl; export; abstract;
function OpenStream(const pwcsName: PChar; reserved1: Pointer; grfMode: Longint;
reserved2: Longint; var ppstm: IStream): HResult; virtual; cdecl; export; abstract;
function CreateStorage(const pwcsName: PChar; grfMode: Longint;
reserved1: Longint; reserved2: Longint; var ppstg: MyIStorage): HResult;
virtual; cdecl; export; abstract;
function OpenStorage(const pwcsName: PChar; pstgPriority: MyIStorage;
grfMode: Longint; snbExclude: PStr; reserved: Longint;
var ppstg: MyIStorage): HResult; virtual; cdecl; export; abstract;
function CopyTo(ciidExclude: Longint; const rgiidExclude: IID;
var snbExclude: PStr; pstgDest: MyIStorage): HResult; virtual; cdecl; export; abstract;
function MoveElementTo(const lpszName: PChar; pstgDest: MyIStorage;
const lpszNewName: PChar; grfFlags: Longint): HResult; virtual; cdecl; export; abstract;
function Commit(grfCommitFlags: Longint): HResult; virtual; cdecl; export; abstract;
function Revert: HResult; virtual; cdecl; export; abstract;
function EnumElements(reserved1: Longint; reserved2: Pointer; reserved3: Longint;
var ppenm: IEnumStatStg): HResult; virtual; cdecl; export; abstract;
function DestroyElement(const pwcsName: PChar): HResult; virtual; cdecl; export; abstract;
function RenameElement(const pwcsOldName: PChar;
const pwcsNewName: PChar): HResult; virtual; cdecl; export; abstract;
function SetElementTimes(const lpszName: PChar; const pctime: TFileTime;
const patime: TFileTime; const pmtime: TFileTime): HResult;
virtual; cdecl; export; abstract;
function SetClass(const clsid: IID): HResult; virtual; cdecl; export; abstract;
function SetStateBits(grfStateBits: Longint; grfMask: Longint): HResult;
virtual; cdecl; export; abstract;
function Stat(var pstatstg: TStatStg; grfStatFlag: Longint): HResult;
virtual; cdecl; export; abstract;
end;

Проблема заключалась в том, что некоторые параметры неправильно были объявлены как VAR, тогда как в действительности они объявлены как CONST - это важно, поскольку иногда функции-члены интерфейса ожидают параметры со значением, равным NIL.

Надеюсь, это поможет.

Проект Delphi World © Выпуск 2002 - 2004
Автор проекта: ___Nikolay