CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13
  1. #1
    Join Date
    Mar 2010
    Location
    Germany
    Posts
    24

    Can a COM+ Component contain a Class ?

    I refer to a Codeguru article:
    "How to Write a COM+ Component"
    http://www.codeguru.com/cpp/com-tech...cle.php/c16639

    My question is:
    The article illustrates how to create a COM+ component and how to add a method to the component. Once the framework for the com+ component is set, and by using the class-wizard, also properties (such as integers, doubles etc.) can be added to the component.

    Is it also possible to add a class?

    My objective is, that once I reference the com+ object, say in Excel I not only want to access the object's functions and the properties but also subclasses of that object. Following the example set by the article (where a component named "Bird" was created and a method "Fly" was formulated) I now want to add an object(!) named "Wings". "Wings" would be represented by a class. Properties of wings would include "Nr_of_Wings", "length_of_Wings", etc.

    Is this possible using a com+ component?

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Can a COM+ Component contain a Class ?

    Sure. COM or COM+ is only the binary standard for the interface.

    You can implement it on the backend however you want (including using classes).

  3. #3
    Join Date
    Mar 2010
    Location
    Germany
    Posts
    24

    Re: Can a COM+ Component contain a Class ?

    Hi Arjan,
    this sounds promising. May I ask for more guidance?

    a) In the quoted sample they created a Bird com+ component. The METHOD fly was implemented through:

    [id(1), helpstring("method Fly")] HRESULT Fly([out,retval] LONG* lSpeed);

    and


    STDMETHODIMP CBird::Fly(LONG* lSpeed)
    {
    // TODO: Add your implementation code here
    *lSpeed = 0xbee;
    return S_OK;
    }

    b) Using the wizard also PROPETRIES can be implemented: In Bird.h I must add a public section so it becomes

    public: double MyValue;

    and in Bird.cpp I must complete the TODO sections for the Get_ and PUT_MyValue methods as follows:

    STDMETHODIMP Bird::get_MyValue(short *pVal)
    {
    *pVal=this->MyValue; return S_OK;
    }

    STDMETHODIMP Bird:ut_MyValue(short newVal)
    {
    this->MyValue=newVal;
    return S_OK;
    }


    c) Where exactly, and usig which commands and syntax must I emplement a CLASS so is also exposed as a subclass of the com+ component ? Remember: At the end of the day, in Excel, I want to say things like:

    Dim MyBird as Bird
    MyBird.Wings.Length_of_Wings=42
    MyBird.Wings.Spread(95) 'comment: 95%


    Best Regards,
    cc
    Last edited by codecheater; March 22nd, 2010 at 04:03 AM.

  4. #4
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Can a COM+ Component contain a Class ?

    What I am referring to is that you can implement the behind the scenes COM code using a class. In Excel, you'll still need to create the COM object as you normally would create COM objects in Excel.

    In terms of implementing the COM code using a class - is instead of putting the code directly into the STDMETHODIMP methods, you create an 'implementation' class and have it do the work:

    Code:
     
    CBirdImpl m_BirdImpl; // declared as a member of CBird in Bird.h
     
    STDMETHODIMP CBird::Fly(LONG* lSpeed)
    {
      return m_BirdImpl.Fly( lSpeed );
    }
    One benefit of this approach is that it allows you to unit test your code without involving the COM subsystem. It also makes debugging simpler because you can get the code working without COM before testing it through the COM interface (problem isolation is easier this way).

  5. #5
    Join Date
    Mar 2010
    Location
    Germany
    Posts
    24

    Re: Can a COM+ Component contain a Class ?

    Hi Arjay, thanks for getting back.
    But I still do not see how I can make the WINGS become a subclass of the com+ component BIRD ?
    It may be asking for too much but without an example or instructions on where excactly I have to enter what sort of code, my knowhow is not sufficient to follow your reply. Maybe you can advise where I can find a sample project for VS 2005 (other versions may be helpful, too). Kind Regards,
    cc

  6. #6
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Can a COM+ Component contain a Class ?

    Quote Originally Posted by codecheater View Post
    Hi Arjay, thanks for getting back.
    But I still do not see how I can make the WINGS become a subclass of the com+ component BIRD ?
    You can't on the COM interface level. However, you can implement Wings on the implementation level with CWingsImpl derived from CBirdsImpl.

  7. #7
    Join Date
    Mar 2010
    Location
    Germany
    Posts
    24

    Re: Can a COM+ Component contain a Class ?

    I start to get an idea. To doublecheck, are you saying that at the end of the day, in Excel I will not be able to write:

    Dim MyBird as Bird
    MyBird.Wings.Length_of_Wings=42
    MyBird.Wings.Spread(95) 'comment: 95%

    Instead, I will only be able to write:

    Dim MyWings as Wings
    MyWings.Length_of_Wings=42
    MyWings.Spread(95) 'comment: 95%

  8. #8
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Can a COM+ Component contain a Class ?

    MyBird.Wings implies Wings as a property of Bird rather than a derived class.

    If that's what you want, then expose a Wings property for the Bird interface.

    I suggest reading up on COM for more info.

    A good book on the subject is Beginning ATL 3 COM Programming.

  9. #9
    Join Date
    Mar 2010
    Location
    Germany
    Posts
    24

    Re: Can a COM+ Component contain a Class ?

    Excellent - thanks a lot for suggesting a book title. As you figured from my questions I am new to C++. With so many things to catch up with, finding a starting point for facing the issue looks very difficult to me and this books looks promising - ordered already. Best, cc

  10. #10
    Join Date
    Mar 2010
    Location
    Germany
    Posts
    24

    Re: Can a COM+ Component contain a Class ?

    I finally succeeded in implementing the code for the DeveloperCollection Object in "Beginning ATL3 COM". I refer to Chapter 9, page 410. Using VBA in Excel, I can now create a collection of Objects. In the sample we get the following tree structure:

    BUObject
    + Manager
    - Name
    - ID
    + Secretray
    - Name
    - ID
    + Manager
    - Name
    - ID
    + Developers
    - Developer(1)
    - Name
    - ID
    - Developer(2)
    - Name
    - ID
    - Developer(etc...)
    - Name
    - ID

    Note that Manager, Secretary and Developers are all of the same Class (Class Employee). The Employee class comes with the properties Name and ID.

    So far so good.

    Here comes my next issue which I must understand to make another step forward:

    I want to create a function (or method) that allows to calculate the mean average of the ID's.
    (... on a more realistic picture, the ID would rather be the age. Calculating the average age may be a useful thing to do).

    The function would need to access the developers collection, loop through all individual Developers and access the ID property. I want this to become a method of the BusinessUnit. At the end of the day, in VBA I want to say:

    AverageID=MyBusinessUnit.CalcAverageID
    ..or
    call MyBusinessUnit.CalculateAge(AverageID)

    What I do not understand is: within the cpp file of the BusinessUnit, how can I access the developer-collection with the individual developers and identify their IDs?

    Maybe I am already very close but do not see the light, yet? Or is there any recommended book or chapter which helps me on... ?

    p.s. A much simpler milestone would be to formulate a method in BusinessUnit that simply adds the IDs of Manager and Secretary. This would eventually already show me the way.
    Last edited by codecheater; April 18th, 2010 at 10:54 AM.

  11. #11
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Can a COM+ Component contain a Class ?

    What I do not understand is: within the cpp file of the BusinessUnit, how can I access the developer-collection with the individual developers and identify their IDs?
    It depends on the low level of your collection implementation. The BU implementation may be or may be not aware of the details, and either use those correspondingly or act as if it see the collection from outside, i.e. iterate it through with the public methods.
    Best regards,
    Igor

  12. #12
    Join Date
    Mar 2010
    Location
    Germany
    Posts
    24

    Re: Can a COM+ Component contain a Class ?

    Hi Igor,
    I appreciate you took a look at this. I understand your approach but unfortunately I am not skilled enough to make it happen. In case you have access to Richard Grime's book and in case you know this Business Unit Collection Example, then the best way for me to see the light is through a real life example. In the code - DeveloperCollection.cpp - there comes a method called GetEmployee and it is used in the ADD method of the DeloperCollection.cpp

    void CBusinessUnit::MyGetEmployee(IEmployee* pEmployee,
    CComBSTR& bstrName,
    long& pEmployeeID)
    {
    pEmployee->get_Name(&bstrName);
    pEmployee->get_EmployeeID(&pEmployeeID);
    }


    What I want to learn is how to write a similar method in the BusinessUnit.cpp that would loop through the DeveloperCollection, access some properties of the individual items (which are "Employee" Objects and then perform some calculations on those properties (find nr of employees that are named "John" or calculate the average EmployeeID. All I currently know to do is access the COllection's Count attribute.


    STDMETHODIMP CBusinessUnit::Calc_Devs(IDeveloperCollection *pDevs,long* myCnt)
    {
    // TODO: Add your implementation code here ...

    // pDevs represents the Collection of Developpers (see argument list!)
    // the following method will retrieve the Count-attribute of pDevs by

    GetDevCol(pDevs, *myCnt);

    // now, I would like loop through the Collection of Developers and access each employee's name and ID
    // (for example, I could then calculate the avarge ID. Or I could identify all employees (developers) who are named "John" etc.
    // I do not know how to do that. How can I access the individual developers (items)?

    return S_OK;
    }


    void CBusinessUnit::GetDevCol(IDeveloperCollection* pDevs,
    long& Cnt)
    {
    pDevs->get_Count(&Cnt);

    }


    "Count" is just a flat attribute so it is easy and pretty trivial. My challange is to loop through each item of the "pDevs" collection. Any idea how the precise code must look? Would it make use of ATL specific features?
    Or maybe you have a precise reference to a source that explains? It's probably all written in the other 400 pages of the book, so maybe with some guidance I could find the proper lines.


    Kind Regards
    cc
    Last edited by codecheater; April 23rd, 2010 at 05:39 AM.

  13. #13
    Join Date
    Mar 2010
    Location
    Germany
    Posts
    24

    Re: Can a COM+ Component contain a Class ?

    ok, some further reading gets me to doing the following lines, say, to access the first item of the collection:


    void CBusinessUnit::GetDevCol(IDeveloperCollection* pDevs, long& Cnt)
    {
    CComVariant index = 1;
    CComVariant Emp;
    HRESULT hr1=pDevs->get_Item(indx, &Emp);
    }

    get_item gives me a Variant Emp with VT_DISPATCH as a member.
    QueryInterface should now allow me to get a pointer to IEmployee. I could then access IEmployee's properties and methods.

    I am still struggling with the syntax. Would anybody have a suggestion on how to do that in terms of exact code?

    Also: I can imagine using the following code to access Emp..

    IUnknown* Emp;
    HRESULT hr2=pDevs->get__NewEnum(&Emp);
    Last edited by codecheater; April 30th, 2010 at 01:55 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured