ActiveX Controls: Using Pictures in an ActiveX Control

OverviewHow Do IFAQSample

This article describes the common Picture type and how to implement it in your ActiveX control. Topics include:

  • Overview of custom Picture properties

  • Implementing a custom Picture property in your ActiveX Control

Overview of Custom Picture Properties

A Picture type is one of a group of types common to all ActiveX controls. The Picture type handles metafiles, bitmaps, or icons and allows the user to specify a picture to be displayed in an ActiveX control. Custom Picture properties are implemented using a picture object and Get/Set functions that allow the control user access to the Picture property. Control users access the custom Picture property using the stock Picture property page.

In addition to the standard Picture type, Font and Color types are also available. For more information on using the standard Font type in your ActiveX control, see the article ActiveX Controls: Using Fonts in an ActiveX Control.

The ActiveX control classes provide several components you can use to implement the Picture property within the control. These components include:

  • The class.

    This class provides easy access to the picture object and functionality for the item displayed by the custom Picture property.

  • Support for properties of type LPPICTUREDISP, implemented with Get/Set functions.

    Using ClassWizard you can quickly add a custom property, or properties, that supports the Picture type. For more information on adding ActiveX control properties with ClassWizard, see the article ActiveX Controls: Properties.

  • A property page that manipulates a control’s Picture property or properties.

    This property page is part of a group of stock property pages available to ActiveX controls. For more information on ActiveX control property pages, see the article ActiveX Controls: Using Stock Property Pages

Implementing a Custom Picture Property in Your ActiveX Control

When you have completed the steps outlined in this section, the control can display pictures chosen by its user. The user can change the displayed picture using a property page that shows the current picture and has a Browse button that allows the user to the select different pictures.

A custom Picture property is implemented using a process similar to that used for implementing other properties, the main difference being that the custom property must support a Picture type. Because the item of the Picture property must be drawn by the ActiveX control, a number of additions and modifications must be made to the property before it can be fully implemented.

To implement a custom Picture property, you must do the following:

  • Add code to your control project.

    A standard Picture property page ID, a data member of type CPictureHolder, and a custom property of type LPPICTUREDISP with a Get/Set implementation must be added.

  • Modify several functions in your control class.

    These modifications will be made to several functions that are responsible for the drawing of your ActiveX control.

Additions to Your Control Project

To add the property page ID for the standard Picture property page, insert the following line after the BEGIN_PROPPAGEIDS macro in the control implementation file (.CPP):

PROPPAGEID(CLSID_CPicturePropPage)

You must also increment the count parameter of your BEGIN_PROPPAGEIDS macro by one. The following line illustrates this:

BEGIN_PROPPAGEIDS(CSampleCtrl, 2)

To add the CPictureHolder data member to the control class, insert the following line under the protected section of the control class declaration in the control header file (.H):

CPictureHolder    m_pic;

It is not necessary to name your data member m_pic; any name will suffice.

Next, add a custom property that supports a Picture type:

To add a custom picture property using ClassWizard

  1. With your control project open, open ClassWizard by clicking ClassWizard on the View menu.

  2. Click the Automation tab.

  3. Click Add Property.

  4. In the External name box, type the property name. For example purposes, ControlPicture is used in this procedure.

  5. In the Implementation box, click Get/Set Methods.

  6. In the Return Type box, select LPPICTUREDISP for the property type.

  7. Type unique names for your Get and Set Functions or accept the default names. (In this example, the default names GetControlPicture and SetControlPicture are used.)

  8. Click OK to close the Add Property dialog box.

  9. Click OK to confirm your choices and close ClassWizard.

ClassWizard adds the following code between the dispatch map comments in the control header (.H) file:

afx_msg LPPICTUREDISP GetControlPicture();
afx_msg void SetControlPicture(LPPICTUREDISP newValue);

In addition, the following code was inserted in the dispatch map of the control implementation (.CPP) file:

DISP_PROPERTY_EX(CSampleCtrl, "ControlPicture", GetControlPicture, SetControlPicture, VT_PICTURE)

ClassWizard also adds the following two stub functions in the control implementation file:

LPPICTUREDISP CSampleCtrl::GetControlPicture()
{
    // TODO: Add your property handler here

    return NULL;
}

void CSampleCtrl::SetControlPicture(LPPICTUREDISP newValue)
{
    // TODO: Add your property handler here

    SetModifiedFlag();
}

Note   Your control class and function names might differ from the example above.

Modifications to Your Control Project

Once you have made the necessary additions to your control project, you need to modify several functions that affect the rendering of your ActiveX control. These functions, OnResetState, OnDraw, and the Get/Set functions of a custom Picture property, are located in the control implementation file. (Note that in this example the control class is called CSampleCtrl, the CPictureHolder data member is called m_pic, and the custom picture property name is ControlPicture.)

In the control OnResetState function, add the following optional line after the call to COleControl::OnResetState:

m_pic.CreateEmpty();

This sets the control’s picture to a blank picture.

To draw the picture properly, make a call to in the control OnDraw function. Modify your function to resemble the following example:

void CSampleCtrl::OnDraw(
    CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
// ****** Add your code below this line ********** //
   m_pic.Render(pdc, rcBounds, rcBounds);
}

In the Get function of the control’s custom picture property, add the following line:

return m_pic.GetPictureDispatch();

In the Set function of the control’s custom Picture property, add the following lines:

m_pic.SetPictureDispatch(newValue);
InvalidateControl();

The picture property must be made persistent so that information added at design time will show up at run time. Add the following line to the COleControl-derived class's DoPropExchange function:

PX_Picture(pPX, "ControlPicture",m_pic);

Note   Your class and function names might differ from the example above.

After you complete the modifications, rebuild your project to incorporate the new functionality of the custom Picture property and use Test Container to test the new property.

See Also   ActiveX Controls: Using Fonts in an ActiveX Control, ActiveX Controls: Property Pages