How to create ActiveX control supporting Automation

Posted on 1997-09-25
Last Modified: 2013-11-20
      I have created a basic ActiveX control using MSVC++ 5.0 Control Wizard. I added one arbitrary method, and compiled it.  
      When I use the control in VB 5.0, it works as long as I place the control on the form and access its method that way. But if I use automation, such as in the following VB code,

Dim obj as Object
set obj = CreateObject("MyControl.mycontrol.1")
obj.MyMethod  ,

I get the error:

Run-time error -2147418113 (8000ffff)
Method 'MyMethod' of object '_DMyControl' failed.

(The error number is S_UNEXPECTED in VC++, and it occurs because the m_bInitialized member variable is false in the instance of COleControl - I tried the equivalent of "CreateObject" in VC++ and the I got the same error)

There must be something simple that I am missing out on...I thank you in advance for any help.


(FYI, the CreateObject statement seems to function properly, as I do get a pointer to my control when debugging)

PS: Instead of trying to instantiate the other object using "CreateObject" (or the equivalent set of C++ functions), can one get a pointer to an ActiveX control from within another ActiveX control given that they both reside in the same container???
Question by:leeor
  • 7
  • 3

Author Comment

ID: 1306961
Edited text of question

Author Comment

ID: 1306962
Adjusted points to 200

Author Comment

ID: 1306963
Edited text of question
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.


Expert Comment

ID: 1306964
Can you show your VC++ container code ?

Author Comment

ID: 1306965
Hi Gelbert,
   Sorry, I guess I was not clear enough. The container is a VB form (although I should not depend on one specific container, of course). If you mean my VC++ code which instantiates the ActiveX control - it performs the same function as CreateObject(), but here it is anyway...

        // Set GUID
      long a = 1163048501;  
      short b = 13338;            
      short c = 4561;      
      unsigned char d[8] = {150,34,0,0,192,52,105,210};

      GUID g;
      g.Data1 = a;
      g.Data2 = b;
      g.Data3 = c;
      for (int i =0; i<=7; i++)
            g.Data4[i] = d[i];      

      if (int r = OleInitialize(NULL) != S_OK)
            TRACE("OleInitialize() failed!\n");

      REFCLSID CLSID_CMyObject = g;

      HRESULT hresult;
      IUnknown FAR* punk;
      IDispatch FAR* pdisp = (IDispatch FAR*)NULL;

      LPCTSTR methodName = "putNoText";


      LPCOLESTR lpOleStr = T2COLE(methodName);

      DISPID dispid;
      DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};

      hresult = CoCreateInstance(CLSID_CMyObject, NULL, CLSCTX_INPROC_SERVER, //CLSCTX_SERVER,
                        IID_IUnknown, (void FAR* FAR*)&punk);

      if (hresult != S_OK)
            TRACE("CoCreateInstance failed!\n");

      hresult = punk->QueryInterface(IID_IDispatch,
                  (void FAR* FAR*)&pdisp);
      if (hresult != S_OK)
            TRACE("QueryInterface (IDispatch) failed!\n");

      IUnknown FAR* punknown = (IUnknown FAR*)NULL;
      LPDWORD lpdwRegister = (LPDWORD)malloc(64);
      hresult = punk->QueryInterface(IID_IUnknown,
                  (void FAR* FAR*)&punknown);

      if (hresult != S_OK)
            TRACE("QueryInterface (IUnknown) failed!\n");

      hresult = CoRegisterClassObject(CLSID_CMyObject, punknown, CLSCTX_INPROC_SERVER,
                        REGCLS_MULTIPLEUSE, lpdwRegister);

      if (hresult != S_OK)
            TRACE("CoRegisterClassObject() failed!\n");

      unsigned long FAR* pdwRegister = (unsigned long FAR*)malloc(64);
      hresult = RegisterActiveObject(punknown, CLSID_CMyObject, ACTIVEOBJECT_STRONG,

      if (hresult != S_OK)
            TRACE("RegisterActiveObject() failed!\n");

      hresult = pdisp->GetIDsOfNames(IID_NULL, (LPOLESTR*)&lpOleStr, 1,
                        LOCALE_USER_DEFAULT, &dispid);

      if (hresult != S_OK)
            TRACE("GetIDsOfNames failed!\n");

      hresult = pdisp->Invoke(
            &dispparamsNoArgs, NULL, NULL, NULL);

        // This is where the failure occurs - all other functions
        // complete successfully
      if (hresult != S_OK)
            TRACE("Invoke failed!\n");


Expert Comment

ID: 1306966
When you use CoCreateInstance() ask for IClassFactory insterface and use it ot call IClassFactory::CreateInstance() to create instance of object

Author Comment

ID: 1306967
Didn't work.....
Let me make my question simpler...

1) I created an ActiveX control using VC++ 5.0 control wizard.
2) I added 1 method called "Method"

3) I created another ActiveX control using VC++ 5.0 control wizard.
4) In the second control, I am trying to invoke the method on the first control.

I have failed to do this so far, and have tried everything I could think of.  If you have any idea (or source code example) please let me know. Thanks.

P.S. I am using VB as the form on which the second control is placed.

Author Comment

ID: 1306968
hint: the CoCreateInstance and CreateInstance functions create an UNINITIALIZED (what does that mean?) object. The error I am getting is within the COleControl class, where the variable m_bInitialized = FALSE when it should be true. Is there someway to "initialize" an ole object that I do not know about???

Accepted Solution

gelbert earned 300 total points
ID: 1306969
You have to load control state to initialized m_bInitialized property to TRUE by calling COleControl::Load() which is wrapper around IPersistXXX::Load() function (IPersistStorage, IPersistFile,....)

Author Comment

ID: 1306970
I already checked that option, but I do not have a pointer to the control, but merely a pointer to its interfaces. Anyway, like I said before, my C++ code is the equivalent to the Visual Basic "CreateObject" function, and that did not work.  I think I have figured out the problem - it is that the new (VC++ 5.0) activeX wizard creates more lightweight controls than (VC++ 4) and as such have left out certain interfaces such as some automation ones, and so I need to add them manually. Thanks for the help anyway...I'll give u the points for good effort.

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
function returning CString in a regular win32 DLL 8 190
Define unique primary key 9 95
Images for a Website that have different components 3 123
wordappend challenge 8 202
In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
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.

830 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