Поделиться через


Интерфейс IOleUndoManager (ocidl.h)

Интерфейс IOleUndoManager позволяет контейнерам реализовывать многоуровневые операции отмены и повтора для действий, выполняемых внутри содержащихся элементов управления.

Наследование

Интерфейс IOleUndoManager наследуется от интерфейса IUnknown . IOleUndoManager также имеет следующие типы элементов:

Методы

Интерфейс IOleUndoManager содержит следующие методы.

 
IOleUndoManager::Add

Добавляет простой блок отмены в коллекцию. Пока открыт родительский блок отмены, диспетчер отмены добавляет в него единицы отмены, вызывая IOleParentUndoUnit::Add.
IOleUndoManager::Close

Закрывает указанный родительский модуль отмены. (IOleUndoManager.Close)
IOleUndoManager::D iscardFrom

Указывает диспетчеру отмены отменить указанную единицу отмены и все блоки отмены под ним в стеке отмены или повтора.
IOleUndoManager::Enable

Включает или отключает диспетчер отмены.
IOleUndoManager::EnumRedoable

Создает объект перечислителя, который вызывающий объект может использовать для перебора последовательности единиц отмены верхнего уровня из стека повтора.
IOleUndoManager::EnumUndoable

Создает объект перечислителя, который вызывающий объект может использовать для перебора последовательности единиц отмены верхнего уровня из стека отмены.
IOleUndoManager::GetLastRedoDescription

Извлекает описание для единицы отмены верхнего уровня, которая находится поверх стека повторов.
IOleUndoManager::GetLastUndoDescription

Извлекает описание для единицы отмены верхнего уровня, которая находится поверх стека отмены.
IOleUndoManager::GetOpenParentState

Извлекает сведения о состоянии самой внутренней открытой родительской единицы отмены. (IOleUndoManager.GetOpenParentState)
IOleUndoManager::Open

Открывает новый родительский блок отмены, который становится частью стека отмены содержащего его блока.
IOleUndoManager::RedoTo

Указывает диспетчеру отмены вызывать действия отмены обратно через стек повтора вплоть до указанной единицы отмены.
IOleUndoManager::UndoTo

Указывает диспетчеру отмены вызывать действия отмены обратно через стек отмены вплоть до указанного блока отмены.

Комментарии

Элемент управления должен создать блок отмены с интерфейсом IOleUndoUnit или родительский блок отмены с интерфейсом IOleParentUndoUnit, производным от IOleUndoUnit. Оба этих интерфейса выполняют действие отмены, а родительская единица отмены дополнительно может содержать вложенные блоки отмены.

Диспетчер отмены предоставляет централизованную службу отмены и повтора. Он управляет родительскими единицами отмены и простыми единицами отмены в стеке отмены и повтора. Независимо от того, активен ли объект в пользовательском интерфейсе, он может вносить единицы отмены в эти стеки, вызывая методы в диспетчере отмены.

Централизованный диспетчер отмены получает данные, необходимые для поддержки пользовательского интерфейса отмены и повтора для ведущего приложения, и может удалять сведения об отмене постепенно по мере заполнения стека.

Диспетчер отмены реализуется как служба, и объекты получают указатель на IOleUndoManger из интерфейса IServiceProvider . Обычно он реализуется контейнером. Служба управляет двумя стеками: стеком отмены и стеком повтора, каждый из которых содержит единицы отмены, созданные внедренными объектами или самим приложением-контейнером.

Единицы отмены обычно создаются в ответ на действия, предпринятые конечным пользователем. Объект не создает действия отмены для программных событий. На самом деле программные события должны очищать стек отмены, так как программное событие может привести к аннулированию предположений, сделанных единицами отмены в стеке.

При изменении состояния объекта создается блок отмены, инкапсулирующий все сведения, необходимые для отмены этого изменения. Объект вызывает методы в диспетчере отмены для размещения своих единиц отмены в стеке. Затем, когда пользователь выбирает операцию Отмена, диспетчер отмены удаляет верхний блок отмены из стека, вызывает его действие путем вызова метода IOleUndoUnit::D o , а затем освобождает его. Когда пользователь выбирает операцию повтора, диспетчер отмены удаляет верхний блок повтора из стека, вызывает его действие путем вызова метода IOleUndoUnit::D o , а затем освобождает его.

Диспетчер отмены имеет три состояния: базовое состояние, состояние отмены и состояние повтора. Он начинается в базовом состоянии. Чтобы выполнить действие из стека отмены, он переводит себя в состояние отмены, вызывает IOleUndoUnit::D o в блоке отмены и возвращается в базовое состояние. Чтобы выполнить действие из стека повтора, он переводит себя в состояние повтора, вызывает IOleUndoUnit::D o в блоке отмены и возвращается в базовое состояние.

Если диспетчер отмены получает новую единицу отмены в базовом состоянии, он помещает ее в стек отмены и удаляет весь стек повтора. Пока он находится в состоянии отмены, он помещает входящие единицы в стек повтора. Пока он находится в состоянии повтора, он помещает их в стек отмены без очистки стека повтора.

Диспетчер отмены также позволяет объектам удалять стек отмены или повтора, начиная с любого объекта в любом из стеков.

Ведущее приложение определяет область диспетчера отмены. Например, в одном приложении область может находиться на уровне документа; для каждого документа поддерживается отдельный диспетчер отмены, а для каждого документа управление отменой осуществляется независимо. Однако другое приложение поддерживает один диспетчер отмены и, следовательно, один область отмены для всего приложения.

Обработка ошибок

Если операция отмены завершается сбоем и документ остается в нестабильном состоянии, диспетчер отмены, единицы отмены и само приложение должны работать вместе, чтобы избежать этого. В результате существуют определенные требования, которым должны соответствовать единицы отмены, диспетчер отмены и приложение или компонент, использующие отмену.

Чтобы выполнить отмену, диспетчер отмены вызывает IOleUndoUnit::D o в одном или нескольких единицах отмены, которые, в свою очередь, могут содержать больше единиц. Если в иерархии происходит сбой единицы, ошибка в конечном итоге достигнет диспетчера отмены, который отвечает за попытку отката состояния документа до того, что он был до вызова последней единицы верхнего уровня. Диспетчер отмены выполняет откат, вызывая IOleUndoUnit::D o для единицы, которая была добавлена в стек повтора во время попытки отмены. Если откат также завершается сбоем, диспетчер отмены вынужден отказаться от всего и вернуться в приложение. Диспетчер отмены указывает, успешно ли выполнен откат, и приложение может выполнять различные действия в зависимости от этого, например повторную инициализацию компонентов, чтобы они были в известном состоянии.

Все шаги по добавлению блока отмены в стек должны выполняться атомарно. То есть все шаги должны быть успешными или ни один из них не должен быть успешным.

Ведущее приложение, предоставляющее диспетчер отмены, решает, какое действие следует предпринять при сбое отмены. По крайней мере, он должен информировать пользователя о сбое. Диспетчер отмены узнает ведущему приложению, успешно ли выполнена отмена и успешно ли выполнена попытка отката. В случае сбоя отмены и отката ведущее приложение может предоставить пользователю несколько вариантов, включая немедленное завершение работы приложения.

Простые единицы отмены не должны изменять состояние любого объекта, если они возвращают ошибку. Сюда входит состояние стека повтора или отмены стека при выполнении повтора. Они также требуются для того, чтобы поместить соответствующую единицу в стек повтора или отмены при успешном выполнении. Приложение должно быть стабильным до и после вызова единицы.

Родительские единицы отмены имеют те же требования, что и простые единицы, за одним исключением. Если один или несколько дочерних элементов были успешно выполнены до сбоя другого дочернего элемента, родительская единица должна зафиксировать соответствующую единицу в стеке повторов и вернуть ошибку в родительскую. Если дочерние элементы не были выполнены успешно, родительская единица должна зафиксировать свою единицу повтора только в том случае, если она внесла изменение состояния, которое необходимо откатить. Например, предположим, что родительская единица содержит три простых единицы. Первые два завершилось успешно и добавили единицы в стек повтора, но третий завершился сбоем. На этом этапе родительская единица фиксирует свою единицу повтора и возвращает ошибку.

В качестве побочных эффектов родительская единица никогда не должна вносить изменения состояния, которые зависят от успеха их дочерних элементов. Это приведет к прерыванию поведения отката. Если родительская единица вносит изменения в состояние, она должна сделать это перед вызовом каких-либо дочерних элементов. Затем, если изменение состояния завершается сбоем, он не должен фиксировать свою единицу повтора, не должен вызывать дочерние элементы и возвращать ошибку родительскому элементу.

Диспетчер отмены имеет одно основное требование для обработки ошибок: попытка отката при сбое отмены или повтора.

Несоответствующие объекты

Объекты, которые не поддерживают многоуровневую отмену, могут вызвать серьезные проблемы для глобальной службы отмены. Поскольку на объект нельзя полагаться для правильного обновления диспетчера отмены, любые единицы, отправленные другими объектами, также являются подозрительными, так как их единицы могут зависеть от состояния несоответствующего объекта. Попытка отменить единицы совместимого объекта может оказаться неудачной, так как состояние в несоответствующем объекте не будет совпадать.

Чтобы обнаружить объекты, которые не поддерживают многоуровневую отмену, проверка значение OLEMISC_SUPPORTSMULTILEVELUNDO. Объект, который может участвовать в глобальной службе отмены, задает это значение.

Если объект без этого значения добавляется в контекст отмены, видимый пользователем, рекомендуется отключить пользовательский интерфейс отмены для этого контекста. Кроме того, пользователю может быть представлено диалоговое окно с запросом на то, следует ли предоставить поддержку частичной отмены, чтобы обойти несоответствие нового объекта.

Кроме того, несоответствующие объекты могут добавляться во вложенные контейнеры. В этом случае вложенный контейнер должен уведомить диспетчер отмены о том, что отмена больше не может быть безопасной, вызвав IOleUndoManager::Enable с false.

Требования

Требование Значение
Минимальная версия клиента Windows 2000 Профессиональная [классические приложения | Приложения UWP]
Минимальная версия сервера Windows 2000 Server [классические приложения | Приложения UWP]
Целевая платформа Windows
Header ocidl.h

См. также раздел

IOleParentUndoUnit

IOleUndoUnit