Solved

COM objects returning other COM objects

Posted on 1998-06-16
4
258 Views
Last Modified: 2013-11-25
Topic: COM objects returning other COM objects

I'm writing a little OCX control using MFC OCX-Control wizard.
The DLL contains two controls - ObjX and ObjY, where the first
one is simple frame control and the second one is "invisible-at-runtime".
To ObjX I’ve added method, which returns instance of ObjY :

afx_msg LPDISPATCH GetNextDisp();

implemented as follows:

{
      CQocxYCtrl* pCtl = new CQocxYCtrl();
      
      pCtl->EnableAutomation();

      LPDISPATCH pdisp = pCtl->GetIDispatch(1); // 1-incrament refcount

      return pdisp;
}

In VB, I’ve placed the ObjX control onto my form and wrote
script which calls GetNextDisp() of ObjX, stores IDispatch object
in variable newObj, and then calls arbitrary method of the newObj.
The VB script was:

Private Sub myButton_Click()
        Dim newObj As Object
        Set newObj = Qocx11.GetNextDisp
        newObj.MyShowMsg "hello"
End Sub

When running this VB app, exception arrives:

"Run-time error '-2147418113': OLE Automation error Catastrophic Failure"

in line newObj.MyShowMsg "hello". The method MyShowMsg is really present
in ObjY, I’ve tested it separately with VB and OLE-control test container.

What I actually wanted to do -> to return pointer to object from another object,
i.e. ObjX returns instances of ObjY, like array object returns it's row objects
sequentially or something similar.
The problem I guess is in the line:

CQocxYCtrl* pCtl = new CQocxYCtrl();

I suspect the CQocxYCtrl should be instantiated using it's class
factory, but I simply can't find it - it is buried under bunch
of MFC helper macros... may be I should use the "hard core" approach -
without MFC wizards, or any other way?

Thanks in Advance,

Aleksandras


0
Comment
Question by:alexas
  • 2
4 Comments
 

Expert Comment

by:dvazquez
ID: 1318022
You don't need to get to the object's class factory.  Just use CoCreateInstance().

Also, you might want to try declaring the function as:

HRESULT CObjX::GetNextDisp(LPDISPATCH *ppDisp);

Do whatever is necessary to get an IID_IDispatch interface pointer into ppDisp and return NOERROR if all goes well.
0
 

Expert Comment

by:dvazquez
ID: 1318023
Rejected?  Explain please...
0
 

Expert Comment

by:t004024
ID: 1318024
A control needs to have a Control site which can handle the events and callbacks of the control. When U create the control as an automation object, it does not have a site associated with it which can handle the callbacks of the control and hence it gives a catastropic error.

I do not know how VB sets the ControlSite, but if U check the code in CreateControl for CWnd, U'll see that it makes the parent Window a container and creates a control site and associates it with the control.

Maybe what U could try is call CreateControl with the parent same as the ObjX, then call GetControlIUnknown, query the IID_Dispatch interface and return it.
0
 

Accepted Solution

by:
unmeshv earned 100 total points
ID: 1318025
Some explaination for dvazquez
1. Instead of using
CQocxYCtrl* pCtl = new CQocxYCtrl()

Try implementing
HRESULT CObjX::GetNextDisp(LPDISPATCH *ppDisp)
{
    CoCreateInstance(CLISID_ObjY, NULL, CLSCTX_LOCAL_SERVER,                                         IID_OBJYINTERFACE, ppDisp);

   return S_OK;
}

In your implementation by returning pdisp u are creating another pointer  to a block which is referred by locally created new object. Now after the funtion returns this block becomes invalid and hence u get an exception.
In the method described above, u are passing pdisp by reference and it directly refers to the object created. So the new object will remain valid even after your call returns in client code.
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
The purpose of this video is to demonstrate how to set up the WordPress backend so that each page automatically generates a Mailchimp signup form in the sidebar. This will be demonstrated using a Windows 8 PC. Tools Used are Photoshop, Awesome…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

747 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now