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


TN040. Изменение размеров и масштабирование MFC/OLE по месту

Примечание.

Следующее техническое примечание не было обновлено, поскольку сначала оно было включено в электронную документацию. В результате некоторые процедуры и разделы могут быть устаревшими или неверными. Для получения последних сведений рекомендуется выполнить поиск интересующей темы в алфавитном указателе документации в Интернете.

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

Из-за тесного взаимодействия между контейнером и сервером, поддерживающим активацию на месте, есть ряд ожиданий от конечного пользователя, которые должны поддерживаться:

  • Отображение презентации (метафайла, нарисованного в COleServerItem::OnDraw переопределении) должно выглядеть точно так же, как при рисовании для редактирования (за исключением того, что средства редактирования не отображаются).

  • Когда контейнер увеличивает масштаб, окно сервера тоже должно быть!

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

Примечание.

Так как активация на месте применяется только к элементам, внедренным (не связанным), масштабирование применяется только к внедренным объектам. Вы увидите ИНТЕРФЕЙСы API в обоих COleServerDoc и COleServerItem используемых для масштабирования. Причина этого дихотомии заключается в COleServerItem том, что только функции, допустимые как для связанных, так и внедренных элементов (это позволяет иметь общую реализацию) и функции, допустимые только для внедренных объектов, находятся в COleServerDoc классе (с точки зрения сервера это документ, внедренный).

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

Поддержка MFC для масштабирования

Текущий коэффициент масштабирования можно определить путем вызова COleServerDoc::GetZoomFactor. Вызов этого, если документ не активен на месте, всегда приведет к коэффициенту масштабирования 100 % (или коэффициенту 1:1). При вызове в то время как активный может возвращать что-то другое, чем 100%.

Пример масштабирования см. в примере OLE MFC HIERSVR. Масштабирование в HIERSVR усложняется тем фактом, что он отображает текст и текст, в целом, не масштабируется в линейной форме (намеки, типографические соглашения, ширины дизайна и высоты все усложняют вопрос). Тем не менее, HIERSVR является разумной ссылкой на реализацию масштабирования правильно, поэтому это руководство по MFC SCRIBBLE (шаг 7).

COleServerDoc::GetZoomFactor определяет коэффициент масштабирования на основе ряда различных метрик, доступных из контейнера или из реализации ваших COleServerItem и COleServerDoc классов. Короче говоря, текущий коэффициент масштабирования определяется следующей формулой:

Position Rectangle (PR) / Container Extent (CE)

Объект POSITION RECTANGLE определяется контейнером. Он возвращается серверу во время активации на месте при COleClientItem::OnGetItemPosition вызове и обновляется, когда контейнер вызывает сервер COleServerDoc::OnSetItemRects (с вызовом COleClientItem::SetItemRects).

СТЕПЕНЬ КОНТЕЙНЕРА немного сложнее вычислять. Если контейнер вызывается COleServerItem::OnSetExtent (с вызовом COleClientItem::SetExtent), то значение CONTAINER EXTENT преобразуется в пиксели на основе количества пикселей на логический дюйм. Если контейнер не вызывает SetExtent (как правило, это так), то контейнер ЭКСТЕНТ — это размер, возвращаемый из COleServerItem::OnGetExtent. Таким образом, если контейнер не вызывает SetExtent, платформа предполагает, что если контейнер вызвал бы его с 100% от естественной экстенты (значение, возвращаемое из COleServerItem::GetExtent). Другой способ, платформа предполагает, что контейнер отображает 100 % (не больше, не меньше) элемента.

Важно отметить, что хотя COleServerItem::OnSetExtent и COleServerItem::OnGetExtent имеют аналогичные имена, они не управляют тем же атрибутом элемента. OnSetExtent вызывается, чтобы сообщить серверу, сколько объектов отображается в контейнере (независимо от коэффициента масштабирования) и OnGetExtent вызывается контейнером для определения идеального размера объекта.

Просмотрев каждый из участвующих API, вы можете получить более четкое изображение:

COleServerItem::OnGetExtent

Эта функция должна возвращать "естественный размер" в единицах HIMETRIC элемента. Лучший способ думать о "естественном размере" — определить его как размер, который он может появиться при печати. Возвращаемый здесь размер является константой для определенного содержимого элемента (так же, как метафайл, который является константой для определенного элемента). Этот размер не изменяется при применении масштабирования к элементу. Обычно он не изменяется, когда контейнер предоставляет элементу больше или меньше места путем вызова OnSetExtent. Примером изменения может быть простой текстовый редактор без возможности "поля", которая упаковала текст на основе последней степени, отправленной контейнером. Если сервер изменится, сервер, вероятно, должен задать OLEMISC_RECOMPOSEONRESIZE бит в системном реестре (дополнительные сведения об этом параметре см. в документации по пакету SDK OLE).

COleServerItem::OnSetExtent

Эта функция вызывается, когда контейнер отображает "больше или меньше" объекта. Большинство контейнеров вообще этого не вызывает. Реализация по умолчанию сохраняет последнее значение, полученное из контейнера в m_sizeExtent, которое используется при COleServerDoc::GetZoomFactor вычислении значения CONTAINER EXTENT, описанного выше.

COleServerDoc::OnSetItemRects

Эта функция вызывается только в том случае, если документ активен на месте. Он вызывается, когда контейнер обновляет положение элемента или вырезку, примененную к элементу. Функция POSITION RECTANGLE, как описано выше, предоставляет числитель для вычисления коэффициента масштабирования. Сервер может запросить изменение позиции элемента путем вызова COleServerDoc::RequestPositionChange. Контейнер может или не отвечать на этот запрос путем вызова (с вызовом OnSetItemRects COleServerItem::SetItemRects).

COleServerDoc::OnDraw

Важно понимать, что метафайл, созданный путем переопределения COleServerItem::OnDraw создания одного метафайла, независимо от текущего коэффициента масштабирования. Контейнер будет масштабировать метафайл соответствующим образом. Это важное различие между представлением OnDraw и элементом OnDrawсервера. Представление обрабатывает масштабирование, элемент просто создает масштабируемый метафайл и оставляет его до контейнера, чтобы сделать соответствующее масштабирование.

Лучший способ убедиться, что ваш сервер работает правильно, — использовать реализацию COleServerDoc::GetZoomFactor , если документ активен на месте.

Поддержка MFC для изменения размера на месте

MFC полностью реализует интерфейс изменения размера на месте, как описано в спецификации OLE 2. Пользовательский интерфейс поддерживается классом, пользовательским сообщением COleResizeBar WM_SIZECHILD и специальной обработкой этого сообщения.COleIPFrameWnd

Может потребоваться реализовать другую обработку этого сообщения, отличного от того, что предоставляется платформой. Как описано выше, платформа оставляет результаты изменения размера на месте до контейнера— сервер реагирует на изменение коэффициента масштабирования. Если контейнер реагирует, задав как КОНТЕЙНЕР ЭКСТЕНТ, так и ПОЛОЖЕНИЕ RECTANGLE во время обработки его COleClientItem::OnChangeItemPosition (вызываемого в результате вызова COleServerDoc::RequestPositionChange), то размер на месте приведет к отображению элемента в окне редактирования "больше или меньше". Если контейнер реагирует, просто задав позицию RECTANGLE во время обработки COleClientItem::OnChangeItemPosition, коэффициент масштабирования изменится, и элемент будет отображаться как "увеличить или вывести".

Сервер может контролировать (в некоторой степени) то, что происходит во время этого согласования. Например, электронная таблица может отображать больше или меньше ячеек, когда пользователь изменяет размер окна при редактировании элемента на месте. Обработчик слов может выбрать изменение полей страницы, чтобы они совпадали с окном и перезаписывали текст на новое поле. Серверы реализуют это путем изменения естественной экстенты (возвращаемого из COleServerItem::OnGetExtent) при выполнении изменения размера. Это приведет к тому, что как ПОЛОЖЕНИЕ RECTANGLE, так и СТЕПЕНЬ КОНТЕЙНЕРА изменяются на один и тот же объем, что приводит к тому же коэффициенту масштабирования, но больше или меньшей области просмотра. Кроме того, более или менее документ будет отображаться в метафайле, созданном с помощью OnDraw. В этом случае сам документ изменяется, когда пользователь изменяет размер элемента, а не только область просмотра.

Вы можете реализовать пользовательское изменение размера и по-прежнему использовать пользовательский интерфейс, COleResizeBar используя переопределение сообщения WM_SIZECHILD в COleIPFrameWnd классе. Дополнительные сведения о специфике WM_SIZECHILD см . в техническом примечание 24.

См. также

Технические примечания по номеру
Технические примечания по категории