Step Seven: Implementing IPipelineComponent

All pipeline components must implement the IPipelineComponent interface. This interface is defined as follows:

// IPipelineComponent

STDMETHOD (Execute) (
    IDispatch*  pdispOrder,
    IDispatch*  pdispContext,
    LONG        lFlags,
    LONG*       plErrorLevel);

STDMETHOD (EnableDesign) (BOOL fEnable);

When the pipeline creates an instance of a component, it requests an interface pointer on the component’s IPipelineComponent implementation, and then uses that pointer to call the component’s Execute implementation. The pipeline passes the component an IDispatch pointer on the OrderForm or Transport Dictionary being passed through the pipeline, and an IDispatch pointer on the site’s pipe context. The pipe context is a Dictionary that contains references to objects and data that the site stores in the Application object, as well as to the built-in Active Server Pages (ASP) objects.

The IPipelineComponent interface is among the interfaces for which the Pipeline Component Wizard adds method definitions and implementation stubs when you add an object to your project. To implement IPipelineComponent::Execute for the MinMaxShip component, open the MinMaxShipping.cpp file, and modify the default implementation provided by the Pipeline Component Wizard.

For this example, the Execute method iterates through the items SimpleList on the OrderForm, and identifies the maximim list price in the list. The value of the MinShipping property is then compared to product of the maximum _product_list_price, multiplied by the Percentage property value, multiplied by -0.5. The maximum of these two values is then written to the OrderForm's _shipping_total name/value pair:

// IPipelineComponent
STDMETHODIMP CMinMaxShipping::Execute (
                IDispatch*  pdispOrder,
                IDispatch*  pdispContext,
                LONG        lFlags,
                LONG*       plErrorLevel)
{

HRESULT hr = S_OK;

IDictionary *pDictOrder = NULL;
ISimpleList *pListItems = NULL;
IDictionary *pDictItem = NULL;
long nItems;
long iItem;
int nListPrice;
int nMaxListPrice = 0;

long lMinShipping;
float fPercentage;

OPP_ERRORLEV ErrorLevel = OPPERRORLEV_FAIL;

if(pdispOrder == NULL)
    return E_INVALIDARG;

// Get the OrderForm Dictionary.

if(SUCCEEDED(hr=pdispOrder->QueryInterface(IID_IDictionary,     (void**)&pDictOrder)))
{

    VARIANT var;
    VariantInit(&var);

    // Make sure that the _shipping_total is not already set.

    hr = GetDictValue(pDictOrder, L"_shipping_total", &var);

    if(SUCCEEDED(hr) && (V_VT(&var) != VT_NULL))
        goto Out;

}

// Get an ISimpleList pointer on Items collection.

if(SUCCEEDED(hr = GetListItems(pDictOrder, &pListItems)))
    if(SUCCEEDED(hr = GetNumItems(pListItems, &nItems)))
    {

        // Get the largest price in the list.

        for(iItem = 0; iItem < nItems; iItem++)
        {

            if(FAILED(hr = GetNthItem(pListItems, iItem, &pDictItem)))
                goto Out;

            if(SUCCEEDED(GetDictValue(pDictItem, L"_product_list_price",                 &nListPrice)) &&     nListPrice > nMaxListPrice)

                nMaxListPrice = nListPrice;
                hr = S_OK;
        }

        // Get the minimum shipping and percentage from the CComVariant
        // members.

        this->get_MinShipping(&lMinShipping);
        this->get_Percentage(&fPercentage);

        hr = PutDictValue(pDictOrder, L"_shipping_total",
                max(lMinShipping, (int)(((float)nMaxListPrice *                             fPercentage) + 0.5)));

        if(SUCCEEDED(hr))
            ErrorLevel = OPPERRORLEV_SUCCESS;
        }

Out:
    if(plErrorLevel) *plErrorLevel = ErrorLevel;

    if(pDictOrder)
        pDictOrder->Release();

    if(pListItems)
        pListItems->Release();

    if(pDictItem)
        pDictItem->Release();
            
    return hr;

}

This implementation first queries the IDispatch interface on the OrderForm for an IDictionary pointer, and then passes this pointer to the PutDictValue function. The PutDictValue function is used to write the final shipping price to the OrderForm’s _shipping_total name/value pair.

The PutDictValue method used in this example is contained in the computil.cpp file. This file contains a collection of utility functions that facilitate working with Dictionary and OrderForm objects. When you use the Pipeline Component Wizard to add an object to a project, computil.h and computil.cpp are automatically added to the project for you, and an include directive referencing computil.h is added to your object’s implementation file.


© 1997-1998 Microsoft Corporation. All rights reserved.