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


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

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

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

Help

Container Help >

Object Help >

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

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. Эта процедура охватывает контейнеры, которые участвуют в слиянии меню Help, а также те, которые в нём не участвуют.

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

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

См. также

Активные контейнеры документов