Table of contents
1.
Introduction
1.1.
Event Handling
1.2.
Principles of Event Handling
2.
Event Handling using IDispEventImpl
2.1.
Example
3.
Frequently Asked Questions
3.1.
Name a few C++ standard library files.
3.2.
What is an Event?
3.3.
Briefly describe ATL.
3.4.
Where do we find ATL?
3.5.
Define ActiveX Controls.
4.
Conclusion
Last Updated: Mar 27, 2024
Medium

Event Handling using IDispEventImpl

Author Rupal Saluja
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

We know that ATL stands for Active Template Library. It is a library with numerous classes that permit you to use, manipulate and implement Windows. It provides an impressive implementation that would not cause overhead on your code.

ATL includes a set of template-based C++ classes that simplify the programming of Component Object Model (COM) objects. COM is a necessary specification used in creating and consuming software components on Windows. It is highly recommended when you want to use ATL Window Classes to their fullest extent.

logo of window

This article will discuss several aspects of one of the most important topics of Implementing the Event Handling Interface- Event Handling using IDispEventImpl.

Event Handling

Event Handling is the process of using, managing, and controlling events. Now, what are events?

Events notify the clients that some changes have been made in the object, such as a user clicking the button or a property change being occurred. Events are extremely useful with COM controllers.

If we create standard COM objects, we give implementations for interfaces along with them. Such implementations ease the creation of incoming interfaces.

Principles of Event Handling

The three guiding principles of Event Handling around which the whole process involves are:

  • Adding the event interface.
  • Informing the event source about the acceptance of events.
  • Notifying the event source when no longer events are required.

Event Handling using IDispEventImpl

When handling events using IDispEventImpl, we will cover the following points.

  • Deriving class from the IDispEventImpl class.
  • Incorporating an event sink map into your class.
  • Adding entries to the event sink map using the SINK_ENTRY or SINK_ENTRY_EX macro.
  • Implementing the methods that you want to handle.
  • Advising and unadvising the event source.
     

Let us see an example to understand the above steps better.

notion of event handling

Example

The example below shows how to handle the FileChange event initiated by a Word’s Application object. This event is present as a method on the AppEvents dispinterface. Use the C++ code below to start with the implementation.

[ uuid(000809F4-0000-0000-C000-000000000059), hidden ]
dispinterface AppEvents
{
properties:
methods:
    [id(0x00000001), restricted, hidden]
    void Start();

    [id(0x00000002)]
    void End();

    [id(0x00000003)]
    void FileChange();
};


We will import several packages and files to produce the necessary header files. Suppose you want to use this code in other versions of the Word other than the latest version. In that case, it is compulsory to specify the accurate mso dll file. Use the C++ code below to start importing.

//pragma warnings to handle exceptions
#pragma warning (disable : 4146)

// Paths to the necessary files
// replacing "MSO.DLL" and "MSEXAMPLE.OLB" with the original paths
#define _PATH "MSO.DLL"
// Delete *.tlh files when altering import qualifiers
#import _PATH rename("RGB", "RGBOriginal") rename("DocumentProperties", "Properties") raw_interfaces_only
#import "C:\Program Files\Files\Shared\VBA\VBA4\VBE4EXT.OLB" raw_interfaces_only
#define _B_PATH "EXAMPLE.OLB"
#import _B_PATH rename("ExitWindows", "Quit") rename("FindText", "Search") raw_interfaces_only
#pragma warning (default : 4146)


Use the C++ code below to continue with the implementation. The comments added can be referred in case of any doubt.

// Generating a LIBID manually
namespace Example
{
   struct __declspec(uuid("000809F4-0000-0000-C000-000000000059"))
      Library;
};

class ATL_NO_VTABLE Simple : 
   public CComObjectRootEx<CComSingleThreadModel>,
   public CComCoClass<CSimple, &CLID_Simple>,
   public IDispatchImpl<ISwitch, &ID_ISwitch, &LIBID_EVENTLib>,
   //Inheritance from IDispEventImpl
   public IDispEventImpl</*nID*/ 1, CSimple, &__uuidof(Example::AppEvents2), &__uuido
   f(Example::Library), /*wMajor*/ 8, /*wMinor*/ 1>
   {
       public:
       CSimple()
       {
       }
       
   DECLARE_RESOURCEID(IDR_SIMPLE)
   DECLARE_FINAL_CONSTRUCT()

   BEGIN_MAP(CSimple)
       INTERFACE_ENTRY(ISwitch)
       INTERFACE_ENTRY(IDispatch)
   END_MAP()
   CComPtr<Example::_Application> m_App;
   
   // Event handlers
   void __call OnQuit()
   {
      Stop();
   }
   void __call OnDocChange()
   {
      ASSERT(m_App != NULL);
      // Fixing a pointer to the interface
      CComPtr<Example::_Document> pD;
      m_App->get_ActiveDocument(&pD);

      CComBSTR bName;
      if (pD)
        pD->get_Name(&bName);

      // Creating a string
      CComBSTR bDisplay(_T("New title:\n"));
      bDisplay += bName;

      // Display the name to the user
      USES_CONVERSION;
      MessageBox(NULL, W2CT(bDisplay), _T("IDispEventImpl :Document Changed"), M
      _OK);
   }
   
  // Fixing the mapping
  BEGIN_MAP(CSimple)
     SINK_ENTRY_EX(/*nID =*/ 1, __uuidof(Example::ApplicationEvents2), /*dispid =*/ 3,
     OnDocChange)
     SINK_ENTRY_EX(/*nID =*/ 1, __uuidof(Example::ApplicationEvents2), /*dispid =*/ 2,
     OnQuit)
  END_MAP()
  
  // ISwitch
  public:
     STD(Start)()
     {
        // If object is already present, return
        if (m_App)
         return OK;

        // Creating an instance
        RESULT r = m_App.CoCreateInstance(__uuidof(Example::Application), NULL, CLSC
        TX_SERVER);
        if (FAILED(r))
            return r;
       
         ASSERT(m_App != NULL);
        // Make the Example interface visible
        m_App->put_Visible(true);
        
       // Note call to advise
       // Forge a connection to enable us to receive events
       DispEventAdvise(m_App);
           return OK;
    }
    STD(Stop)()
    {
       // Checking if we have to unadvise an object
       if (!m_App)
         return OK;
         
       // Notifying unadvise
       DispEventUnadvise(m_App);

      // Releasing the application
      m_App.Release();

      return OK;
   }
};

Frequently Asked Questions

Name a few C++ standard library files.

A few C++ standard library files are the General Utilities Library, Standard String Templates Library, and the Diagnostics Library.

What is an Event?

An Event is a result of user interaction with the GUI components.

Briefly describe ATL.

ATL stands for Active Template Library. It is a library with numerous classes that permit you to use, manipulate and implement Windows. It provides an impressive implementation that would not cause overhead on your code.

ATL includes a set of template-based C++ classes that simplify the programming of Component Object Model (COM) objects.

Where do we find ATL?

We find ATL in Microsoft Visual Studio. If you do not have Visual Studio in your system, you will get the ATL libraries from one of Visual C++ Microsoft’s Redistributable packages.

Define ActiveX Controls.

Computer Component Objects created by Microsoft are known as ActiveX Controls. They permit applications to execute particular tasks. Any ActiveX Control is a short program that other applications can use to offer the same functionality without additional development and programming.

Conclusion

On the whole, we understood the aspects of Event Handling using IDispEventImpl. We also learned some points regarding Event Handling. 

We hope the above discussion helped you understand the concepts of ATL Window Classes and can be used for reference whenever needed. To learn more about Windows, you can refer to blogs on the Windows Operating SystemFeatures of the Windows Operating SystemWindows FormsJavaScript Window, and Sliding Window Protocol.

Visit our website to read more such blogs. Make sure you enroll in our courses, take mock tests, solve problems, and interview puzzles. Also, you can pay attention to interview stuff- interview experiences and an interview bundle for placement preparations. Do upvote our blog to help fellow ninjas grow.

Happy Coding!

Live masterclass