Исследование хранилищ
Хорошо… мы создали хранилище, записали в него данные и прочитали их. Но мы сделали это, ЗНАЯ имя потока, в котором записаны наши данные. Но как быть, если мы не знаем структуры хранилища? Для этого в интерфейсе IStorage предусмотрен механизм перечисления элементов хранилища - он содержится в интерфейсе IEnumStatStg (указатель на который возвращается функцией IStorage.EnumElements):
function EnumElements (reserved1: Longint; reserved2: Pointer; reserved3: Longint;out enm: IEnumStatStg): HResult; stdcall;
Употребление этой функции происходит так:
OleCheck (Stg.EnumElements (0,nil,0,Enum));После этого используем только методы интерфейса IenumStatStg (Next, Skip, Reset, Close). Самым важным из этих методов на данный момент является для нас метод Next:
Next (celt:Longint; out elt; pceltFetched: PLongint): HResult; stdcall;
Он может принимать следующие параметры:
- Celt - количество элементов структуры, которое будет извлечено при его вызове;
- Elt - массив-приемник элементов типа TstatStg;
- PceltFetched - указатель на переменную, в которую будет записано действительное количество извлеченных элементов.
Для примера воспользуемся любым doc-файлом и перечислим его элементы:
procedure TForm1.Button2Click (Sender: TObject); var Stg:IStorage; Enum:IEnumStatStg; Data:TStatStg; begin OleCheck (StgOpenStorage ('D:.doc',nil,STGM_READWRITE or STGM_SHARE_EXCLUSIVE,nil,0,Stg)); OleCheck (Stg.EnumElements (0,nil,0,Enum)); try While Enum.Next (1,Data,nil)=S_Ok do ListBox1.Items.Add (Format ('%s (%d)',[Data.pwcsName,Data.cbSize])); finally Stg:=nil; Enum:=nil; end; end;Структура TStatStg содержит, помимо pwcsName и cbSize, следующие поля:
pwcsName: POleStr; | название потока или хранилища |
dwType: Longint; | тип элемента (флаги типа STGTY_*) |
cbSize: Largeint; | размер конкретного элемента |
mtime,ctime,atime: TFileTime; | дата модификации, создания, последнего доступа |
grfMode: Longint; | флаг доступа |
grfLocksSupported: Longint; | не используется в хранилищах |
clsid: TCLSID; | идентификатор класса хранилища |
grfStateBits: Longint; | статусные биты |
reserved: Longint; | зарезервирован |
Описанные интерфейсы и методы помогут вам не только использовать уже существующие COM-хранилища (такие как документы MS Office), но и создавать собственные,- благодаря чему ваши данные будут храниться в компактном и согласованном виде.