TN071: Реализация IOleCommandTarget в MFC
Примечание |
---|
Следующая техническая заметка не была обновлена со времени сначала была включена в подключенной документации.В результате некоторые процедуры и разделы могут оказаться устаревшей или неверны.Последние новости, рекомендуется поиск раздела процента в подключенном индексу документации. |
Интерфейс IOleCommandTarget включает объекты и их контейнеров к командам диспетчера друг к другу.Например, панель инструментов объекта могут содержать кнопки команд, как Печать, Предварительный просмотр, Сохранить, New и Масштаб.Если такой объект был внедрен в контейнере, который поддерживает IOleCommandTarget объект может включать его кнопки и команды переадресовать в контейнер для обработки, когда пользователь нажимает их.Если контейнер хотел внедренный объект печати, он может выполнить этот запрос, отправляя команда с помощью интерфейса IOleCommandTarget внедренного объекта.
IOleCommandTarget Автоматизация-как интерфейс, в нем используется клиентом для вызова методов на сервере.Однако использование IOleCommandTarget сохраняет издержки вызова через интерфейсы автоматизации, поскольку разработчики приложений обычно не следует использовать дорогий метод InvokeIDispatch.
В MFC, интерфейс IOleCommandTarget используемый серверами активного документа, чтобы разрешить контейнеров активных документов к командам отправки на сервер.Класс сервера активных документов, CDocObjectServerItem, использует сопоставление интерфейса MFC (см. TN038: реализация MFC/OLE IUnknown), чтобы реализовать интерфейс IOleCommandTarget.
IOleCommandTarget также реализуется в классе COleFrameHook.COleFrameHook недокументированный класс MFC, который реализует функциональность окна фрейма редактирования на месте контейнеры.COleFrameHook также использует сопоставления интерфейсов MFC для реализации интерфейса IOleCommandTarget.Реализация ###COleFrameHook IOleCommandTarget переадресует в COleDocObjectItem команды OLE, унаследованных от контейнеров активных документов.Это позволяет любой контейнер активных документов MFC, из которой нужно получать сообщения, содержащиеся сервера активных документов.
Сопоставления команд MFC OLE
Разработчики могут воспользоваться преимуществами MFC IOleCommandTarget с помощью сопоставления команд MFC OLE.Сопоставление команды OLE, как сопоставления сообщений, поскольку их можно было использовать для сопоставления команд в OLE функции-членам класса, который содержит сопоставление команды.Сделать этот работы, макросы размещения в сопоставлении команды для определения команды OLE группу в составе команды необходимо обработать, ЯВЛЯЕТСЯ команды и идентификатор группы сообщений WM_COMMAND, который будет отправлен, когда команда будет получена OLE.MFC также предоставляет несколько предопределенных макросов OLE для стандартных команд.Список стандартных команд OLE, которые изначально были предназначены для использования с приложениями Microsoft Office см. в разделе перечисление OLECMDID, которое определено в docobj.h.
При получении приложением MFC команда OLE, содержащий сопоставление команды OLE, MFC пытается найти группу идентификатор команды и команды OLE запрошенного в сопоставлении команды приложения.Если обнаружено совпадение, то сообщение отправляется WM_COMMAND приложению, содержащий сопоставление команды с идентификатором команды.(См. описание ниже) ON_OLECMD. Таким образом, посланные команды OLE приложению повернуты в сообщения WM_COMMAND MFC.Сообщения WM_COMMAND затем направляются через сопоставления сообщения приложения с помощью архитектуры MFC стандартную маршрутизация команд.
В отличие от сопоставления сообщения, сопоставления команд MFC OLE, не поддерживаются ClassWizard.Разработчики MFC необходимо добавить команды OLE записи сопоставления поддержки сопоставления и команды OLE вручную.Сопоставление команды OLE можно добавить к серверам активных документов MFC в любом классе, в цепочке сообщение-маршрутизации WM_COMMAND во время активного документа активную на месте в контейнере.Эти классы включают классы, производные от CWinApp приложения, CView, CDocument и COleIPFrameWnd.В контейнерах активного документа, ЯВЛЯЕТСЯ сопоставления команды можно добавлять только к COleDocObjectItem- производному классу.Также в контейнерах активного документа, WM_COMMAND сообщения отправляются только к сопоставлению в COleDocObjectItem- производный класс сообщений.
Макросы сопоставления команды OLE
Используйте следующие макросы для добавления функциональных возможностей сопоставления команды к классу:
DECLARE_OLECMD_MAP ()
Этот макрос переходит в объявление класса (обычно в файле заголовка) класса, который содержит сопоставление команды.
BEGIN_OLECMD_MAP(theClass, baseClass)
theClass
Имя класса, который содержит сопоставление команды.baseClass
Имя базового класса, содержащий сопоставление команды.
Этот макрос отмечает начало сопоставления команды.Используйте этот макрос в файле реализации класса, который содержит сопоставление команды.
END_OLECMD_MAP()
Этот макрос отмечает конец сопоставления команды.Используйте этот макрос в файле реализации класса, который содержит сопоставление команды.Этот макрос должен всегда следуйте BEGIN_OLECMD_MAP макроса.
ON_OLECMD(pguid, olecmdid, id)
pguid
Указатель на идентификатор GUID группы команд ЯВЛЯЕТСЯ команды.Этот параметр ЯВЛЯЕТСЯ NULL для стандартной группы команд.olecmdid
Идентификатор команды OLE вызывать.id
Идентификатор сообщения WM_COMMAND для отправки приложению, содержащий сопоставление команды OLE, когда эта команда будет инициировано.
Используйте макрос ON_OLECMD в сопоставлении команды для добавления записи для команды OLE необходимо обработать.Если команды OLE будут получены, они будут преобразованы к конкретному сообщению WM_COMMAND и направляются через сопоставление сообщений приложения, используя стандартную архитектуру команда-маршрутизации MFC.
Пример
В следующем примере показано, как добавить возможность OLE команда-регулируя на сервер активных документов MFC для обработки команды OLE OLECMDID_PRINT.В этом примере предполагается, что используется AppWizard для создания приложения MFC, сервер активных документов.
В CView- файл заголовка производного типа, добавляет макрос DECLARE_OLECMD_MAP к объявлению класса.
Примечание Используйте CView- производный класс, поскольку оно один из классов сервера активных документов, в цепочке сообщение-маршрутизации WM_COMMAND.
class CMyServerView : public CView { protected: // create from serialization only CMyServerView(); DECLARE_DYNCREATE(CMyServerView) DECLARE_OLECMD_MAP() . . . };
В файле реализации для CView- производный класс добавляет макрос BEGIN_OLECMD_MAP и END_OLECMD_MAP:
BEGIN_OLECMD_MAP(CMyServerView, CView) END_OLECMD_MAP()
Для обработки стандартную команду print OLE добавьте макрос ON_OLECMD к сопоставлению команды, указывающие, ЯВЛЯЕТСЯ идентификатор команды для стандартной команды печати и ID_FILE_PRINT для идентификатора WM_COMMANDID_FILE_PRINT стандартный идентификатор команды печати, используемое AppWizard-произведенными приложениями MFC:
BEGIN_OLECMD_MAP(CMyServerView, CView) ON_OLECMD(NULL,OLECMDID_PRINT,ID_FILE_PRINT) END_OLECMD_MAP()
Обратите внимание, что один из стандартных команды OLE макросов, определенное в afxdocob.h, может быть использовано вместо макроса ON_OLECMD поскольку стандартное OLECMDID_PRINT OLE идентификатор команды.Макрос ON_OLECMD_PRINT выполняет одну и ту же задачу в качестве макроса ON_OLECMD, показанный выше.
Если этот сервер контейнерное приложение отправляет команду OLECMDID_PRINT через интерфейс IOleCommandTarget сервера, обработчик команды печати MFC, будет вызван на сервере, что сервер печати приложение.Код контейнера активных документов для вызова команды на принтер, добавленную выше в шагах будет выглядеть примерно так:
void CContainerCntrItem::DoOleCmd()
{
IOleCommandTarget *pCmd = NULL;
HRESULT hr = E_FAIL;
OLECMD ocm={OLECMDID_PRINT, 0};
hr = m_lpObject->QueryInterface(IID_IOleCommandTarget,reinterpret_cast<void**>(&pCmd));
if(FAILED(hr))
return;
hr = pCmd->QueryStatus(NULL, 1, &ocm, NULL);
if(SUCCEEDED(hr) && (ocm.cmdf & OLECMDF_ENABLED))
{
//Command is available and enabled so call it
COleVariant vIn;
COleVariant vOut;
hr = pCmd->Exec(NULL, OLECMDID_PRINT,
OLECMDEXECOPT_DODEFAULT, &vIn, &vOut);
ASSERT(SUCCEEDED(hr));
}
pCmd->Release();
}