During discussion on forums, I come across many people who want to write COM/ATLDLL, but don’t know how to create properties, methods or raise events from Component or strive for fundamental knowledge to create them. In this Article, I am going to write a simple, ATL DLL step by step using VC++ 6.0 and demonstrate creation and usage of property, method and event.
Since I am writing a Beginner Article, I have included as many screen shots to explain the creation of COM DLL and let me explain that to you step by step.
These above written two steps will create a blank COM DLL project for you.
// SimpleAtlCom.idl : IDL source for SimpleAtlCom.dll // // This file will be processed by the MIDL tool to // produce the type library (SimpleAtlCom.tlb) and marshalling code. import "oaidl.idl"; import "ocidl.idl"; // Above two File are define the IDispatch Inteface etc. [ object, uuid(10CDF249-A336-406F-B472-20F08660D609), // Unique Id OF Object dual, // State our Interface is Dually Suported helpstring("ISimpleObj Interface"), pointer_default(unique) ] // Our Empty Interface interface ISimpleObj : IDispatch { }; [ uuid(8B1C3F79-07BA-44F8-8C47-AE2685488DFA), version(1.0), // our Library Name helpstring("SimpleAtlCom 1.0 Type Library") ] library SIMPLEATLCOMLib { importlib("stdole32.tlb"); importlib("stdole2.tlb"); [ uuid(9B5BC0F8-7421-4C46-AA5F-539ECCAFCB82), helpstring("_ISimpleObjEvents Interface") ] // Disinterface Provides support for raising events, //as I already told you about that above dispinterface _ISimpleObjEvents { properties: methods: }; [ uuid(27BF0027-BECC-4847-AF91-99652BCE9791), helpstring("SimpleObj Class") ] // Our object base class where actual coding of our Property //and Event resides coclass SimpleObj { [default] interface ISimpleObj; [default, source] dispinterface _ISimpleObjEvents; }; };
Name
ATLMarks
ComMarks
Calculate
interface ISimpleObj : IDispatch // Our base interface { [propget, id(1), helpstring("property Name")] HRESULT Name([out, retval] BSTR *pVal); [propput, id(1), helpstring("property Name")] HRESULT Name([in] BSTR newVal); [propget, id(2), helpstring("property ATLMarks")] HRESULT ATLMarks([out, retval] short *pVal); [propput, id(2), helpstring("property ATLMarks")] HRESULT ATLMarks([in] short newVal); [propget, id(3), helpstring("property COMMarks")] HRESULT COMMarks([out, retval] short *pVal); [propput, id(3), helpstring("property COMMarks")] HRESULT COMMarks([in] short newVal); [id(4), helpstring("method Calculate")] HRESULT Calculate(); };
CSimpleObj
propget
propput
method
Propget
PropPut
Method
[in]
[out,retval]
HRESULT
char Name[100]
short AtlMarks
short COMMarks
total
Here is our SimpleObj class code.
SimpleObj
STDMETHODIMP CSimpleObj::get_Name(BSTR *pVal) { // return Name of Student CComBSTR bstStr(this->Name); *pVal=bstStr.Detach(); return S_OK; } STDMETHODIMP CSimpleObj::put_Name(BSTR newVal) { // put Name of Student ::wcstombs(this->Name,newVal,99); return S_OK; } STDMETHODIMP CSimpleObj::get_ATLMarks(short *pVal) { //return ATL marks *pVal=this->ATLMarks; return S_OK; } STDMETHODIMP CSimpleObj::put_ATLMarks(short newVal) { // return Put of marks of atl this->ATLMarks=newVal; return S_OK; } STDMETHODIMP CSimpleObj::get_COMMarks(short *pVal) { // get the marks for COM *pVal=this->COMMarks; return S_OK; } STDMETHODIMP CSimpleObj::put_COMMarks(short newVal) { //put marks for COM this->COMMarks=newVal; return S_OK; } STDMETHODIMP CSimpleObj::get_Total(short *pVal) { //return total number of marks *pVal=this->m_iTotalMarks; return S_OK; } STDMETHODIMP CSimpleObj::Calculate() { // Calculate total number of marks and store it total number variable this->m_iTotalMarks=this->ATLMarks+this->COMMarks; return S_OK; }
'Our Component Object Private Obj As SIMPLEATLCOMLib.SimpleObj Private Sub cmdPutValue_Click() 'give memory to Com object Set Obj = New SIMPLEATLCOMLib.SimpleObj 'put atl marks in component Obj.ATLMarks = txtPutATL 'put com marks Obj.COMMarks = Me.txtPutCom 'put Name Obj.Name = Me.txtPutName End Sub Private Sub cmdGetValue_Click() 'calculate the marks Obj.Calculate 'put atl marks in component Me.txtGetAtl = Obj.ATLMarks 'put com marks Me.txtGetCom = Obj.COMMarks 'put Name Me.txtGetName = Obj.Name 'get total marks and display it on the Component Me.txtTotalMarks = Obj.Total End Sub
_ISimpleObjEvents
Void TOTAL([in]short marks)
CProxy_ISimpleObjEvents
VOID Fire_TotalMarks(SHORT TotalMarks)
CSimpleObj::Calculate()
Now new CSimpleObj::Calculate() looks like this:
STDMETHODIMP CSimpleObj::Calculate() { //add Marks this->m_iTotalMarks=this->ATLMarks + this->COMMarks; // when you use this pointer ,Fire_Totalmarks support //is added to your class // after you implement the Connection points // This event will fire the Total though event to Client this->Fire_TotalMarks(this->m_iTotalMarks); return S_OK; }
Change
Private Obj As SIMPLEATLCOMLib.SimpleObj
to
Private withevents Obj As SIMPLEATLCOMLib.SimpleObj
This helps us to implement events, look this figure for more clarity.
TotalMarks
Private Sub Obj_TotalMarks(ByVal TotalMarks As Integer) 'Display the MessageBox displaying Total Marks MsgBox "total marks " & TotalMarks End Sub
If you like, use the Com DLL and Test application first. Don’t forget to register Com DLL i.e., SimpleAtlCom.dll, to your computer. You can use this command line to register the Component.
Drive:> %sys%regsvr32 SimpleAtlCom.dll
I tried my level best to tell each and every simple aspect of com DLL. If it is missing something, feel free to contact me.
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)
General News Suggestion Question Bug Answer Joke Rant Admin
Math Primers for Programmers