Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лек 008.doc
Скачиваний:
14
Добавлен:
07.02.2015
Размер:
47.62 Кб
Скачать

2. Доступ к structured storage через ole2 api

Microsoft предоставляет мощные средства для работы в рамках технологии OLE, они сконцентрированы в библиотеках OLE2.DLL (для 16-разрядных приложений) и OLE32.DLL (для 32-разрядных приложений). В принципе, к ним можно обращаться из любой системы программирования (например, из MS VB и даже из языка ассемблера), использовав традиционный механизм GetModuleHandle/GetProcAddress. Но проще всего это делать из MS VC или Borland C/C++. По крайней мере, все примеры из этой статьи компилировались при помощи Borland C/C++ v5.01.

Итак, в довольно объемной и сложной библиотеке OLE32.DLL для нас с точки зрения темы статьи интересны около дюжины API- функций, позволяющих создавать и открывать составные файлы в различных режимах, обращаться к их каталогам и т.п. Рассмотрим некоторые из них.

  1. Создание нового составного файла с форматом структурированного хранилища:

  2. HRESULT StgCreateDocfile (WCHAR *„I„}„‘„U„p„z„|„p,

  3. DWORD „U„|„p„s„y„D„Ђ„ѓ„„„…„Ѓ„p,

  4. DWORD „N„u„I„ѓ„Ѓ„Ђ„|„Ћ„x„…„u„„„ѓ„‘,

  5. IStorage **„I„~„„„u„‚„†„u„z„ѓ);

    Обычно для параметра ФлагиДоступа используется конкатенация из битов STGM_CREATE (создать новый составной файл), STGM_READ (разрешить чтение), STGM_WRITE (разрешить запись) или STGM_READWRITE (разрешить чтение и запись). Но можно указать STGM_CONVERT, это якобы позволяет преобразовывать "сырые" данные в структурированное хранилище, помещая их в поток с предопределенныи именем CONTENTS.

  6. Открытие существующего составного файла, имеющего формат структурированного хранилища, флаги те же:

  7. HRESULT StgOpenStorage (WCHAR *„I„}„‘„U„p„z„|„p,

  8. IStorage *„T„w„u„O„„„{„‚„Ќ„„„Ќ„z„I„~„„„u„‚„†„u„z„ѓ,

  9. DWORD „U„|„p„s„y„D„Ђ„ѓ„„„…„Ѓ„p,

  10. SNB „M„p„ѓ„{„p„I„ѓ„{„|„ђ„‰„u„~„y„‘,

  11. DWORD „N„u„I„ѓ„Ѓ„Ђ„|„Ћ„x„…„u„„„ѓ„‘,

  12. IStorage **„I„~„„„u„‚„†„u„z„ѓ);

  13. Проверка файла на соответствие формату структурированного хранилища. Возвращает S_OK - это хранилище; S_FALSE - это не хранилище; STG_E_FILENOTFOUND - файла вообще нет:

  14. HRESULT StgIsStorageFile(WCHAR* „I„}„‘„U„p„z„|„p)

    Функции StgCreateDocfile и StgOpenStorage требуют имя дискового файла (например, L"C:\FILE.DOC"), а возвращают в последнем параметре интерфейс доступа - т.е. указатель на объект класса IStorage, свойства и методы которого позволяют манипулировать с элементами структуры уже открытого или созданного составного документа (физически это - просто массив адресов).

    Дальше кратко описываются некоторые, наиболее интересные методы этого интерфейса.

  15. Создание нового подкаталога в главном каталоге открытого составного файла.

  16. HRESULT CreateStorage(wchar_t *„I„}„‘„P„Ђ„t„{„p„„„p„|„Ђ„s„p,

  17. DWORD „U„|„p„s„y„D„Ђ„ѓ„„„…„Ѓ„p,

  18. DWORD „N„u„I„ѓ„Ѓ„Ђ„|„Ћ„x„…„u„„„ѓ„‘1,

  19. DWORD „N„u„I„ѓ„Ѓ„Ђ„|„Ћ„x„…„u„„„ѓ„‘2,

  20. IStorage **„O„„„{„‚„Ќ„„„Ќ„z„O„q„Њ„u„{„„);

  21. Открытие существующего подкаталога в главном каталоге открытого составного файла.

  22. HRESULT OpenStorage(wchar_t *„I„}„‘„P„Ђ„t„{„p„„„p„|„Ђ„s„p,

  23. IStorage *„T„w„u„O„„„{„‚„Ќ„„„Ќ„z„O„q„Њ„u„{„„

  24. DWORD „U„|„p„s„y„D„Ђ„ѓ„„„…„Ѓ„p,

  25. SNB „I„}„u„~„p„P„Ђ„„„Ђ„{„Ђ„r,

  26. DWORD „N„u„I„ѓ„Ѓ„Ђ„|„Ћ„x„…„u„„„ѓ„‘,

  27. IStorage **„O„„„{„‚„Ќ„„„Ќ„z„O„q„Њ„u„{„„);

  28. Закрытие открытого каталога или подкаталога после завершения работы с ними (крайне рекомендуется использовать!).

  29. ULONG Release(void);

  30. Инициализация перечисления записей в каталоге или подкаталоге.

  31. HRESULT EnumElements(DWORD „N„u„I„ѓ„Ѓ„Ђ„|„Ћ„x„…„u„„„ѓ„‘1,

  32. void „N„u„I„ѓ„Ѓ„Ђ„|„Ћ„x„…„u„„„ѓ„‘2,

  33. DWORD „N„u„I„ѓ„Ѓ„Ђ„|„Ћ„x„…„u„„„ѓ„‘3,

  34. IEnumSTATSTG **„I„~„„„u„‚„†„u„z„ѓ„P„u„‚„u„‰„y„ѓ„|„u„~„y„‘);

    Возвращает новый интерфейс к объекту-перечислителю, который обладает методами:

    1. HRESULT Next(ULONG ???????, void *????, void *?????????????????)- возвращает очередные элементы;

    2. HRESULT Skip(ULONG ???????)- пропускает элементы списка;

    3. HRESULT Reset(void)- возвращает позицию начала списка;

    4. HRESULT Clone(???????)- возвращает копию перечислителя.

  35. Создание нового потока внутри открытого каталога.

  36. HRESULT CreateStream(wchar_t * „I„}„‘„P„Ђ„„„Ђ„{„p,

  37. DWORD „U„|„p„s„y„D„Ђ„ѓ„„„…„Ѓ„p,

  38. DWORD „N„u„I„ѓ„Ѓ„Ђ„|„Ћ„x„…„u„„„ѓ„‘1,

  39. DWORD „N„u„I„ѓ„Ѓ„Ђ„|„Ћ„x„…„u„„„ѓ„‘2,

  40. IStream **„O„„„{„‚„Ќ„„„Ќ„z„P„Ђ„„„Ђ„{);

  41. Открытие потока внутри открытого каталога.

  42. HRESULT OpenStream(const wchar_t *„I„}„‘„P„Ђ„„„Ђ„{„p,

  43. void *„N„u„I„ѓ„Ѓ„Ђ„|„Ћ„x„…„u„„„ѓ„‘1,

  44. DWORD „U„|„p„s„y„D„Ђ„}„„„…„Ѓ„p,

  45. DWORD „N„u„I„ѓ„Ѓ„Ђ„|„Ћ„x„…„u„„„ѓ„‘2,

  46. IStream **„O„„„{„‚„Ќ„„„Ќ„z„P„Ђ„„„Ђ„{);

  47. Запись данных в поток.

  48. HRESULT Write(void *„A„…„†„u„‚,

  49. ULONG „Q„p„x„}„u„‚,

  50. ULONG *„Q„u„p„|„Ћ„~„Ђ„H„p„Ѓ„y„ѓ„p„~„Ђ);

  51. Чтение данных из потока.

  52. HRESULT Read(void *„A„…„†„u„‚,

  53. ULONG „Q„p„x„}„u„‚,

  54. ULONG *„Q„u„p„|„Ћ„~„Ђ„P„‚„Ђ„‰„y„„„p„~„Ђ);

  55. Переименование записи в каталоге.

  56. HRESULT RenameElement(wchar_t *„R„„„p„‚„Ђ„u„I„}„‘,

  57. wchar_t *„N„Ђ„r„Ђ„u„I„}„‘);

Фактически, сервисных методов гораздо больше. Например, существует большой набор методов для работы с lock-bytes, но он нам в контексте статьи не слишком актуален.

Теперь рассмотрим примерчик работы с составным файлом через OLE API, а именно - рекурсивный просмотр дерева заключенных внутри объектов:

// Рекурсивный сканер docfile. (с) Климентьев К., Самара 2002

#include "windows.h"

#include "ole2.h"

#include "iostream.h"

#include "stdio.h"

int level=0;

walk(char *s, LPSTORAGE ls)

{

OLECHAR FileName[256]; LPENUMSTATSTG lpEnum=NULL;

LPSTORAGE pIStorage=NULL; LPSTORAGE pIStorage2=NULL;

ULONG uCount; STATSTG stat; int i;

if (!ls) {

mbstowcs(FileName, s, 256); wprintf(L"[%s]\n", FileName);

StgOpenStorage(FileName, NULL,

STGM_READ|STGM_SHARE_EXCLUSIVE,

NULL,0,&pIStorage);

walk("", pIStorage);

}

else {

ls->EnumElements(0,NULL,0,&lpEnum);

if (lpEnum)

while (lpEnum->Next(1,&stat,&uCount)==S_OK) {

for (i=0;i<level;i++) wprintf(L" ");

wprintf(L"%d: %s\n", stat.type, (LPSTR)stat.pwcsName);

if (stat.type==STGTY_STORAGE) {

ls->OpenStorage(stat.pwcsName, NULL,

STGM_READ|STGM_SHARE_EXCLUSIVE,

NULL, 0, &pIStorage2);

level++;

walk("", pIStorage2);

level--;

}

};

ls->Release();

}

}

int main(int argc, char* argv[]) {

if (argc>1) walk(argv[1],NULL);

}

Создадим в Word 97/2000/XP пустой DOC-файл без текста и напустим на него нашу программу. Мы увидим примерно следующее:

[word97.doc]

2: 1Table

2: \1CompObj

1: ObjectPool

2: WordDocument

2: \5SummaryInformation

2: \5DocumentSummaryInformation

Для DOC-файла в формате Word 6/7 (его можно создать, например, при помощи Wordpad) картинка будет попроще:

[word6.doc]

2: \1CompObj

2: WordDocument

Примерно так, как описано в этом разделе, устроены популярный FAR-плагин DocFile Browser Игоря Павлова и утилита OLE2View из MS Visual C/С++.

Если хотите подробностей, то рекомендую:

1) хорошую статью Артема Каева "ActiveX по шагам"; 2)фирменный материал от Microsoft "OLE 2 programmers reference" (его можно найти в файлах OLE.HLP или OLE2.HLP).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]