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

This article describes the process for accessing the exposed methods and properties of embedded ActiveX controls.

Important

ActiveX is a legacy technology that should not be used for new development. For more information about modern technologies that supersede ActiveX, see 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 Circ sample control, Circ, will be added to the resulting project.

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

Procedures

To add the Circ control to the dialog template

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

  2. Click the Resource View tab.

  3. Open the Dialog folder.

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

  5. Click the Circ control icon on the Toolbox.

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

  7. From the File menu, choose Save All to save all modifications to the dialog box template.

Modifications to the Project

To enable the Container application to access the Circ control, Visual C++ automatically adds the wrapper class (CCirc) implementation file (.CPP) to the Container project and the wrapper class header (.H) file to the dialog box header file:

#include "circ.h"

The Wrapper Class Header (.H) File

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

class CCirc : public CWnd
{
// Functions
//

void AboutBox()
{
   InvokeHelper(DISPID_ABOUTBOX, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
}

// Properties
//

unsigned long GetBackColor()
{
   unsigned long result;
   GetProperty(DISPID_BACKCOLOR, VT_UI4, (void*)& result);
   return result;
}
void SetBackColor(unsigned long propVal)
{
   SetProperty(DISPID_BACKCOLOR, VT_UI4, propVal);
}
signed char GetCircleShape()
{
   signed char result;
   GetProperty(0x1, VT_I1, (void*)& result);
   return result;
}
void SetCircleShape(signed char propVal)
{
   SetProperty(0x1, VT_I1, propVal);
}
short GetCircleOffset()
{
   short result;
   GetProperty(0x3, VT_I2, (void*)& result);
   return result;
}
void SetCircleOffset(short propVal)
{
   SetProperty(0x3, VT_I2, propVal);
}
CString GetCaption()
{
   CString result;
   GetProperty(DISPID_CAPTION, VT_BSTR, (void*)& result);
   return result;
}
void SetCaption(CString propVal)
{
   SetProperty(DISPID_CAPTION, VT_BSTR, propVal);
}
COleFont GetFont()
{
   LPDISPATCH result;
   GetProperty(DISPID_FONT, VT_DISPATCH, (void*)& result);
   return COleFont(result);
}
void SetFont(LPDISPATCH propVal)
{
   SetProperty(DISPID_FONT, VT_DISPATCH, propVal);
}
unsigned long GetForeColor()
{
   unsigned long result;
   GetProperty(DISPID_FORECOLOR, VT_UI4, (void*)& result);
   return result;
}
void SetForeColor(unsigned long propVal)
{
   SetProperty(DISPID_FORECOLOR, VT_UI4, propVal);
}
CString GetNote()
{
   CString result;
   GetProperty(0x4, VT_BSTR, (void*)& result);
   return result;
}
void SetNote(CString propVal)
{
   SetProperty(0x4, VT_BSTR, propVal);
}
unsigned long GetFlashColor()
{
   unsigned long result;
   GetProperty(0x2, VT_UI4, (void*)& result);
   return result;
}
void SetFlashColor(unsigned long propVal)
{
   SetProperty(0x2, VT_UI4, propVal);
}
};

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 Visual C++. You can then use the member variable to access the embedded control at any time.

When the Add Member Variable dialog box adds the m_circctl member variable to the project, it also adds the following lines to the header file (.H) of the CContainerDlg class:

class CContainerDlg : public CDialog
{
   DECLARE_DYNAMIC(CContainerDlg)

public:
   CContainerDlg(CWnd* pParent = NULL);   // standard constructor
   virtual ~CContainerDlg();

   virtual void OnFinalRelease();

   // Dialog Data
   enum { IDD = IDD_CONTAINER_DIALOG };

protected:
   virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

   DECLARE_MESSAGE_MAP()
   DECLARE_DISPATCH_MAP()
   DECLARE_INTERFACE_MAP()
public:
   CCirc m_circctl;
};

In addition, a call to DDX_Control is automatically added to the CContainerDlg's implementation of DoDataExchange:

DDX_Control(pDX, IDC_CIRCCTRL1, m_circctl);

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 CCirc wrapper class, in this case CIRC.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_circctl member variable to modify the Caption and CircleShape properties of the embedded Circ control:

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

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

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

See also

ActiveX Control Containers