?
Solved

Handling event in VC ++ raised by VB activeX exe

Posted on 2002-07-25
9
Medium Priority
?
664 Views
Last Modified: 2013-11-18
my problem is
I'll explain u in detail.:
I have a VB activeX exe which raises an event with a Recordset(of ADO) having some some records picked from the database. Now my requirement is to handle that raised event in a VC++ component. I cannot change that VB ActiveX exe as it part of the existing system which is raising this event to all other VB clients . I want to introduce a VC client which can also handle the same event.

I tried raising an event with VB activeX dll and handling in VC it is working fine but I am not been able to do the same with VB active X exe and handling it in VC.
Now if you can help me in this......
0
Comment
Question by:iamvikky
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
9 Comments
 
LVL 22

Expert Comment

by:ambience
ID: 7179283
how are you instantiating the exe ? how are you sinking the events ? can post some code
0
 
LVL 22

Accepted Solution

by:
ambience earned 2000 total points
ID: 7179288
there is a different way to sink Iunknown derived events and disp interface events, since your server is written in VB am sure it must be using dispinterfaces for event interfaces.

0
 

Author Comment

by:iamvikky
ID: 7179435
Hi ambience,

Yes since the server is wrriten in VB, , it is using dispinterfaces for event interfaces. Basically we are calling (from VC) the method (defined in the VB activex exe, which fires the event using RaiseEent statement). This causes the event to fire from VB. And this event is then supposed to be captured in VC. (this is working fine in case the vb component is a ActiveX DLL , but not in case if its a VB activeX exe). I am sending you the .IDL file.


///CODE FOR .IDL//////

// Generated .IDL file (by the OLE/COM Object Viewer)
//
// typelib filename: VBEvents.exe

[
  uuid(BB7B028D-7863-4916-8E21-CAFEF7AAF04E),
  version(18.0)
]
library VBEvents
{
    // TLib :     // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
    importlib("stdole2.tlb");

    // Forward declare all types defined in this typelib
    interface _clsEventSrc;
    dispinterface __clsEventSrc;

    [
      odl,
      uuid(F601C5AB-9FBB-11D6-BFA1-00034724F256),
      version(1.0),
      hidden,
      dual,
      nonextensible,
      oleautomation
    ]
    interface _clsEventSrc : IDispatch {
        [id(0x60030000)]
        HRESULT prcFireEvent();
    };

    [
      uuid(46F0E144-B78D-4912-A63F-AE7EFB7961CF),
      version(1.0)
    ]
    coclass clsEventSrc {
        [default] interface _clsEventSrc;
        [default, source] dispinterface __clsEventSrc;
    };

    [
        uuid(F601C5AC-9FBB-11D6-BFA1-00034724F256),
      version(1.0),
      hidden,
      nonextensible,       
    ]
    dispinterface __clsEventSrc {
        properties:
        methods:
            [id(0x00000001)]
            void evtNotify([in, out] BSTR* str);
    };
};

//////IDL CODE ENDS HERE///////////////

and  below is the part of code where we initilize the object and call the method from VB.

//-------->>>>>>>>  The initilization of class is done in On initdialog function using CoCreateInstance function.
      BOOL CMFCClientDlg::OnInitDialog()
      {
      CDialog::OnInitDialog();

      // Add "About..." menu item to system menu.

      // IDM_ABOUTBOX must be in the system command range.
      ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
      ASSERT(IDM_ABOUTBOX < 0xF000);

      CMenu* pSysMenu = GetSystemMenu(FALSE);
      if (pSysMenu != NULL)
      {
            CString strAboutMenu;
            strAboutMenu.LoadString(IDS_ABOUTBOX);
            if (!strAboutMenu.IsEmpty())
            {
                  pSysMenu->AppendMenu(MF_SEPARATOR);
                  pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
            }
      }

      // Set the icon for this dialog.  The framework does this automatically
      //  when the application's main window is not a dialog
      SetIcon(m_hIcon, TRUE);                  // Set big icon
      SetIcon(m_hIcon, FALSE);            // Set small icon
      
      // TODO: Add extra initialization here
      CoInitialize(NULL);
      /*Initialize COM system*/
      m_pSink=new MFCSink; /*create an instance of the sink object*/

      /*create source object*/
      HRESULT hr=CoCreateInstance(CLSID_clsEventSrc,NULL, CLSCTX_LOCAL_SERVER,IID_IDispatch,      
      (void**) &m_pSrc);
      LPUNKNOWN m_pUnk;
      if(SUCCEEDED(hr))
      m_pUnk=m_pSink->GetIDispatch(FALSE);
      if(SUCCEEDED(hr))
      {
      /*establish the connection*/

      if(AfxConnectionAdvise(m_pSrc,DIID___clsEventSrc,m_pUnk,FALSE,&m_dwCookie))
      return TRUE;
      else
      return FALSE;
      }
      else
      return FALSE;      
      }

      ------>>>>The function below is called when a button is pressed on client dlg.
      void CMFCClientDlg::OnButton1()
      void CMFCClientDlg::OnButton1()
      {      
            m_pSrc->prcFireEvent();
      
      }
       ----->>>>>and on calling the above function this is where the control goes(.TLI file):
      //
      // interface _clsEventSrc wrapper method implementations
      //

      inline HRESULT _clsEventSrc::prcFireEvent ( ) {
          HRESULT _hr = raw_prcFireEvent();
          if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
          return _hr;
      }

      //
      // dispinterface __clsEventSrc wrapper method implementations
      //

      inline HRESULT __clsEventSrc::evtNotify ( BSTR * str ) {
          return _com_dispatch_method(this, 0x1, DISPATCH_METHOD, VT_EMPTY, NULL,
              L"\x4008", str);
      }

      ---------->>>>>>> This is the method which is capturing the event raised from VB activex exe
      void MFCSink::evtNotify(BSTR str)
      {
      CString s;
            s = "Event notification handled in MFC client -- " + (CString)(LPCTSTR)str;
      AfxMessageBox(s);
      }

      ====>>>>And Below is the code in VB ActiveX exe
      
      
      Public Event evtNotify(str As String)

      Public Sub prcFireEvent()
      MsgBox "Event raised"
      RaiseEvent evtNotify("HI and BYE")
      End Sub

      Private Sub Class_Initialize()
      MsgBox "Class Ini"
      End Sub

      Private Sub Class_Terminate()
      MsgBox "Class TER"
      End Sub

I hope this will help you in solving the problem.....


Regards...
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 22

Expert Comment

by:ambience
ID: 7179492
you said it works for a dll but not with an Exe, this leads me to think if there is any proxy/stub problem.

Also have you spcified an IDL for the event sink ?, make sure the dispids match, can post the header for MFCSink and its IDL/ODL source.

try put a breakpoint in prcFireEvent and see if that gets called, check for any errors.

When you say it works for the dll do you mean there is a dll version of this control that you have tested with or that you tried MFCSink class with some other dll component, there might be a difference.
0
 

Author Comment

by:iamvikky
ID: 7179799
Dll works means ..the events raised by an activeX dll written in VB works fine.
I have checked every thing..even the breakpoint also but as soon as it executes that statement it gives and refference memory error when i click to debug it it takes me to dis assembley editor...


0
 
LVL 22

Expert Comment

by:ambience
ID: 7179934
does the control reach __clsEventSrc::evtNotify

try to put a break point there, the exception is coming perhaps beccause of unhandled com_exception that gets thrown.

also a good way is to catch the exception and check for the HRESULT values. Try the following

try
{
    m_pSrc->prcFireEvent();
}
catch(_com_error &err)
{
    err.hr;  // look out for this
};

If the control is reaching evtNotify then there is some problem with your MFCSink class, otherwise this appears to be a proxy/stub problem.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7200014
>>when i click to debug it it takes me to dis assembley editor
When that happens, use the command: View/Debug Windows/Call Stack (or ptess Alt+F7) That might help you track back to the part of your program that caused the fault.
-- Dan
0
 
LVL 11

Expert Comment

by:griessh
ID: 7378447
Dear iamvikky

I think you forgot this question. I will ask Community Support to close it unless you finalize it within 7 days. You can always request to keep this question open. But remember, experts can only help you if you provide feedback to their questions.
Unless there is objection or further activity,  I will suggest to accept

     "ambience"

comment(s) as an answer.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
======
Werner
0
 
LVL 6

Expert Comment

by:Mindphaser
ID: 7420129
Force accepted

** Mindphaser - Community Support Moderator **
0

Featured Post

Enroll in August's Course of the Month

August's CompTIA IT Fundamentals course includes 19 hours of basic computer principle modules and prepares you for the certification exam. It's free for Premium Members, Team Accounts, and Qualified Experts!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question