YOU CAN CODE!

 

With The Case Of UCanCode.net  Release The Power OF  Visual C++ !   HomeProducts | PurchaseSupport | Downloads  
Download Evaluation
Pricing & Purchase?
E-XD++Visual C++/ MFC Products
Overview
Features Tour 
Electronic Form Solution
Visualization & HMI Solution
Power system HMI Solution
CAD Drawing and Printing Solution

Bar code labeling Solution
Workflow Solution

Coal industry HMI Solution
Instrumentation Gauge Solution

Report Printing Solution
Graphical modeling Solution
GIS mapping solution

Visio graphics solution
Industrial control SCADA &HMI Solution
BPM business process Solution

Industrial monitoring Solution
Flowchart and diagramming Solution
Organization Diagram Solution

Graphic editor Source Code
UML drawing editor Source Code
Map Diagramming Solution

Architectural Graphic Drawing Solution
Request Evaluation
Purchase
ActiveX COM Products
Overview
Download
Purchase
Technical Support
  General Q & A
Discussion Board
Contact Us

Links

Get Ready to Unleash the Power of UCanCode .NET

 


UCanCode Software focuses on general application software development. We provide complete solution for developers. No matter you want to develop a simple database workflow application, or an large flow/diagram based system, our product will provide a complete solution for you. Our product had been used by hundreds of top companies around the world!

"100% source code provided! Free you from not daring to use components because of unable to master the key technology of components!"


VC++ Example: Com Programming
IDispatch, QueryInterface, CoCreateInstance, IUnknown, GetTickCount, itoa, ATL Control

By Ranjan Banerji. 
A tutorial on how to create connection points using VC++ and ATL

Introduction

The purpose of this article is to provide an introductory tutorial to implement connection points in VC++ using ATL. For deeper understanding of connection points I suggest you read Code Project/COM / DCOM - Connection Points And Asynchronous calls - Part I. From a simplistic point of view I tend to treat Connection Points as an event handling mechanism for COM. So if you created an ActiveX control, a button for example and you wanted the click event to be handled by the container of the control and not the control itself you would use connection points. You may, however, go beyond just handling windows event and create those of your own. I have found that creating connection points in VC++ 6.0 to be a little confusing and not very obvious. I did these a couple of years ago while creating some controls and then recently had to use connection points again and just could not remember how I implemented them the first time. This tutorial is designed to help figure out how to create connection points using VC++.

The Project

Some of what is here will be a repeat of what you have seen in other articles. I will be as brief as possible and will assume that you know how to create an ATL DLL and a control within it. Lets start with creating an ATL COM DLL using the VC++ wizards calling the project Connection. Then lets create a composite control. You can create any control or object. A composite control simply allows me to provide for a good example. I am not showing how to create these as I am assuming that you know. If you do not know how to do so you should read some of the other articles posted here. Name this control ConnCtl. While creating the control select the attribute tab and then select the Support Connection Points check box. Then click OK.

VC++ This will automatically take you to the resource editor to place controls and build your composite control. For starters lets place a button on this control. You can either double click on the button or right click on CConCtl in the ClassView and then select to Add a Windows Message Handler. We add a handler to handle the clicking of a the button. This is done no differently from how we would add a windows message handler in a regular windows application using VC++. In the message handling function lets add a message box to show that we handled the click.

 

LRESULT CConnCtl::OnClickedButton(WORD wNotifyCode, WORD wID, 
      HWND hWndCtl, BOOL& bHandled) {
    ::MessageBox( hWndCtl, "Button was clicked"", 
      "Handled in Control", MB_OK" );

    return 0;
}

Build the project and test the control. When you click on the button you will see the message box we added. So now we have an ActiveX control that has a button and when you click the button you get our message box. Fantastic! You can use this control in any COM container. So where do the connection points come in?

Now suppose you wanted to trap the button click event in the container. Or to be more precise if you wanted the control to inform the container that the button has been clicked. This is when you need to implement connection points.

To do so first go to class view and right click on _IconnCtlEvents and add a method that will represent the interface that your control will provide its container with the information that the button has been clicked. Lets call it OnControlButtonClicked. And let's pass a BSTR. You could pass anything. I guess you should have arguments that are pertinent to button clicks. Well figure it out.

Now here comes the tricky part. I always goof up here and tend o forget what needs to be done to create a connection point. You need to compile the project. I always forget to do this and then wonder why the following steps do not work. Now in class view right click on CConCtl and then select "Implement Connection Point". You will be shown a dialog box.

Check IConnCtlEvents and click OK. Now VC++ implements connection points for you. In class view you will see that CProxy_IConnCtlEvents< class T> is created and it provides Fire_OnControlButtonClicked(BSTR someStr). Next, to make connection points work, that is for your code to let its container know that the button has been clicked we add Fire_OnControlButtonClicked(BSTR someStr) to the Windows message handling function created earlier.

 

LRESULT CConnCtl::OnClickedButton(WORD wNotifyCode, 
        WORD wID, HWND hWndCtl, BOOL& bHandled) {
    ::MessageBox( hWndCtl, "Button was clicked", 
        "Handled in Control", MB_OK );

    Fire_OnControlButtonClicked( CComBSTR( 
           "This message has been fired to the container" ) );

    return 0;
}

Now compile the project and if everything goes as designed you should get a few compile errors saying something along the lines that IID__IConnCtlEvents could not be found. If that is the case make IID__IconnCtlEvents in ConnCTL.h as shown below. I have always wondered if this is a problem on my installation of VC++ or a VC++ bug.

 

BEGIN_CONNECTION_POINT_MAP(CConnCtl)
    CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink)
    CONNECTION_POINT_ENTRY(DIID__IConnCtlEvents)
END_CONNECTION_POINT_MAP()

You now have a control that handles the windows click button event and passes that event on as defined by you (This is very cool. You the developer get to decide how this event is fired and what information is sent to the container). If you place this control in a VB form you will be able to catch the button click event fired by ConnCtl as follows:

 

Private Sub ConnCtl1_OnControlButtonClicked( ByVal someStr As String )
    'Now the container can do further processing once the button is clicked.
End Sub

 

Only Windows Messages?

Are connection points used just to pass on Windows Messages? No. Connection Points are a way for a COM object, server or control to provide an interface via which other objects, applications etc can receive notifications of events. For a more detailed explanation of how connection points work please refer to Code Project/COM / DCOM - Connection Points And Asynchronous calls - Part I and read ATL Internals by Brent Rector and Chris Sells.

So lets suppose that not only did we want to let the control container know when we click the button but also when we clicked it for the 10th time. The process to set this up is very simple. Once again in class view right click on _IconnCtlEvents and select the option to add a method. Let's call this one OnTenthClick. Once again compile the project. Then right-click on CConCtl and then select "Implement Connection Point". Follow the steps mentioned above. Now you have the ability to provide the container with an interface that will notify the container when the user has clicked 10 times. Well not really. All you have done is create an interface that has that name. Now you must count the clicks and when you reach ten you must call Fire_OnTenthClick().

LRESULT CConnCtl::OnClickedButton(WORD wNotifyCode, 
         WORD wID, HWND hWndCtl, BOOL& bHandled) {
    ::MessageBox( hWndCtl, "Button was clicked", 
          "Handled in Control", MB_OK );

    Fire_OnControlButtonClicked( CComBSTR( 
          "This message has been fired to the container" ) );

    ClickCounter();  //Do stuff with how many times 
           //the button has been clicked

    return 0;
}

void CConnCtl::ClickCounter() {
    _clickCount++;

    if( 10 == _clickCount ) {
        Fire_OnTenthClick( CComBSTR( "Button has been clicked 10 times" ) );
    }
}

Conclusion

Connection Points are a great mechanism to handle events and are very easy to implement in VC++ using ATL (except for some non-intuitive steps). Please note that connection points can be created for any COM object and not just controls.

Download source files - 10.1 Kb

 

 

Copyright ?1998-2009 UCanCode.Net Software , all rights reserved.
Other product and company names herein may be the trademarks of their respective owners.

Please direct your questions or comments to webmaster@ucancode.net