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. реализация метода COleFrameHookIOleCommandTarget переадресует OLE команды в COleDocObjectItem- производные контейнеров активных документов. При этом любой контейнер активных документов MFC для получения сообщения, который содержат сервера активных документов.
Сопоставления команды MFC OLE
Разработчики могут воспользоваться преимуществами MFC IOleCommandTarget с помощью сопоставлений команды MFC OLE. OLE сопоставления команды как сопоставления сообщений, поскольку они могут быть использованы для сопоставления OLE команды к функциям элемента класса, содержащий сопоставление команды. Сделать этот работы, макросы места в сопоставлении команды для определения OLE группу в составе команды команду необходимо обработать, OLE команды, и идентификатор группы сообщений WM_COMMAND, которое будет отправлена команда будет получена при OLE. MFC также предоставляет несколько предопределенных макросов OLE для стандартных команд. Для списка стандартных OLE команды, которые изначально были предназначены для использования в приложениях Microsoft Office см. перечисление OLECMDID, заданному в docobj.h.
Если команда OLE выполняется приложением MFC 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. В контейнерах активных документов, OLE сопоставления команды можно добавлять только к 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 группы команды OLE команды. Этот параметр NULL для стандартной OLE группы команд.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()
Для обработки стандартная OLE команду на принтер добавьте макрос ON_OLECMD для сопоставления команды OLE, содержащее идентификатор команды для стандартной команды на принтер и ID_FILE_PRINT для идентификатора WM_COMMAND ID_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();
}