ATL Tutorial – Events methods by thatsalok

During any discussions in forums, there are many people who want to write COM/ATL DLL but have problems creating Properties, Methods or raise Events from Components.

In this article, I am going to write a Simple, ATL DLL step by step using VC++ 6.0 and Demonstrate Creating and using of Property, Method and Events.

Convention Used

Symbol –> Means Author Comments

Symbol | Means Menus Operation, i.e., FILE | NEW mean Clicking New item of File Menu.

As I am writing the article at beginner level, I have included as many Screen Shots to explain the creation of COM DLL and explaining it step by step..

1. Open Visual Studio 6.0 and click Menu Item File|NEW to get this Dialog Box

Figure 1
 Figure 1

 

2. Choosethe ATL COM AppWizard and Give a Project Name SimpleAtlCom and click OK to Accept Project Setting, and In next Step this Dialog Box will be shown.

,Clickthe Menu Insert|NEW ATL Object… , add a Atl Object to the Project, you will see this Figure when you click above menu itemFree Threaded Marshaler,as they are Too advanced to be used in this article it Looks like.not put them now let get back to our application.

//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;
}

Figure2
figure2

 

3. Click Finish to Accept Project Setting, these above written two steps will create a blank COM DLL project.

4. Now

Figure 3
 fig3.gif

5. Select the Object|Simple Object and click Next, then you will see this Property page, let take a view in following Figure.

Figure 4 & 5
 Figure 4
 fig5.gif

6. Here in (Fig 4 ) give the Short Name as SimpleObj and you will see other Field in this dialog box get self generated.

7. in (Fig 5) let me explain every thing

  • First you see the Threading Model in the wizard; the Compiler default is selected here which is apartment as most of other application using our component is comfortable with this model.
  • Second is Interface, again I have selected the Wizard Default to Dual (there is one benefit of using dual interface ,is that you can use it in scripting language also)
  • Leave the topics of Aggregation and
  • Now look at ISupportErrorInfo, this is provided to send rich Textual information back to Client Application which is using our Interface. As we are not going to send any Error Information back to Client, I have left this Check Box unchecked.
  • Last but not the Least, for invoking event from Component ,you need support of IConnectionPoint Interface, So check the box for Supporting the Connection Point, click OK to Add the Object.

8. Now In your Project a New IDL File is get added in your Project (simpleAtlCom.idl) here take a look at IDL file how


// SimpleAtlCom.idl : source IDL for our SimpleAtlCom.dll project // // This file will be processed by the MIDL compiler 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; }; };


9. Now add Property and Method to Our Interface, let make a simple application based on Class Application. Any way do you know what is property and method. if not here is brief description about them Method is a name given to Function in interface and property to variable .but remember one thing every thing in COM/ATL is based on function, one major difference between Property and Method you can make Property Read only means you can only get data from Property but you can

10. Now put Three Property Both Get and Put and one method in our interface. Now you going to ask how and where to put them. Right click on your interface you will get option for putting the both method and Property .for clarity let take a look on these pictures. Let look at these figure.

 

Figure 6 and Figure 7
 fig6.gif  fig7.gif

11. Figure 6 shows you from where you can add the Property and Method to your interface ,now as in figure 7 you can add Three property Name ,ATL marks and Com Marks and One Method calculate and For raising I will tell you at end. After adding that your interface look like this


interface ISimpleObj : IDispatch { [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(); };


12. Now you will see function for every property and method in you class CSimpleObj .before going for actual coding, I think you want to know propget, propput and method in above Interface.

  • Propget ??? stand for Property for getting the value from Component
  •  PropPut ???Stand property for Putting property to Component. this can be optional and if you remove it this can make yor property readonly.
  •  Method???simple Function to perform some calculation.
  •  [in] — mean data is going in or your putting some value to Component.
  •  [out,retval] — notation state argument using this will return with data.
  •  HRESULT — Standard Error reporting variable

13. Now add a some useful variable in Class that will take care of above properties add char Name[100] ,short AtlMarks and short COMMarks in your CSimpleObj Class and I have coded rest of simple class for you. Let see and explain each function, I have included one more property viz Total which will return the Total till we do not implement EVENTS

Here is our SimpleObj Class code


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) {


14. Now compile and build the SimpleAtlCom dll using BUILD|BUILD SimpleATLCom.dll, and I think , you successfully get yourself a SimpleATLCom.dll.

15. Now Develop a simple Visual Basic Project for it, I have created a sample UI for above component ,let take a look on it.

 

Figure 8
 fig8.gif

 

16. now let go for coding Side, first add reference of our com dll to project ,you can found option for it in PROJECT|REFRENCES , after clicking that you will get a dialog box like this ,just find our SimpleAtlCom library in it and check the box against it and press OK here is Dialog applicationlook like

Figure 9
 fig9.gif

 17. now let look at backend coding of VB application .


//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


18. Before going for Events , let see test running of our application., here it is –>

Figure 10
 fig10.gif

19. I think, till now nobody have face problem I n getting above. Now take a look at events and how to create them and raise them. You can see a Interface names _ISimpleObjEvents this is disinterface created by APP Wizard ehich provide support for Events. You can see a prefix ‘???_??? (underscore) ,this underscore notify MIDL (Microsoft IDL compiler) that this interface is Disinteface and don???t make it part of TLB files. Now right click on this interface and add a method say

Void TOTAL([in]short marks);

Like shown in this fiqure

Figure 11
 fig11.gif

 20. Now right Click on your CSimpleObj class and Click on Implement Connection Point Option. You will see this figure, check on _ISimpleObjEvents Check Box and Click OK .voila the CProxy_ISimpleObjEvents class is get added to your project. This is proxy class that will fire Event for you. you can see it contain this function

VOID Fire_TotalMarks(SHORT TotalMarks)

Which is proxy function ,which raise events . ohh I forget ,take a look at picture for Connection Point implementation

Figure 12
 fig12.gif

 21. Now event is added to your class, now let modify the CSimpleObj::Calculate()

    Now new CSimpleObj::Calculate() look like this


STDMETHODIMP CSimpleObj::Calculate() {   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; }


22. Now let modify our Visual Basic application to handle events

Private Obj As SIMPLEATLCOMLib.SimpleObj

Private withevents Obj As SIMPLEATLCOMLib.SimpleObj

This help us to implement Events, look this figure for more Clarity

Change it to

Figure 14
 fig14.gif

 23. Now Look at code for Implementation of events, as Total marks come from Event ,just add a line to show total marks. so our Event code look like

Private Sub Obj_TotalMarks(ByVal TotalMarks As Integer) MsgBox “total marks ” & TotalMarks End Sub

Figure 15
 fig15.gif

Download Codes Includes

Source Code Include

  • #1 SimpleAtlCom.DLL (with source code)
  • #2 Test Project in Visual Basic.

Download the Source code by clicking the link.

Test Project Include

  • #1 Compiled Test Application
  • #2 Compiled SimpleAtlCom.DLL

Download the Project files by clicking the link.

Using of Demo Application

If you directly use the Com dll and Test application ,don???t forget to register ComDLL ie SimpleAtlCom.dll to your computer.

You can use this command line to register the Component

Drive:> %sys%regsvr32 SimpleAtlCom.dll to register application.

Author Comment

Special Thanks : To My Mother and Father

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

24. Now test and run the application here it is the message box showing event.