Implementing the Property Page

In Adding the Property Page, you used the Microsoft® Visual C++® user interface to add a property page to the MinMaxShip project. This task also involved creating the controls for the MinMaxShip component’s properties on the default dialog box that Visual C++ created for you.

When you add a property page to a project, Visual C++ creates the class definition and implementation files for the class that is intended to manage your property page. The class definition and implementation for the MinMaxShip project’s property pages appears in the MinMaxShipPropPg.h and MinMaxShipPropPg.cpp files, respectively.

The MinMaxShipPropPg.h file contains the definition for the CMinMaxShipPropPg class. This class inherits from the IPropertyPagesImpl interface, which supports default implementations of the Apply and Activate methods. The Activate method is called by the Win32®-based Pipeline Editor when the property pages for a component are displayed. The Apply method is called when the user clicks the Apply button. Implementing a property page generally involves overriding the default implementation of these two methods.

If you open CMinMaxPropPg.h, and you see the following stub implementation of the Apply method:

    STDMETHOD(Apply)(void)
    {
        ATLTRACE(_T("CMinMaxPropPg::Apply\n"));
        for (UINT i = 0; i < m_nObjects; i++)
        {
            // Do something interesting here
            // ICircCtl* pCirc;
            // m_ppUnk[i]->QueryInterface(IID_ICircCtl, (void**)&pCirc);
            // pCirc->put_Caption(CComBSTR("something special"));
            // pCirc->Release();
        }
        m_bDirty = FALSE;
        return S_OK;
    }

};

To implement this method for the MinMaxShip component, replace this implementation of Apply with the following:

STDMETHODIMP (Apply)(void)
{

    HRESULT hRes = S_OK;
    ATLTRACE(_T("CMinMaxPropPg::Apply()"));
    CComBSTR bstrMinShipping;
    CComBSTR bstrPercentage;

    VariantInit(&varbstrMinShipping);
    VariantInit(&varbstrPercentage);
    VariantInit(&varMinShipping);
    VariantInit(&varPercentage);


    for(UINT i = 0; i < 1; i++){

    ComQIPtr<IMinMaxShipping,     &IID_IMinMaxShipping>pMinMaxShipping(m_ppUnk[i]);

    GetDlgItemText(IDC_MINSHIPPING, bstrMinShipping.m_str);
    GetDlgItemText(IDC_PERCENTAGE, bstrPercentage.m_str);

    V_BSTR(&varbstrMinShipping) = SysAllocString(bstrMinShipping.m_str);
    V_VT(&varbstrMinShipping) = VT_BSTR;

    V_BSTR(&varbstrPercentage) = SysAllocString(bstrPercentage.m_str);
    V_VT(&varbstrPercentage) = VT_BSTR;

    hRes = VariantChangeType(&varMinShipping, &varbstrMinShipping, 0,                     VT_I4);

    if(FAILED(hRes))
        return hRes;
        
    hRes = VariantChangeType(&varPercentage, &varbstrPercentage, 0,                         VT_R4);

    if(FAILED(hRes))
        return hRes;

    pMinMaxShipping->put_MinShipping(varMinShipping.lVal);
    pMinMaxShipping->put_Percentage(varPercentage.fltVal);

    VariantClear(&varbstrPercentage);
    VariantClear(&varbstrMinShipping);
    VariantClear(&varMinShipping);
    VariantClear(&varPercentage);

}

    m_bDirty = FALSE;
    return S_OK;
}

The sole purpose of this Apply implementation is to retrieve the values that the user has typed in the dialog box controls that you created in Adding the Property Page, and to write them to the variables in which MinMaxShip stores its property values.

To do this, the code retrieves the new property settings from the dialog box, gets an interface pointer on the component’s IMinMaxShipping implementation, and uses this pointer to call the put_MinShipping and put_Percentage methods that you implemented in Step 3: Adding Propertiescom_writingcomponents_RHDQ.

When you implement the Activate method, you simply perform the same operation in reverse: that is, you use the get_MinShipping and get_Percentage methods to write the component’s properties to local variables, and you display these variable values in the appropriate property page dialog box controls.

Note

Because most components can simply use IPropertyPagesImpl’s default implementation of Activate, Visual C++ does not include a stub implementation of this method in your property pages class when you add the property page to your project. You must add the entire method implementation yourself.

Here is the MinMaxShip component’s Activate implementation.

STDMETHODIMP (Activate)(HWND hWndParent, LPCRECT pRect, BOOL fModal)
{
    
HRESULT hRes = IPropertyPageImpl<CMinMaxPropPg>::Activate(hWndParent,     pRect, fModal);
    
if(SUCCEEDED(hRes)){

    ATLTRACE(L"Created object");
    CComQIPtr<IMinMaxShipping,                                                     &IID_IMinMaxShipping>pMinMaxShipping(m_ppUnk[0]);

    VariantInit(&varMinShipping);
    VariantInit(&varPercentage);
    VariantInit(&varbstrMinShipping);
    VariantInit(&varbstrPercentage);

    pMinMaxShipping->get_MinShipping(&m_lMinShipping);
    pMinMaxShipping->get_Percentage(&m_fPercentage);

    V_I4(&varMinShipping) = m_lMinShipping;
    V_VT(&varMinShipping) = VT_I4;

    V_R4(&varPercentage) = m_fPercentage;
    V_VT(&varPercentage) = VT_R4;

    hRes = VariantChangeType(&varbstrMinShipping, &varMinShipping, 0,                 VT_BSTR);

    if(FAILED(hRes))
        return hRes;

    hRes = VariantChangeType(&varbstrPercentage, &varPercentage, 0,                 VT_BSTR);
    ATLTRACE(varbstrPercentage.bstrVal);

    if(FAILED(hRes))
        return hRes;

    SetDlgItemText(IDC_MINSHIPPING, varbstrMinShipping.bstrVal);
    SetDlgItemText(IDC_PERCENTAGE, varbstrPercentage.bstrVal);

    VariantClear(&varbstrMinShipping);
    VariantClear(&varbstrPercentage);
    VariantClear(&varPercentage);
    VariantClear(&varMinShipping);

    }

    return S_OK;
}

Next, you need to include a handler that Microsoft® Windows NT® can notify when the user modifies a value in the property page.

LRESULT OnChange(WORD wNotify, WORD wID, HWND hWnd, BOOL& bHandled);

The OnChange handler is not a member of IPropertyPageImpl. It is included to track the state of the controls in the property page. To enable this handler, add the following entry to the message map for the MinMaxPropPg class:

BEGIN_MSG_MAP(CMinMaxPropPg)
COMMAND_RANGE_HANDLER(IDC_MINSHIPPING, IDC_PERCENTAGE, OnChange);
CHAIN_MSG_MAP(IPropertyPageImpl<CMinMaxPropPg>)
END_MSG_MAP()

When the user changes a value in one of the edit controls on the dialog box previously displayed, Windows NT will invoke this handler. It is then appropriate to call the IPropertyPageImpl template's SetDirty method, as follows, in the CMinMaxPropPg implementation file:

LRESULT CMinmaxPropPg::OnChange(WORD wNotify, WORD wID, HWND hWnd, BOOL& bHandled)
{ 
    if (wNotify == EN_CHANGE)
        SetDirty(TRUE);
    return 0;
}

Finally, because the methods defined in the property page class need to access the properties of the component class (CMinMaxShip), you should add a reference to MinMaxShip.h in the MinMaxPropPg.h file that defines the property page class.

#include MinMaxShip.h

© 1997-1998 Microsoft Corporation. All rights reserved.