Click here to Skip to main content
15,884,809 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
JokeThe monkeys do it! Pin
Rajesh R Subramanian11-Jun-09 2:12
professionalRajesh R Subramanian11-Jun-09 2:12 
GeneralRe: module name Pin
ali kanju11-Jun-09 1:45
ali kanju11-Jun-09 1:45 
AnswerRe: module name Pin
Hamid_RT11-Jun-09 1:40
Hamid_RT11-Jun-09 1:40 
AnswerRe: module name Pin
CPallini11-Jun-09 1:41
mveCPallini11-Jun-09 1:41 
GeneralRe: module name Pin
ali kanju11-Jun-09 1:52
ali kanju11-Jun-09 1:52 
GeneralRe: module name Pin
CPallini11-Jun-09 2:04
mveCPallini11-Jun-09 2:04 
GeneralRe: module name Pin
ali kanju11-Jun-09 2:12
ali kanju11-Jun-09 2:12 
QuestionEvent sink for event raised by managed code component. Pin
Keith Sheppard11-Jun-09 0:51
Keith Sheppard11-Jun-09 0:51 
I'm not sure whether this is the right place to ask. I am having difficulty trying to handle, in a conventional (unmanaged code) C++ application, an event raised by a managed code component.

I am tackling this as a C++ problem because I can successfully handle the same event, from the same component, in a VB6 application.

The component raising the event is implemented in C# and enclosed in a COM wrapper. On the C# side we have the following code:

      public interface IMyObjectEvents
      {   [DispId(1)] void TakenFocus();      }
      public class MyObjectInterface : IMyObject
      {
            public event TakenFocusDelegate TakenFocus;
            public void FireTakenFocus()
            {
                  if (TakenFocus != null)   TakenFocus();
            }
      }

The following code in an unmanaged VB6 application works fine:

      Dim WithEvents oMyControl As MyControl.MyObjectInterface

      Private Sub oMyControl_TakenFocus()
            MsgBox "Event caught"
      End Sub

When the object calls FireTakenFocus(), I see the messagebox "Event caught"

In C++ it all gets a bit harder. My code is in an MFC dll. I created a new class CEventSink as follows:

In the header file:
      class CEventSink : public CCmdTarget
      {
     DECLARE_DYNCREATE(CEventSink)
     CEventSink();               // protected constructor used by dynamic creation

      // Attributes
      public:

      // Operations
      public:
     void Connect(LPUNKNOWN lpuEventSource);
     void Disconnect();
     void OnTakenFocus();

      // Overrides
     // ClassWizard generated virtual function overrides
     //{{AFX_VIRTUAL(CEventSink)
     public:
     virtual void OnFinalRelease();
     //}}AFX_VIRTUAL

      // Implementation
      protected:
     virtual ~CEventSink();

     // Generated message map functions
     //{{AFX_MSG(CEventSink)
          // NOTE - the ClassWizard will add and remove member functions here.
     //}}AFX_MSG

     DECLARE_MESSAGE_MAP()
     // Generated OLE dispatch map functions
     //{{AFX_DISPATCH(CEventSink)
          // NOTE - the ClassWizard will add and remove member functions here.
     //}}AFX_DISPATCH
     DECLARE_DISPATCH_MAP()
     DECLARE_INTERFACE_MAP()

      private:
     DWORD m_dwEventSinkHandle;
     LPUNKNOWN m_puEventSource;
      };

Then the implementation in the cpp file:

      IMPLEMENT_DYNCREATE(CEventSink, CCmdTarget)

      CEventSink::CEventSink()
      {
     EnableAutomation();
     m_puEventSource = NULL;
      }

      CEventSink::~CEventSink()
      {
     Disconnect();
      }

      void CEventSink::OnFinalRelease()
      {
     CCmdTarget::OnFinalRelease();
      }

      BEGIN_MESSAGE_MAP(CEventSink, CCmdTarget)
     //{{AFX_MSG_MAP(CEventSink)
          // NOTE - the ClassWizard will add and remove mapping macros here.
     //}}AFX_MSG_MAP
      END_MESSAGE_MAP()

      BEGIN_DISPATCH_MAP(CEventSink, CCmdTarget)
     //{{AFX_DISPATCH_MAP(CEventSink)
          DISP_FUNCTION_ID(CEventSink, "TakenFocus", 1, OnTakenFocus, VT_EMPTY, VTS_NONE)
     //}}AFX_DISPATCH_MAP
      END_DISPATCH_MAP()

      // {B0FD7D1F-6686-44B3-A040-A2BF4E37DA30}
      static const IID IID_IEventSink =
      { 0xb0fd7d1f, 0x6686, 0x44b3, { 0xa0, 0x40, 0xa2, 0xbf, 0x4e, 0x37, 0xda, 0x30 } };

      // {0C4298D9-7CEC-46D6-A865-79204E29557D}
      static const IID IID_IMyObjectEvents =
      { 0x0c4298d9, 0x7cec, 0x46d6, { 0xA8, 0x65, 0x79, 0x20, 0x4e, 0x29, 0x55, 0x7D } };

      BEGIN_INTERFACE_MAP(CEventSink, CCmdTarget)
     INTERFACE_PART(CEventSink, IID_IMyObjectEvents Dispatch)
      END_INTERFACE_MAP()

      void CEventSink::Connect(LPUNKNOWN lpuEventSource)
      {
     AfxConnectionAdvise(m_puEventSource = lpuEventSource, IID_IMyObjectEvents,
                                          GetIDispatch(FALSE), FALSE, &m_dwEventSinkHandle);
      }

      void CEventSink::Disconnect()
      {
     if (m_puEventSource != NULL)
     {
          AfxConnectionUnadvise(m_puEventSource, IID_IMyObjectEvents,
                                                         GetIDispatch(FALSE), FALSE, m_dwEventSinkHandle);
          m_puEventSource = NULL;
     }
      }

      void CEventSink::OnTakenFocus()
      {
     Trace("Event caught");
      }

In my startup code I create an instance of the C# object and of the event sink, and call Connect (error checking code omitted for brevity):
      IMyObjectPtr oMyObject;

      oMyObject.CreateInstance(clsidMyObjectInterface);
      CRuntimeClass *prtcEventSink = RUNTIME_CLASS(CEventSink);
      CEventSink *pSink = (CEventSink *)prtcEventSink->CreateObject();
      LPUNKNOWN pUnk;
      oMyObject.QueryInterface(IID_IUNKNOWN, &pUnk);
      pSink->Connect(pUnknown);

The connect works fine but as soon as my C# component calls FireTakenFocus I get a .net runtime error message:
      Member not found. Exception from HRESULT 0x8002003
      [DISPID_E_MEMBERNOTFOUND]

      (detail)
      ForwardCallToInvokeMember(String MemberName, BindingFlags Flags, Object Target,
                                             Int32[] aWrapperTypes, MessageData &msgData)

CEventSink::OnTakenFocus is never called.

Any suggestions where I'm going wrong? As I said, I'm sure the problem is on the C++ side of the fence because a VB6 app can field the event without batting an eyelid.

Keith
AnswerRe: Event sink for event raised by managed code component. Pin
Keith Sheppard11-Jun-09 1:57
Keith Sheppard11-Jun-09 1:57 
QuestionHIde a Process in Task manager Pin
tns_ranjith11-Jun-09 0:19
tns_ranjith11-Jun-09 0:19 
AnswerRe: HIde a Process in Task manager PinPopular
Rajesh R Subramanian11-Jun-09 0:21
professionalRajesh R Subramanian11-Jun-09 0:21 
GeneralRe: HIde a Process in Task manager Pin
tns_ranjith11-Jun-09 1:14
tns_ranjith11-Jun-09 1:14 
GeneralRe: HIde a Process in Task manager Pin
tns_ranjith11-Jun-09 1:14
tns_ranjith11-Jun-09 1:14 
GeneralRe: HIde a Process in Task manager Pin
Rajesh R Subramanian11-Jun-09 1:19
professionalRajesh R Subramanian11-Jun-09 1:19 
GeneralRe: HIde a Process in Task manager Pin
Cedric Moonen11-Jun-09 1:22
Cedric Moonen11-Jun-09 1:22 
AnswerRe: HIde a Process in Task manager Pin
Garth J Lancaster11-Jun-09 0:22
professionalGarth J Lancaster11-Jun-09 0:22 
GeneralRe: HIde a Process in Task manager Pin
tns_ranjith11-Jun-09 1:16
tns_ranjith11-Jun-09 1:16 
GeneralRe: HIde a Process in Task manager Pin
Garth J Lancaster11-Jun-09 1:24
professionalGarth J Lancaster11-Jun-09 1:24 
GeneralRe: HIde a Process in Task manager Pin
Chandrasekharan P11-Jun-09 2:03
Chandrasekharan P11-Jun-09 2:03 
GeneralRe: HIde a Process in Task manager Pin
Michael Schubert11-Jun-09 2:17
Michael Schubert11-Jun-09 2:17 
GeneralRe: HIde a Process in Task manager Pin
Garth J Lancaster11-Jun-09 11:44
professionalGarth J Lancaster11-Jun-09 11:44 
GeneralRe: HIde a Process in Task manager Pin
CPallini11-Jun-09 2:00
mveCPallini11-Jun-09 2:00 
QuestionDebug Assertion Failed Pin
Davitor10-Jun-09 23:52
Davitor10-Jun-09 23:52 
AnswerRe: Debug Assertion Failed Pin
Cedric Moonen11-Jun-09 0:14
Cedric Moonen11-Jun-09 0:14 
GeneralRe: Debug Assertion Failed Pin
Davitor11-Jun-09 0:33
Davitor11-Jun-09 0:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.