ActiveX Control Containers: Programming ActiveX Controls in an ActiveX Control Container

OverviewHow Do ISample

This article describes the process for accessing the exposed methods and properties of embedded ActiveX controls. Basically, you will follow these steps:

  1. Insert an ActiveX control into the ActiveX container project using Gallery.

  2. Define a member variable (or other form of access) of the same type as the ActiveX control wrapper class.

  3. Program the ActiveX control using predefined member functions of the wrapper class.

For this discussion, assume you’ve created a dialog-based project (named Container) with ActiveX control support. The Circ2 sample control, Circ2, will be added to the resulting project.

Once the Circ2 control is inserted into the project (step 1), insert an instance of the Circ2 control into the application’s main dialog box.

To add the Circ2 control to the dialog template

  1. Load the ActiveX control container project. For this example, use the Container project.

  2. Click ResourceView in the Project Workspace window.

  3. Open the Dialog folder.

  4. Double-click the main dialog box template. For this example, use IDD_CONTAINER_DIALOG.

  5. Click the Circ2 control icon on the Controls toolbar.

  6. Click a spot within the dialog box to insert the Circ2 control.

  7. On the File menu, click Save All to save all modifications to the dialog box template.

Modifications to the Project

To enable the Container application to access the Circ2 control, Gallery automatically adds the wrapper class (CCirc2) implementation file (.CPP) to the Container project and the wrapper class header (.H) file to the dialog box implementation file:

//{{AFX_INCLUDES(CContainerDlg)
#include "circ2.h"
//}}AFX_INCLUDES
// ContainerDlg.cpp : implementation file
//

The Wrapper Class Header (.H) File

To get and set properties (and invoke methods) for the Circ2 control, the CCirc2 wrapper class provides a declaration of all exposed methods and properties. In the example, these declarations are found in CIRC2.H. The following sample is the portion of class CCirc2 that defines the exposed interfaces of the ActiveX control:

class CCirc2 : public CWnd
{
...
// Attributes
public:
   OLE_COLOR GetBackColor();
   void SetBackColor(OLE_COLOR);
   BOOL GetCircleShape();
   void SetCircleShape(BOOL);
   short GetCircleOffset();
   void SetCircleOffset(short);
   unsigned long GetFlashColor();
   void SetFlashColor(unsigned long);
   BSTR GetCaption();
   void SetCaption(LPCTSTR);
   LPFONTDISP GetFont();
   void SetFont(LPFONTDISP);
   OLE_COLOR GetForeColor();
   void SetForeColor(OLE_COLOR);
   CString GetNote();
   void SetNote(LPCTSTR);

// Operations
public:
   void AboutBox();
};

These functions can then be called from other of the application’s procedures using normal C++ syntax. For more information on using this member function set to access the control’s methods and properties, see the section Programming the ActiveX control.

Member Variable Modifications to the Project

Once the ActiveX control has been added to the project and embedded in a dialog box container, it can be accessed by other parts of the project. The easiest way to access the control is to create a member variable of the dialog class, CContainerDlg (step 2), that is of the same type as the wrapper class added to the project by Gallery. You can then use the member variable to access the embedded control at any time.

When ClassWizard adds the m_circ2ctl member variable to the project, it also adds the following lines to the header file (.H) of the CContainerDlg class:

class CContainerDlg : public CDialog
{
// Construction
public:
   CContainerDlg(CWnd* pParent = NULL);   // standard constructor

// Dialog Data
   //{{AFX_DATA(CContainerDlg)
   enum { IDD = IDD_CONTAINER_DIALOG };
   CCirc2   m_circ2ctl;
   //}}AFX_DATA
};

In addition, ClassWizard adds a DDX_Control call to the CContainerDlg’s implementation of DoDataExchange:

DDX_Control(pDX, IDC_CIRC2CTRL1, m_circ2ctl);

Programming the ActiveX Control

At this point, you have inserted the ActiveX control into your dialog template and created a member variable for it. You can now use common C++ syntax to access the properties and methods of the embedded control.

As noted (in The Wrapper Class Header (.H) File), the header file (.H) for the CCirc2 wrapper class, in this case CIRC2.H, contains a list of member functions that you can use to get and set any exposed property value. Member functions for exposed methods are also available.

A common place to modify the control’s properties is in the OnInitDialog member function of the main dialog class. This function is called just before the dialog box appears and is used to initialize its contents, including any of its controls.

The following code example uses the m_circ2ctl member variable to modify the Caption and CircleShape properties of the embedded Circ2 control:

BOOL CContainerDlg::OnInitDialog()
{
   CDialog::OnInitDialog();

   // Add "About..." menu item to system menu.

   // IDM_ABOUTBOX must be in the system command range.
   ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
   ASSERT(IDM_ABOUTBOX < 0xF000);

   CMenu* pSysMenu = GetSystemMenu(FALSE);
   CString strAboutMenu;
   strAboutMenu.LoadString(IDS_ABOUTBOX);
   if (!strAboutMenu.IsEmpty())
   {
      pSysMenu->AppendMenu(MF_SEPARATOR);
      pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
   }

   m_circ2ctl.SetCaption(_T("Circ 2 Control"));
   if( !m_circ2ctl.GetCircleShape())
      m_circ2ctl.SetCircleShape(TRUE);

   return TRUE;  // return TRUE  unless you set the focus to a control
}