-
March 21st, 2010, 02:30 PM
#1
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?
-
March 21st, 2010, 03:00 PM
#2
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).
-
March 22nd, 2010, 02:22 AM
#3
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.
-
March 22nd, 2010, 09:44 AM
#4
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).
-
March 22nd, 2010, 11:10 AM
#5
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
-
March 22nd, 2010, 11:31 AM
#6
Re: Can a COM+ Component contain a Class ?
Originally Posted by codecheater
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.
-
March 22nd, 2010, 11:58 AM
#7
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%
-
March 22nd, 2010, 12:06 PM
#8
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.
-
March 22nd, 2010, 02:15 PM
#9
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
-
April 18th, 2010, 10:45 AM
#10
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.
-
April 18th, 2010, 02:21 PM
#11
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
-
April 23rd, 2010, 04:54 AM
#12
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.
-
April 27th, 2010, 04:14 AM
#13
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|