Стояла задача в RichEdit вставить ActiveX ("SendFile"), при клике на нем приложение получает событие...
ActiveX был написан на ATL, имеет событийный интерфейс _ISendFileAX_ATLCtrlEvents, и лежит в dll
Сервер вроде отлажен, т.к. уже долгое время используется в MFC клиенте.
Теперь же возникла необходимость вставить его в WTL-ный проект.
Делаю так:
Создаю sink класс:
class CMySink
: public CComObjectRootEx<CComSingleThreadModel>
, public CComCoClass<CMySink>
, public IDispEventImpl<0, CMySink, &__uuidof(ISendFileAX_ATLCtrlPtr)>
{
public:
CMySink() {}
~CMySink(){}
BEGIN_COM_MAP(CMySink)
COM_INTERFACE_ENTRY_IID(__uuidof(ISendFileAX_ATLCtrlPtr), CMySink)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
DECLARE_NOT_AGGREGATABLE(CMySink)
DECLARE_NO_REGISTRY()
BEGIN_SINK_MAP(CMySink)
SINK_ENTRY_INFO(0, __uuidof(ISendFileAX_ATLCtrlPtr), 0x1, OnClickToLink, infoOnDataReady())
END_SINK_MAP()
static _ATL_FUNC_INFO* infoOnDataReady()
{
static _ATL_FUNC_INFO _infoOnDataReady = {CC_STDCALL, VT_I4, 2, { VT_I1, VT_I4 } };
return &_infoOnDataReady;
}
HRESULT OnClickToLink(BYTE Link,ULONG ulID)
{
MessageBox(NULL, _T("Text"), _T("Message"), MB_OK);
return TRUE;
}
};
Имеется класс отнаследованный от RichEdit:
class GUI_ELEM_API CRichEditTS
: public CWindowImpl<CRichEditTS, CRichEditCtrl, CControlWinTraits>
{
public:
DECLARE_WND_SUPERCLASS(NULL, CRichEditCtrl::GetWndClassName())
CRichEditTS();
CRichEditTS(__packet *);
~CRichEditTS();
typedef struct tagOLEItem
{
tagOLEItem()
{
m_lpSendFileAX = NULL;
m_dwCookie = 0;
m_ulID = 0;
}
ISendFileAX_ATLCtrlPtr m_lpSendFileAX;
DWORD m_dwCookie;
ULONG m_ulID;
HMODULE m_hModule;
}OLEItem;
.
.
.
protected:
CComObject<CMySink> *m_pSink;
std::vector<OLEItem> m_OLEItems;
.
.
.
HRESULT LoadInterface(LPOLESTR szLibraryName,REFCLSID clsid, REFIID riid, void** ppvObj);
HRESULT InsertSendFile(...);
.
.
.
}
И пытаюсь подписаться на собитие:
HRESULT CRichEditTS::InsertSendFile(...)
{
HRESULT hr=S_OK;
OLEItem Item;
.
.
.
hr = LoadInterface(T2OLE((LPTSTR)czPath.c_str()),CLSID_SendFileAX_ATLCtrl, IID_ISendFileAX_ATLCtrl, (void**)&Item.m_lpSendFileAX);
hr = CComObject<CMySink>::CreateInstance(&m_pSink); // здесь hr = E_OUTOFMEMORY и m_pSink = NULL
m_pSink->AddRef();
hr = m_pSink->DispEventAdvise(Item.m_lpSendFileAX);
.
.
.
}
Подскажите, что я делаю не так...
Делал по статьям:
http://www.rsdn.ru/article/qna/com/comevents.xmlАвтор(ы): Владислав Чистяков
http://rsdn.ru/Forum/?mid=84939Автор: Vi2
Дата: 14.08.02