Solved

vc++ 6.0

Posted on 1998-12-24
4
423 Views
Last Modified: 2010-04-16
I have defined some class properties or methods of myselves in an MFC ActiveX . But I can't use it in VB.
For example, I defined two classes named CPoint and CPoints use MFC class wizard as follow:
  class CPoint : public CCmdTarget
  {
   public:
      ...
   public:
     X : double;
     Y : double;
     ...(methods and properties)
   };

  class CPoints : public CCmdTarget
  {
   public:
      ...
   public:
     CPoint Items(short Index);
     void Add(CPoint aPoint);
     ...(methods and properties)
   };
   
   class CMyActiveXCtl : public COleControl
   {
    ....
    };

   Now I suppose that I will use these two ActiveX Automation objects in VB 6.0 as follow:
   dim pt as new Point
   dim pts as new Points
   pt.x = 100.1
   pt.y = 200.1
   pts.Add(pt)
   
   May you tell me how can I realize these? If possible, please give me the actual steps and detail source code of the example.Thanks a lot.

0
Comment
Question by:Axy
  • 2
4 Comments
 

Expert Comment

by:umzilber
ID: 1180999
Use ATL in VC++.

Steps:
1.  Create  a project in VC++ as an ATL project, choose DLL or ACTIVEX/CLIENT
2. use  Insert->New ATL Object to create a new ATL object (choose Simple Object)
3. right-click on the MIDL extension objject and add a property.
4 write the code for that property
5. compile the OCX
6. Use the OCX in VB
7. Done


Look on Microsofts web site on in MSDN for ATL tutorial and follow that.

Max

0
 

Accepted Solution

by:
gpeddle earned 100 total points
ID: 1181000
Use MFC in VC++

Steps:
1. Create a new project - Choose MFC AppWizard (dll)
2. In first AppWizard dialog window,
    Select 'Automation' checkbox to enable Automation
3.  Click Finish..Ok to complete the creation of the
    skeleton application
4.  Using ClassWizard, create a new class derived from
    CCmdTarget. Name this class 'Point'. Select 'Creatable by
    Type ID' checkbox and specify the name you want to use
    under Visual Basic.  (e.g. MyApp.Point)
5.  In ClassWizard, select the Automation tab for the Point
    class and add the Properties and methods you need.  
    This gives you a correctly structured class with skeleton
    version of the properties you specified.(Specify the type of
    your x/y properties as float or double if you intend to
    use decimal points as in your example code above.)
6.  Now go to the code file and add any functionality that takes
    care of storing/retrieving the property value during a
    Get/Set call, etc.
7.  Follow the same for the 'Points' class.  You will need to
    implement some kind of collection to hold the items you add.
    The CPtrList is a good way to hold them.
8.  Once you get the skeleton methods fleshed out, you can test
    this from VB using code like what you specified above.

9.  Because these are Automation objects, you must use their
    AddRef() and Release() methods to signal your interest in
    them. Review the IUnknown::AddRef() and IUnknown::Release()
    documentation from MSVC.


Notes:

All the Automation objects you creat are represented by LPDISPATCH type pointers.  When you add the function Add() to the Points class, you should specify a parameter of type LPDISPATCH for the method.  You should see something like this
in the Points.h header file:

      // Generated OLE dispatch map functions
      //{{AFX_DISPATCH(Points)
      afx_msg void Add(LPDISPATCH item);
      //}}AFX_DISPATCH

When you go back to the Points.cpp file, you'll see this:
(I've added my own comment)
/////////////////////////////////////////////////////////////////////////////
// Points message handlers

void Points::Add(LPDISPATCH item)
{
      // TODO: Add your dispatch handler code here
      /* Here you implement the code that accepts and
      *  manages the LPDISPATCH pointer
      *  
      *  For example, using a CPtrList:
      *  
      *  m_List.AddTail(item);
      *  
      */
}

In the Points::Add method, you'll need to write code to manage the collection of LPDISPATCH pointers you'll be receiving via the Add() method. The CPtrList member mentioned above would be
part of the Points class and initialized in the constructor. Add
it yourself, since it is a C++ only member, never accessed via
Automation by VB.




0
 

Author Comment

by:Axy
ID: 1181001
Sir, thanks very for your help, I have found another method to resolve the question, that is to use the FromIDispatch() and GetIDispatch(), I felt it is more convenient than the method you give me, do you think so? In another hand, if you can tell me how can I define an array property in VC? For example, Item is an arrry proerty of Points, and I will use it in VB as following:
                   Dim pts as new Points
                   Dim p as new Point
                   pts.add p
                   Dim p1 as new Point
                   set p1 = pts(0)

Note: the Item is an default property of points in VC++.
How can I define _NewEnum proeperty in class Points?

0
 

Expert Comment

by:gpeddle
ID: 1181002
The LPDISPATCH pointer you get is equivalent to the pointer you get from calling GetIDispatch, no difference.  When you call Points.Add from VB, the Point that you are adding is passed to VC as an LPDISPATCH.
=======================================================
RE 'set p1 = pts(0) '

You cannot do what you are proposing, since all communication
between VC an VB must use 'Automation' types.  It is not possible
to expose an overloaded [] operator to the VB.

You could just treat Points as a VB array and then pass it to C++ once all the Point objects are created and put into the array.  The VB array is what is called a SAFEARRAY, and it would be passed to VC as a VARIANT that contains a SAFEARRAY. You would have to write some pretty tricky code to get the values out from a VB SAFEARRAY passed to VC. Read about it and see if it makes sense to you.

OR to do the same thing in VC:

In order to do what you want, you chould write something like:

void Points::SetAt(LPDISPATCH item, long index)
{
      // Now set the item into the
      // (internal) array at the desired index
      // assume that the array is a CPtrArray
      m_Array[index] = item;

}


Also, NOTE that the VC to VB communication set up by ClassWizard
doesn't set up the internal array you'll need to create for storing the items you want to collect using either the Add() call we discussed yesterday or the SetAt() above.

You have to create the array as part of the class, perhaps in
the constructor.  The Add() or SetAt() methods just give you a way to pass the items from VB to VC++ where you can then write C++ code to put the items into the C++ array.

Go to the documentation and read CPtrList and CPtrArray.

Also, don't forget to review the AddRef and Release methods
from IDispatch.

Good Luck.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

708 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

15 Experts available now in Live!

Get 1:1 Help Now