Expiring Today—Celebrate National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

How to create ActiveX control supporting Automation

Posted on 1997-09-25
10
Medium Priority
?
761 Views
Last Modified: 2013-11-20
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???
0
Comment
Question by:leeor
[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
  • 7
  • 3
10 Comments
 

Author Comment

by:leeor
ID: 1306961
Edited text of question
0
 

Author Comment

by:leeor
ID: 1306962
Adjusted points to 200
0
 

Author Comment

by:leeor
ID: 1306963
Edited text of question
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 8

Expert Comment

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

Author Comment

by:leeor
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";

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


0
 
LVL 8

Expert Comment

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

Author Comment

by:leeor
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.
0
 

Author Comment

by:leeor
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???
0
 
LVL 8

Accepted Solution

by:
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,....)
0
 

Author Comment

by:leeor
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.
0

Featured Post

Independent Software Vendors: 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!

Question has a verified solution.

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

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
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.

718 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