MFC ActiveX control

Posted on 2001-08-23
Last Modified: 2013-11-25
I have an MFC ActiveX control, one property of which should expose an ATL COM object from within the same dll.  The ATL object is a collection of other ATL objects, although I don't *think* that's important.

My problem is that, although I can get the interface to recognize what I'm trying to do (ie in VB the intellisense works) I can't get the COleControl to expose the custom control.

I'm new to this, so I guess I'm looking for someone to hold my hand a bit through it.  Depending on how complicated the question is, I might raise the points.

Some background info:

the odl code for the interface:
[propget, id(2)] long Series([out, retval] ISeriesCollection* *pVal);

where ISeriesCollection is my interface to the ATL object which is a collection of ATL objects.

the declaration of the corresponding class declaration (within the AFX_DISPATCH comments):
afx_msg long GetSeries(ISeriesCollection **pVal);

The definition after the BEGIN_DISPATCH_MAP() macro:
DISP_PROPERTY_PARAM(CGraphMFCCtrl, "Series", GetSeries, SetNotSupported, VT_R8,VTS_VARIANT)

I've seen some code for how to do this exact thing with ATL, but my control is MFC.

All help gratefully accepted.
Question by:IainHere
  • 4
  • 3

Expert Comment

ID: 6419738

Trick is to make ATL Code treat your MFC control
as a client for the interface. You could try
aggreagation, but that does not sound too good
atleast not right away.

Go through the CoCreateInstance (CoGetClassObject)
rigmarole in MFC to create interface ISeries...

I guess intellisense worked, bcos it used your .tlb
and not really used actual object.

What exactly is the nature of error message.


Author Comment

ID: 6419817
Sorry if I'm being rather vague - it's always a problem when someone doesn't understand what they're trying to do :-)

Everything compiles OK, but only because I haven't done anything.  What I'm asking for is advice on how to do it.  The error message I've seen has occurred when I changed the GetSeries function to expose an ISeriesCollection in the way I wrote it above.  Now, if I try to use the ClassWizard on the interface, it says

"Parsing Error: ISeriesCollection **pVal is not a valid OLE Parameter type"

But I thought that, since I'd defined it, I could use it?  Am I being naive?

Accepted Solution

peterchen092700 earned 100 total points
ID: 6420044
>> "Parsing Error: ISeriesCollection **pVal is not a valid OLE Parameter type"

The problem is, OLE does only know about IDispatch. I know that VB no supports custom (IUnknown-based) interfaces as well, if all functions use OLE compatible types only - but I dubt thar you can accept MFC to accept another interface than IDispatch in an automation-compatible object.

I assume your ISeriesCollection is a dual interface (i.e. inherited from IDispatch, provides both early and late binding). If not, you've got to do that again ;)

Change the declaration of the propget to returning an IDispatch * (rather than ISeriesCollection).

As I don't know how you implemented the collection, I assume the usual way: You create an Instance of the SeriesCollection, feed it with an pointer to the SeriesContainer (a chart?), cst it to IDispatch, AddRef it, and return.  The creation of the ATL component is like I described in your last question ;) - I have no MSDN/Source of me here, so it's right out of my brain:

GetSeriesCollection(IDispatch ** disp)
  (if !disp) return E_POINTER;
CComObject<CSeriesCollection> * sc = 0;
HRESULT hr = CComObject<CSeriesCollection>::CreateInstance(&sc);
// up to here compare w/ my answer to your last question
if (FAILED(hr)) return hr;

sc->SetOwner(this); // this is passing a CChart * to the container - i.e. this is not a COM method. this allows the two to communicate directly, rather than through C++ interfaces)

sc->AddRef();  / we are returning a pointer, s owe have to addref
*disp = static_cast<IDispatch *>(sc);
return S_OK;

There might be some problems in VB to make intellisense work - I'm not sure here, but the standard ODL declaration (the SeriesCollection object suports an ISeriesCollection interface) should be enough here.

So far, did it help to take a step?

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.


Author Comment

ID: 6421202
Thanks again peter.  I'll try what you're describing; I hope you don't mind me keeping the Q open for a little longer, until I understand what you said :-)

Author Comment

ID: 6421312
OK.  I'm still lost:

1) "Parsing error IDispatch** is not valid etc.  I hacked an attempt at IDispatch* and IDispatch, neither of which were happy.  Can I safely ignore this message?

2) Do I have to implement SetOwner() myself?  I can't find it.

I would go away and RT(F)M, if I could find one.  Thanks.

Expert Comment

ID: 6421429
1) is it declared as [out, retval] ?
2) SetOwner:

yes, it's actually quite simple:
class CChart : public IChart, ....

class CSeriesCollection
  CComObject<CChart> * m_chart;  // init to 0
  void SetOwner(CChar * chart)
     if (chart) chart->AddRef();
     if (m_chart)  m_chart->Release();
     m_chart = chart;
   ~CSeriesCollection() { SetOwner(0); }

the SeriesColleciton now has full access to the chart, so it can iterate over it's items. Note that the colleciton has a reference to the chart, so the chart will be "kept alive" by any "living" SeriesCollection.

Another option would be the SetOwner function to copy the Series Interface Pointer list (addrefing it), and not keeping a reference to the chart.

3) Yeah, MSDN can be a pain. There's all informaiton you need, buried under 1000 tons of marketing sh*t


Expert Comment

ID: 6421430
P.S. keeping your Q open as long as you're not satisfied is quite ok. Only thing that could happen that I gently withdraw from the question..

Author Comment

ID: 6421457
>> is it declared as [out, retval] ?
Yes (all the declarations and stuff are as they were described in the original Q, excapt they've been corrected to IDispatch).  I think I'll ignore the message for now, and see what happens.  If you can think of anything else it might be, I'd be grateful for the info.

Thanks for the help.  I'll take the hint, and open another question when I have my next problem.  Hope you'll feel like helping me again :-)

Featured Post

ScreenConnect 6.0 Free Trial

At ScreenConnect, partner feedback doesn't fall on deaf ears. We collected partner suggestions off of their virtual wish list and transformed them into one game-changing release: ScreenConnect 6.0. Explore all of the extras and enhancements for yourself!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
sameEnds challenge 3 162
SignTool Error with Windows 10 5 150
How do ASP.NET and MVC work together? 4 49
VS2015 Redefinition errors 4 52
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
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 is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA.…

831 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