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


Слияние меню "Справка"

Если объект активен в контейнере, то протокол слияния меню OLE Documents предоставляет объекту полный контроль над меню справки . В результате разделы справки контейнера недоступны, если пользователь не деактивирует объект. Архитектура активного содержимого документа расширяет правила объединения меню на месте, чтобы разрешить контейнеру и активному документу, активному для совместного использования меню. Новые правила — это просто дополнительные соглашения о том, какой компонент владеет частью меню и как создается общее меню.

Новое соглашение просто. В активных документах меню справки имеет два элемента меню верхнего уровня, организованные следующим образом:

Help

Container Help >

Object Help >

Например, если раздел Word активен в привязке Office, меню справки будет отображаться следующим образом:

Help

Binder Help >

Word Help >

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

Для создания этого объединенного меню справки активная архитектура хранения документов изменяет обычную процедуру OLE Documents. Согласно документам OLE, в объединенной строке меню может быть шесть групп меню, а именно "Файл", "Изменить", "Контейнер", "Объект", "Окно", "Справка" в этом порядке. В каждой группе может быть нулевая или более меню. Группы File, Container и Window принадлежат контейнеру, а группы Edit, Object и Help принадлежат к объекту. Когда объект хочет выполнить слияние меню, он создает пустую строку меню и передает ее контейнеру. Затем контейнер вставляет свои меню, вызывая вызов IOleInPlaceFrame::InsertMenus. Объект также передает структуру, которая является массивом шести длинных значений (OLEMENUGROUPWIDTHS). После вставки меню контейнер помечает количество добавленных меню в каждой из групп, а затем возвращается. Затем объект вставляет свои меню, обращая внимание на количество меню в каждой группе контейнеров. Наконец, объект передает объединенную строку меню и массив (который содержит количество меню в каждой группе) в OLE, который возвращает непрозрачный дескриптор меню. Позже объект передает этот дескриптор и объединенную строку меню в контейнер.IOleInPlaceFrame::SetMenu В настоящее время контейнер отображает объединенную строку меню, а также передает дескриптор OLE, чтобы OLE смог выполнить правильную отправку сообщений меню.

В измененной активной процедуре документа объект должен сначала инициализировать элементы OLEMENUGROUPWIDTHS до нуля перед передачей в контейнер. Затем контейнер выполняет обычную вставку меню с одним исключением: контейнер вставляет меню справки в качестве последнего элемента и сохраняет значение 1 в последней (шестой) записи массива OLEMENUGROUPWIDTHS (то есть ширина[5], которая принадлежит группе справки объекта). Это меню справки будет содержать только один элемент, который является подменю, каскадным меню "Справка> контейнера", как описано ранее.

Затем объект выполняет обычный код вставки меню, за исключением того, что перед вставкой меню справки он проверка шестой записи массива OLEMENUGROUPWIDTHS. Если значение равно 1, а имя последнего меню — справка (или соответствующая локализованная строка), объект вставляет меню справки в качестве подменю меню справки контейнера.

Затем объект задает шестой элемент OLEMENUGROUPWIDTHS равным нулю и увеличивает пятый элемент на один. Это позволяет OLE знать, что меню справки принадлежит контейнеру, а сообщения меню, соответствующие этому меню (и его подменю), должны быть перенаправлены в контейнер. Затем контейнер должен пересылать WM_INITMENUPOPUP, WM_SELECT, WM_COMMAND и другие сообщения, связанные с меню меню. Это достигается с помощью WM_INITMENU для очистки флага, который сообщает контейнеру, перейдет ли пользователь в меню справки объекта. Затем контейнер просматривает WM_MENUSELECT для входа или выхода из любого элемента в меню справки , которое контейнер не добавил. При входе пользователь переходит в меню объектов, поэтому контейнер задает флаг "в меню справки объекта" и использует состояние этого флага для пересылки всех WM_MENUSELECT, WM_INITMENUPOPUP и WM_COMMAND сообщений как минимум в окно объекта. (При выходе контейнер очищает флаг, а затем обрабатывает эти же сообщения.) Контейнер должен использовать окно, возвращаемое из функции объекта IOleInPlaceActiveObejct::GetWindow в качестве назначения для этих сообщений.

Если объект обнаруживает ноль в шестом элементе OLEMENUGROUPWIDTHS, он продолжается в соответствии с обычными правилами OLE Documents. Эта процедура охватывает контейнеры, которые участвуют в слиянии меню справки , а также те, которые не выполняются.

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

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

См. также

Контейнеры активных документов