Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / productivity / Office

VBA Composite Control Object Model

5.00/5 (2 votes)
25 Feb 2011Ms-PL4 min read 28.9K   454  
A method for managing complex, event-driven interactions between controls
screenshot.JPG

Introduction

The VBA Composite Control Object Model encapsulates event-driven interactions between controls and objects in Visual Basic for Applications. By encapsulating complex control interactions, standard Office ActiveX controls and other objects may be used to create new "controls" with custom special effects, or enhanced functionality (like adding a RecordSource to a TabControl).

Background

This project was initially developed out of an interest in creating dynamic callbacks for ActiveX controls in Microsoft Access using the WithEvents keyword.

You can find my original blogs about the project on the Microsoft Access Team Blog:

You can also visit the Codeplex site established for this project.

To date, the project has been developed entirely in Microsoft Access VBA. However, effort has been made to make the code as generic as possible to facilitate implementation in other Microsoft Office products or 3rd party applications which support VBA.

Ultimately, the code lives entirely within VBA. That is, a chief project requirement is that all functionality be maintained entirely in VBA code. No add-ins, DLLs, or other external 3rd party solutions allowed. This includes avoiding adding project references and limited use of the WinAPI. The chief reason behind this decision was to make the object model suitable for implementation in environments with restrictive IT policies toward macros.

Using the Code

Since the project is more about developing an object model than it is about creating widgets, it's a bit difficult to cite code examples in a meaningful way. The Codeplex tutorials provide some in-depth examples of developing composite controls and event handlers.

Briefly, the object model consists of the following elements:

Interfaces

Interfaces make it possible to cast a variety of Composite Control classes to a generic type, exposing core members and eliminating the need to rely on late-bound VBA data types (Object and Variant) and slow VBA calling functions (CallByName(), Application.Run(), etc.). Employing interfaces to facilitate early binding can realize performance increases on an order of magnitude over late-bound techniques.

Interfaces implemented in the object model include:

  • iControl_Base - Defines basic properties (Name, ID, and ControlType) common to all Composite Control classes.
  • iControl - Defines members specific to cControl and cControl_EventHandler classes.
  • iControl_EventHandler - Defines members specific to the cControl_EventHandler class.
  • iCallback - Defines members specific to the cCallback class.

Classes

The object model lives in its classes. The class hierarchy is characterized by a shallow structure, lending itself to simpler memory management and reduced code modules. Further, the object model is designed to be modular with a core extended only with the classes required by a given project.

Classes core to the object model include:

  • cCompositeControl - Top-level management class.
  • cCompositeControlManager - Instanced in the cCompositeControls object, this class creates / initializes cControl and cControl_EventHandler objects.
  • cControl - Workhorse of the object model. This class encapsulates the event-driven interactions between objects of any variety, whether they are ActiveX controls, Composite Controls or something else!
  • cControl_EventHandler - A special case of the cControl class. The cControl_EventHandler class acts as a delegator for declared events.
  • cControlChild_Event - A child class to the cControl_EventHandler class. This class provides the actual delegation, executing callbacks registered with the class instance when it's associated event is triggered.
  • cCallback - Class which provides callback functions which may be registered with a cControlChild_Event class delegator.

Support Modules

The support modules serve as a repository for functions called across the classes, or functions specific to a class that do not need to be contained within the class. Using support modules provides a way to reduce the amount of code in a class thus reducing memory demands and overall loading time. Support modules are specific to the individual classes to encourage modularity, with only two modules serving as general-purpose repositories for functions, enumerations, data types, and constants.

Also contained in the support modules are the creation functions. Simply, a creation function is a publicly available function that is specific to the type of Composite Control it creates. The implementation of this type of function encapsulates the code needed to create / initialize / configure a composite control in a single line of code at the Form level.

Points of Interest

Some key ideas that come from OOP were implemented to make the object model work. First is the concept of delegation. It works and works well. Second was the implementation of interfaces to allow for "casting" of the classes. This ability to cast a class to a more generic interface type is what allows the object model to maintain its ability to interact with almost any type of object while circumventing slower late-binding techniques typically required to interface with unknown object types.

History

Improvements from the alpha release include prolific implementation of interfaces, reduction / reorganization of code modules, and a more robust implementation of the Object Monitor development tool. Also notable is the absence of the cControl_Binder class in the Beta release, pending the development of a more robust implementation, the cDataSource class.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)