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


Предоставление активации без окна

Код создания окна (то есть все, что происходит при вызове CreateWindow) является дорогостоящим для выполнения. Элемент управления, который поддерживает окно на экране, должен управлять сообщениями для окна. Поэтому элементы управления без окон быстрее, чем элементы управления с окнами.

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

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

Так как элементы управления без окон не имеют собственных окон, контейнер (у которого есть окно), отвечает за предоставление служб, которые в противном случае были предоставлены собственным окном элемента управления. Например, если элемент управления должен запрашивать фокус клавиатуры, записывать мышь или получать контекст устройства, эти операции управляются контейнером. Контейнер направляет пользовательские входные сообщения, отправленные в его окно, в соответствующий элемент управления без окон с помощью IOleInPlaceObjectWindowless интерфейса. (См. раздел Пакет SDK ActiveX для описания этого интерфейса.) COleControl функции-члены вызывают эти службы из контейнера.

Чтобы сделать элемент управления использовать активацию без окон, включите флаг windowlessActivate в набор флагов, возвращаемых COleControl::GetControlFlags. Например:

DWORD CMyAxOptCtrl::GetControlFlags()
{
   DWORD dwFlags = COleControl::GetControlFlags();
// The control can activate without creating a window.
dwFlags |= windowlessActivate;
return dwFlags;
}

Код для включения этого флага создается автоматически при выборе параметра активации без окон на странице "Элемент управления Параметры" мастера элементов управления MFC ActiveX.

Если активация без окон включена, контейнер будет делегировать входные сообщения интерфейсу элемента управления IOleInPlaceObjectWindowless . COleControlРеализация этого интерфейса отправляет сообщения через карту сообщений элемента управления после настройки координат мыши соответствующим образом. Вы можете обработать такие сообщения, как обычные сообщения окна, добавив соответствующие записи в карту сообщений. В обработчиках этих сообщений не используйте переменную члена m_hWnd (или любую функцию-член, которая использует ее) без первого проверка, что его значение не равно NULL.

COleControl предоставляет функции-члены, которые вызывают захват мыши, фокус клавиатуры, прокрутку и другие службы окон из контейнера, в том числе:

В элементах управления без окон всегда следует использовать COleControl функции-члены вместо соответствующих CWnd функций-членов или связанных функций API Win32.

Может потребоваться, чтобы элемент управления без окна был целевым объектом операции перетаскивания OLE. Как правило, для этого потребуется, чтобы окно элемента управления было зарегистрировано в качестве целевого объекта удаления. Так как элемент управления не имеет собственного окна, контейнер использует собственное окно в качестве целевого объекта удаления. Элемент управления предоставляет реализацию IDropTarget интерфейса, которому контейнер может делегировать вызовы в соответствующее время. Чтобы предоставить этот интерфейс контейнеру, переопределите COleControl::GetWindowlessDropTarget. Например:

IDropTarget* CMyAxOptCtrl::GetWindowlessDropTarget()
{
   m_DropTarget.m_xDropTarget.AddRef();
   return &m_DropTarget.m_xDropTarget;
}

См. также

Элементы ActiveX в MFC. Оптимизация