Link to home
Start Free TrialLog in
Avatar of leeor
leeor

asked on

How to create ActiveX control supporting Automation

Hi,
      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.

..............................Lee

(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???
Avatar of leeor
leeor

ASKER

Edited text of question
Avatar of leeor

ASKER

Adjusted points to 200
Avatar of leeor

ASKER

Edited text of question
Can you show your VC++ container code ?
Avatar of leeor

ASKER

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";

      USES_CONVERSION;

      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,
            pdwRegister);

      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(
            dispid,
            IID_NULL,
            LOCALE_USER_DEFAULT,
            DISPATCH_METHOD,
            &dispparamsNoArgs, NULL, NULL, NULL);

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


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

ASKER

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.
Avatar of leeor

ASKER

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???
ASKER CERTIFIED SOLUTION
Avatar of gelbert
gelbert

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of leeor

ASKER

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.