I created a control based on the DispServ ATL example. I want to extend it so that the client control is both a source for events as well as a receiver. I think I've done everything correctly but when I attempt to compile the client control, the compiler fails with the following:
------ Build started: Project: HandlerClient, Configuration: Debug Win32 ------
Compiling...
HandlerCtl.cppc:\program files\microsoft visual studio 8\vc\atlmfc\include\atlcom.h(1792) : error C2259: 'ATL::CComObject<Base>' : cannot instantiate abstract class
with
[
Base=CHandlerCtl
]
due to following members:
'HRESULT ATL::__EventHandlerProxy::__eventHandlerProxy(int,...)' : is abstract
c:\program files\microsoft visual studio 8\vc\atlmfc\include\atlevent.h(177) : see declaration of 'ATL::__EventHandlerProxy::__eventHandlerProxy'
c:\program files\microsoft visual studio 8\vc\atlmfc\include\atlcom.h(1781) : while compiling class template member function 'HRESULT ATL::CComCreator<T1>::CreateInstance(void *,const IID &,LPVOID *)'
with
[
T1=ATL::CComObject<CHandlerCtl>
]
c:\program files\microsoft visual studio 8\vc\atlmfc\include\atlcom.h(1872) : see reference to class template instantiation 'ATL::CComCreator<T1>' being compiled
with
[
T1=ATL::CComObject<CHandlerCtl>
]
c:\program files\microsoft visual studio 8\vc\atlmfc\include\atlcom.h(1868) : while compiling class template member function 'HRESULT ATL::CComCreator2<T1,T2>::CreateInstance(void *,const IID &,LPVOID *)'
with
[
T1=ATL::CComCreator<ATL::CComObject<CHandlerCtl>>,
T2=ATL::CComCreator<ATL::CComAggObject<CHandlerCtl>>
]
*c:\dna2\apps\temphandlercontroller\handlerclient\debug\handlerctl.inj:5(6) : see reference to class template instantiation 'ATL::CComCreator2<T1,T2>' being compiled
with
[
T1=ATL::CComCreator<ATL::CComObject<CHandlerCtl>>,
T2=ATL::CComCreator<ATL::CComAggObject<CHandlerCtl>>
]
Build log was saved at "file://c:\dna2\Apps\TempHandlerController\HandlerClient\Debug\BuildLog.htm"
HandlerClient - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Furthermore, If I attempt to add methods to my client control event interface, the compiler complains that they are undefined but they're not. They're implemented within the class definition. Also, adding events to the client control method interface results in them being declared as unimplmented abstract methods even though they too are implemented within the class declaration in the CClientCtl.h file.
Is it incorrect to try to have a control that has both event_receiver(com) and event_source(com) declared
Help! - spd3001

COM Events
Vincent D. - Nolme Informatique
This forum is for general C++ compiler and IDE issues. For Win32 programming issues, please post your question in one of the MSDN discussion groups. In particular:
http://msdn.microsoft.com/newsgroups/default.aspx dg=microsoft.public.win32.programmer.ole&lang=en&cr=US
BCras
Here's the client code that won't compile. Everything else is just like the DispSink example except for the necessary corrections (check attributes box for server and client as it's not really the default). The sample project can be found at :
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_vclib/html/6c3d27a6-80d3-4a80-833c-aa8b19487632.htm
**********************************************
// MyDispCtl.h : Declaration of the CMyDispCtl
#pragma
once#include
"resource.h" // main symbols#include
<atlctl.h>#import
"progid:MyDispServer.MyDispServ.1" embedded_idl, no_namespace#if
defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif
// IMyDispCtl
[
object,
uuid(787EDBCA-7FA3-4375-9214-A4C3979AA6F0),
dual,
helpstring(
"IMyDispCtl Interface"),pointer_default(unique)
]
__interface
IMyDispCtl : public IDispatch{
[id(1), helpstring(
"method Connect")] HRESULT Connect();[id(2), helpstring(
"method Disconnect")] HRESULT Disconnect();[id(3), helpstring(
"method Send")] HRESULT Send(VARIANT data);};
// _IMyDispCtlEvents
[
uuid(
"FDA3A9A2-FD09-458D-A360-8DECD4186B89"),dispinterface,
helpstring(
"_IMyDispCtlEvents Interface")]
__interface
_IMyDispCtlEvents{
};
// CMyDispCtl
[
coclass,
control,
default(IMyDispCtl, _IMyDispCtlEvents),threading(single),
vi_progid(
"MyDispClient.MyDispCtl"),progid(
"MyDispClient.MyDispCtl.1"),version(1.0),
uuid(
"8CE77369-8959-4FFE-8E83-DD8F7FC64C7E"),helpstring(
"MyDispCtl Class"),event_source(com),
registration_script(
"control.rgs"),event_receiver(com)
]
class
ATL_NO_VTABLE CMyDispCtl : public IMyDispCtl, public IPersistStreamInitImpl<CMyDispCtl>, public IOleControlImpl<CMyDispCtl>, public IOleObjectImpl<CMyDispCtl>, public IOleInPlaceActiveObjectImpl<CMyDispCtl>, public IViewObjectExImpl<CMyDispCtl>, public IOleInPlaceObjectWindowlessImpl<CMyDispCtl>,#ifndef
_WIN32_WCE public IDataObjectImpl<CMyDispCtl>,#endif
#ifdef
_WIN32_WCE // IObjectSafety is required on Windows CE for the control to be loaded correctlypublic IObjectSafetyImpl<CMyDispCtl, INTERFACESAFE_FOR_UNTRUSTED_CALLER>,
#endif
public CComControl<CMyDispCtl>{
public
:CMyDispCtl()
{
m_bConnected =
false;m_OutText = L
"Not connected";}
~CMyDispCtl()
{
Disconnect();
}
DECLARE_OLEMISC_STATUS(OLEMISC_RECOMPOSEONRESIZE |
OLEMISC_CANTLINKINSIDE |
OLEMISC_INSIDEOUT |
OLEMISC_ACTIVATEWHENVISIBLE |
OLEMISC_SETCLIENTSITEFIRST
)
BEGIN_PROP_MAP(CMyDispCtl)
PROP_DATA_ENTRY(
"_cx", m_sizeExtent.cx, VT_UI4)PROP_DATA_ENTRY(
"_cy", m_sizeExtent.cy, VT_UI4) // Example entries // PROP_ENTRY("Property Description", dispid, clsid) // PROP_PAGE(CLSID_StockColorPage)END_PROP_MAP()
BEGIN_MSG_MAP(CMyDispCtl)
CHAIN_MSG_MAP(CComControl<CMyDispCtl>)
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
// Handler prototypes:
// LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
// LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
// LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
__event __interface _IMyDispCtlEvents;// IViewObjectEx
DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)
// IMyDispCtl
public
:HRESULT OnDraw(ATL_DRAWINFO& di)
{
USES_CONVERSION;
LPCTSTR text = OLE2CT(m_OutText.bstrVal);
RECT& rc = *(RECT*)di.prcBounds;
Rectangle(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom);
SetTextAlign(di.hdcDraw, TA_CENTER|TA_BASELINE);
TextOut(di.hdcDraw,
(rc.left + rc.right) / 2,
(rc.top + rc.bottom) / 2,
text,
lstrlen(text));
return S_OK;}
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;}
void FinalRelease(){
}
private
: // Data bool m_bConnected;CComPtr<IMyDispServ> m_spIServ;
CComVariant m_OutText;
public
:HRESULT Connect()
{
HRESULT hr;
hr = m_spIServ.CoCreateInstance(
__uuidof(CMyDispServ)); if (SUCCEEDED(hr)){
hr =
__hook(&_IMyDispServEvents::Transfer, m_spIServ, &CMyDispCtl::OnTransmit);}
if (hr == S_OK){
m_bConnected =
true;m_OutText = L
"Connected";}
FireViewChange();
return(hr);}
HRESULT Disconnect()
{
if (m_bConnected){
HRESULT hr =
__unhook(&_IMyDispServEvents::Transfer, m_spIServ, &CMyDispCtl::OnTransmit); if (SUCCEEDED(hr)){
m_spIServ.Release();
m_bConnected =
false;m_OutText = L
"Not connected";}
FireViewChange();
return(hr);}
return(S_OK);}
HRESULT OnTransmit(VARIANT data)
{
if (data.vt == VT_BSTR)m_OutText = data;
FireViewChange();
return(S_OK);}
HRESULT Send(VARIANT data)
{
if (m_bConnected)m_spIServ->Send(data);
return(S_OK);}
};
Learning WPF