Обзор интерфейса IDispatch OLE
Интерфейс IDispatch — средства, какие приложения expose методы и свойства такие другие приложения, такие как Visual BASIC и других языках, может заставить использовать функций приложения. Наиболее важной частью этого интерфейса является функция IDispatch::Invoke . MFC использует «направить карты» для реализации IDispatch::Invoke. Схеме диспетчеризации обеспечивает сведения о реализации MFC на макет или «форму» CCmdTarget-производным классам, что она может непосредственно управлять свойствами объекта, или вызывать функции в пределах объекта для удовлетворения запросов на IDispatch::Invoke -члены.
По большей части ClassWizard и MFC сотрудничать для скрытия большинство деталей OLE-автоматизации от прикладной программист. Программист концентрируется на фактического функциональность для показа в приложения и не нужно беспокоиться о базовой сантехника.
Бывают случаи, когда это нужно понимать, что делает MFC за кулисами. Эта записка будет заниматься как рамки присваивает Идентификатор DISPIDs свойства и функции-члены. Алгоритм, используемый MFC для назначения идентификаторов DISPIDs необходимо знание только когда вам необходимо знать идентификаторы, например, при создании библиотеки"типов" для объектов вашего приложения.
Назначение идентификаторов DISPID MFC
Хотя конечного пользователя автоматизации (Visual Basic пользователя, к примеру), видит фактические имена автоматизации позволили свойства и методы в коде (например obj.ShowWindow), осуществление IDispatch::Invoke не получает действительные имена. В целях оптимизации он получает Идентификатор DISPID, который является 32-разрядной "Волшебный cookie", описывающий метод или свойство, который должен получить доступ. Эти значения идентификатора DISPID возвращаются от реализации IDispatch другой метод, называемый IDispatch::GetIDsOfNames. Приложение клиента автоматизации вызовите GetIDsOfNames один раз для каждого члена или свойства, которые он намеревается получить доступ и кэшировать их для последующих вызовов для IDispatch::Invoke. Таким образом, дорогих строки поиска выполняется только один раз за использование объекта, вместо того, один раз в IDispatch::Invoke звонок.
MFC определяет Идентификатор DISPIDs для каждого метода и свойства, основанный на две вещи:
Идентификатор DISPID делится на две части. LOWORD DISPID содержит первый компонент, расстояние от верхней части схеме диспетчеризации. HIWORD содержит расстояние от самых производного класса. Например:
класс CDispPoint: государственные CCmdTarget
{
общественности:
nbsp; короткие m_x, m_y;
...
DECLARE_DISPATCH_MAP()
...
};
класс CDisp3DPoint: государственные CDispPoint
{
общественности:
короткие m_y;
...
DECLARE_DISPATCH_MAP()
...
};
BEGI&N_DISPATCH_MAP (CDispPoint, CCmdTarget)
DISP_PROPERTY (CDispPoint, «x», m_x, VT_I2)
DISP_PROPERTY (CDispPoint, «y», m_y, VT_I2)
END_DISPATCH_MAP()
BEGIN_DISPATCH_MAP (CDisp3DPoint, CDispPoint)
DISP_PROPERTY (CDisp3DPoint, «z», m_z, VT_I2)
END_DISPATCH_MAP()
Как вы можете видеть, существует два класса, оба из которых предоставляют интерфейсы автоматизации OLE. Один из этих классов является производным от другого и таким образом использует функциональность базового класса, включая часть автоматизации OLE («x» и «y» свойства в данном случае).
МФЦ будет генерировать s DISPIDдля класса CDispPoint следующим:
имущество X (DISPID) 0X00000001
свойства Y (DISPID) 0x00000002
Поскольку свойства, не в базовом классе, HIWORD DISPID всегда равен нулю (расстояние от самых производного класса для CDispPoint равно нулю).
МФЦ будет генерировать s DISPIDдля класса CDisp3DPoint следующим:
имущество Z (DISPID) 0X00000001
свойства X (DISPID) 0x00010001
свойства Y (DISPID) 0x00010002
Свойство z присваивается Идентификатор DISPID с нулевой HIWORD так, как оно определено в классе, который предоставление свойств, CDisp3DPoint. Так как в базовом классе определены свойства x и Y, HIWORD DISPID — 1, так как класс, в котором определены эти свойства находится на расстоянии одного наследования из самых производного класса.
Примечаниеnbsp;LOWORD всегда определяется позицией на карте, даже если существуют записи в схеме с явной DISPID (см. следующий раздел информацию о версиях _ID макросов DISP_PROPERTY и DISP_FU&NCTION ).
Дополнительные возможности карты диспетчеризации MFC
Существует ряд дополнительных функций, которые ClassWizard не поддерживаются в этой версии Visual C++. ClassWizard поддерживает DISP_FUNCTION, DISP_PROPERTYи DISP_PROPERTY_EX , которые определяют метод, свойство переменной члена и свойство члена функции get и set, соответственно. Эти возможности, как правило, все, что нужно для создания большинства автоматизации серверов.
Следующие дополнительные макросы могут использоваться при ClassWizard поддерживает макросы не являются адекватными: DISP_PROPERTY_NOTIFYи DISP_PROPERTY_PARAM.
DISP_PROPERTY_NOTIFY — Описание макроса
DISP_PROPERTY_NOTIFY (theClass, pszName, memberName, pfnAfterSet, vtPropType)
theClass
Имя класса.
pszName
Внешнее имя свойства.
memberName
Имя переменной-члена, в котором хранится свойство.
pfnAfterSet
Имя функции-члена для вызова при изменении свойства.
vtPropType
Значение, определяющее тип свойства.
Примечаниеnbsp; Этот макрос так же, как DISP_PROPERTY, за исключением того, что он принимает дополнительный аргумент. Дополнительный аргумент, pfnAfterSet, должно быть, ничего не возвращает и не принимает параметров, 'void OnProperty&Notify()' функция-член. Он будет вызываться после модификации переменная-член.
DISP_PROPERTY_PARAM — Описание макроса
DISP_PROPERTY_PARAM (theClass, pszName, pfnGet, pfnSet, vtPropType, vtsParams)
theClass
Имя класса.
pszName
Внешнее имя свойства.
memberGet
Имя функции-члена для получения свойства.
набор членов
Имя функции-члена, используется для задания свойства.
vtPropType
Значение, определяющее тип свойства.
vtsParams
Строка пространства разделены VTS_ для каждого параметра.
Примечание Многое как макрос DISP_PROPERTY_EX , этот макрос определяет свойство доступ с отдельных функций-членов Get и Set. Этот макрос, однако, позволяет указать список параметров для свойства. Это полезно для реализации свойств, которые индексируются или параметризованные иным способом. Параметры всегда попадут во-первых, после чего новое значение для свойства. Например:
DISP_PROPERTY_PARAM (CMyObject, «пункт», GetItem, SetItem, VT_DISPATCH, VTS_I2 VTS_I2)
будет соответствовать для получения и задания функций-членов:
LPDISPATCH CMyObject::GetItem(short row, short col)
void CMyObject::SetItem (короткие строки, короткие col, LPDISPATCH newValue)
DISP_XXXX_ID — Описания макросов
DISP_FUNCTION_ID (theClass, pszName, dispid, pfnMember, vtRetVal, vtsParams)
DISP_PROPERTY_ID (theClass, pszName, dispid, memberName, vtPropType)
DISP_PROPERTY_NOTIFY_ID (theClass, pszName, dispid, memberName, pfnAfterSet, vtPropType)
DISP_PROPERTY_EX_ID (theClass, pszName, dispid, pfnGet, pfnSet, vtPropType)
DISP_PROPERTY_PARAM_ID (theClass, pszName, dispid, pfnGet, pfnSet, vtPropType, vtsParams)
theClass
Имя класса.
pszName
Внешнее имя свойства.
dispid
Фиксированная DISPID для свойства или метода.
pfnGet
Имя функции-члена для получения свойства.
pfnSet
Имя функции-члена, используется для задания свойства.
memberName
Имя переменной-члена для сопоставления свойства
vtPropType
Значение, определяющее тип свойства.
vtsParams
Строка пространства разделены VTS_ для каждого параметра.
Примечаниеnbsp; Эти макросы позволяют указывать Идентификатор DISPID вместо того, чтобы дать MFC автоматически назначить один. Эти дополнительные макросы имеют те же имена, за исключением того, что ID добавляется к имени макроса (например DISP_PROPERTY_ID) и ID определяется параметр, указанный сразу после параметра psz&Name . Смотрите AFXDISP.H для получения дополнительной информации об этих макросов. _ID записи должны быть расположены в конце схеме диспетчеризации. Они будут влиять на автоматическое создание идентификаторов DISPID так же, как не -_ID версии макроса будет ( DISPIDs, определяются позиции). Например:
BEGI&N_DISPATCH_MAP (CDisp3DPoint, CCmdTarget)
nbsp; DISP_PROPERTY (CDisp3DPoint, «y», m_y, VT_I2)
DISP_PROPERTY (CDisp3DPoint, «z», m_z, VT_I2)
DISP_PROPERTY_ID (CDisp3DPoint, «x», 0x00020003, m_x, VT_I2)
END_DISPATCH_MAP()
МФЦ будет создавать идентификаторы DISPID для класса CDisp3DPoint следующим:
имущество X (DISPID) 0X00020003
свойства Y (DISPID) 0x00000002
свойства Z (DISPID) 0x00000001
Указание фиксированного DISPID полезен для сохранения обратной совместимости для ранее существовавших интерфейс диспетчера или для реализации определенных системы определены методы или свойства (обычно указывается отрицательное DISPID, такие как сбор DISPID_NEWENUM ).
Извлечение интерфейса IDispatch для COleClientItem
Многие серверы будет оказывать поддержку автоматизации в рамках их объектов документа, вместе с функциональность сервера OLE. Для того чтобы получить доступ к данному интерфейсу автоматизации, это необходимо для прямого доступа к переменной-члена COleClientItem::m_lpObject . Приведенный ниже код извлечет интерфейса IDispatch для объекта, производного от COleClientItem. Можно включить приведенный ниже код в приложение, если вы нашли эту функциональность необходимую
LPDISPATCH CMyClientItem::GetIDispatch()
{
nbsp; ASSERT_VALID(this);
ASSERT (m_lpObject! = NULL);
LPUNKNOWN lpUnk = m_lpObject;
Run(); / / должна быть запущена
LPOLELINK lpOleLink = NULL;
Если (m_lpObject - > QueryInterface (IID_IOleLink, (LPVOID FAR *) & lpOleLink) == NOERROR)
{
ASSERT (lpOleLink! = NULL);
lpUnk = NULL;
Если (lpOleLink - > GetBoundSource(&lpUnk)! = NOERROR)
{
TRACE0 ("предупреждение: ссылка не подключен! \n");
lpOleLink - > Release();
возвращение NULL;
}
ASSERT (lpUnk! = NULL);
}
LPDISPATCH lpDispatch = NULL;
Если (lpUnk - > QueryInterface (IID_IDispatch & lpDispatch)! = NOERROR)
{
TRACE0 ("предупреждение: не поддерживает IDispatch! \n");
возвращение NULL;
}
ASSERT (lpDispatch! = NULL);
возвращение lpDispatch;
}
Интерфейс диспетчера вернулся из этой функции может затем использоваться напрямую или к COleDispatchDriver для типизированного доступа. Если вы используете его напрямую, убедитесь, что вы называете его релиза -членов когда через с указателем (деструктор COleDispatchDriver делает это по умолчанию).
Технические примечания по номеру |nbsp; Технические примечания по категориям