Когда хранилище открыто…
Рассмотрим более подробно методы интерфейса IStorage.
Создание потока - IStorage.CreateStream.
function CreateStream (pwcsName: POleStr; grfMode: Longint; reserved1: Longint;reserved2: Longint; out stm: IStream): HResult; stdcall;
Открытие потока - IStorage.OpenStream:
function OpenStream (pwcsName: POleStr; reserved1: Pointer; grfMode: Longint;reserved2: Longint; out stm: IStream): HResult; stdcall;
параметры:
- pwcsName - название потока;
- grfMode - флаги доступа;
- reserved1, reserved2 - соответственно;
- stm - указатель на созданный поток.
Можем приступать к чтению (записи) данных из (в) потоков посредством интерфейсов IStream. Тут можно заметить до боли знакомые методы работы с потоками: Read, Write, Seek… - а если так, то почему бы не перевести эти методы в более простую и понятную объектную форму? Для этого воспользуемся наработками Borland, собранными в модуле AxCtrls.pas (точнее - классом TOleStream, который интерпретирует вызовы методов интерфейса IStream в соответствующие методы класса Tstream).
А чтоб не быть голословным - приведу небольшой пример:
Implementation Uses ActiveX,AxCtrls,ComObj; procedure TForm1.Button1Click (Sender: TObject); var Stg:IStorage; Strm:IStream; OS:TOleStream; S:String; begin OleCheck (StgCreateDocfile ('Testing.stg',STGM_READWRITE or STGM_SHARE_EXCLUSIVE,0,Stg)); OleCheck (Stg.CreateStream ('Testing',STGM_READWRITE or STGM_SHARE_EXCLUSIVE,0,0,Strm)); OS:=TOleStream.Create (Strm); try S:='This is the test'; OS.WriteBuffer (Pointer (S)^,Length (S)); finally OS.free; Strm:=nil; Stg:=nil; end; end; end.В этом фрагменте мы создаем новое хранилище с одним потоком, в который записываем строку S. Естественно, ничто не мешает нам написать например:
Image1.Picture.Bitmap.SaveToStream (OS)- и тем самым записать в поток Testing изображение (вот она - "универсальная мусоросвалка"). Теперь ненадолго отвлечемся от Delphi и посмотрим на наш файл с точки зрения, скажем, Far (или VC)… Посмотрели? Если там же открыть любой документ Word (Excel), убедимся, что структура будет такой же, что и в нашем файле. Проверка принадлежности файла к формату хранилищ проводится с использованием функции StgIsStorageFile из ActiveX.pas:
function StgIsStorageFile (pwcsName: POleStr): HResult; stdcall;
Результат:
- S_OK (0) - файл является хранилищем данных;
- S_FALSE (1) - файл не является хранилищем.
Кроме того, эта функция может принимать значения STG_E_INVALIDFILENAME (если имя задано неправильно) и STG_E_FILENOTFOUND (если файла с таким именем не существует).