На этом шаге мы рассмотрим интерфейсы памяти.
Существует ряд интерфейсных методов, используемых для доступа к структурной памяти OLE. Эти интерфейсы перечислены в таблице 1. В этой таблице приводятся интерфейсы, их реализация и компоненты, которые их используют (контейнер, сервер, контейнер и сервер, OLE или кто-нибудь еще).
| Интерфейс | Реализация | >Кто использует |
|---|---|---|
| Используется, когда необходимо задать перечисление объектов IStorage. В составных файлах элементы будут состоять из субпамяти и потоков. Вы также можете вызвать функцию IStorage::EnumElements() для того, чтобы получить указатель на интерфейс IEnumSTATSG | ||
| Несмотря на то, что интерфейс ILockBytes может использоваться и в приложениях, в основном он используется OLE в качестве метода манипуляции массивами байтов, лежащими в основе составных файлов | ||
| Используется для управления распределением памяти для приложений OLE. Интерфейс IMalloc жизненно важен, ниже он описывается более детально | ||
| Обработчики объектов и приложения объектов | Может использоваться для получения CLSID данного объекта. Интерфейсы IPersistStorage, IPersistStream и IPersistFile базируются на интерфейсе IPersist | |
| Приложения объектов и (необязательно) приложения контейнеров для поддержки компоновки с внедренными и файловыми объектами | Используется OLE для загрузки объектов документов внешнего уровня, которые размещаются в файлах, в отличие от документов, внедренных внутрь составного документа | |
| Обработчики объектов и приложения объектов | Используется контейнерными приложениями для чтения и записи, собственно данных объектов составных документов, которые находятся в интерфейсе IStorage | |
| Используется контейнерными приложениями для чтения и записи объектов, хранящихся в потоковой памяти | ||
| Используется контейнерными приложениями для переключения между дисковыми файлами, лежащими в основе объектов IStorage | ||
| Используется для связи с объектом структурной памяти. Интерфейс IStorage очень важен, ниже он описывается более детально | ||
| Используется для связи с потоковыми объектами, находящимися в объекте IStorage. Вы можете рассматривать объект IStream во многом подобным несоставному файлу |
Далее мы рассмотрим интерфейсы IMalloc и IStorage.
Составными файлами можно манипулировать с помощью указателя на объект интерфейса IStorage. В листинге 1 интерфейс IStorage используется для взаимодействия с объектами структурной памяти.
Листинг 1. Интерфейс IStorage
DECLARE INTERFACE_ (IStorage, IUnknown)
{
// *** методы IUnknown ***
HRESULT QueryInterface (THIS_ REFIID riid, LPVOID FAR* ppvObj);
ULONG AddRef (THIS);
ULONG Release (THIS);
// *** методы IStorage ***
HRESULT CreateStream(THIS_ const char FAR* pwcsName, DWORD grfMode,
DWORD dwReserved1, DWORD dwReserved2, LPTSTREAM FAR* ppStm);
HRESULT OpenStream(THIS_ const char FAR* pwcsName, void FAR *pReserved1,
DWORD grfMode, DWORD dwReserved2, LPTSTREAM FAR* ppStm);
HRESULT CreateStorage(THIS_ const char FAR* pwcsName, DWORD grfMode,
DWORD dwReserved1, DWORD dwReserved2, LPTSTORAGE FAR* ppStg);
HRESULT OpenStorage(THIS_ const char FAR* pwcsName,
LPSTORAGE FAR *pstgPriority, DWORD grfMode,
SNB snbExclude, DWORD dwReserved, LPTSTORAGE FAR* ppStg);
HRESULT CopyTo(THIS_ DWORD dwCiidExclude, IID const FAR *rgiidExclude,
SNB snbExclude, LPSTORAGE FAR* pStgDest);
HRESULT MoveElementTo(THIS_ const char FAR* ipszName,
LPSTORAGE FAR *pStgDest,
const char FAR* lpszNewName, DWORD grfFlags);
HRESULT Commit(THIS_ DWORD grfCommitFlags);
HRESULT Revert(THIS);
HRESULT EnumElements(THIS_ DWORD dwReserved1, void FAR* pReserved2,
DWORD dwReserved3, LPENUMSTATSG FAR* ppenumStatStg);
HRESULT DestroyElement(THIS_ const char FAR* pwcsName);
HRESULT RenameElement(THIS_ const char FAR* pwcsOldName,
const char FAR* pwcsNewName);
HRESULT SetElementTimes(THIS_ const char FAR* IpszName,
FILETIME const FAR *pctime;
FILETUME const FAR *patime, FILETIME const FAR *pmtime);
HRESULT SetClass(THIS_ REFCLSID rclsid);
HRESULT SetStateBits(THIS_ DWORD grfStateBits, DWORD grfMask);
HRESULT Stat(THIS_ STATSG FAR *pStatStg, DWORD grfStatFlag);
};
Как продемонстрировано в листинге 1, память для процедур OLE выделяется, главным образом, с помощью функций интерфейса IMalloc. В IMalloc входят функции, подобные библиотечным функциям языка C alloc(), free() и realloc(). В листинге 2 демонстрируется формат интерфейса IMalloc.
Листинг 2. Интерфейс IMalloc
DECLARE_INTERFACE_ (IMalloc, IUnknown)
{
// *** методы IUnknown***
HRESULT QueryInterface (THIS_REFIID riid, LPVOID FAR* ppvOj);
ULONG AddRef (THIS);
ULONG Release (THIS);
// *** методы IMalloc ***
void FAR*Allooc (THIS_ ULONG cb);
void Free (THIS_ void FAR* pv);
void FAR*Realloc (THIS_ void FAR* pv, ULONG cb);
ULONG Getsize (THIS_ void FAR* pv);
int DidAlloc (THIS_ void FAR* pv);
void HeapMinimize (THIS);
};
На следующем шаге мы рассмотрим функции для субпамяти и потоков.