Siebel Pharma Handheld Guide > COM Extensibility > Process of Implementing a SCEC >

Modifying SCEC Files


This task is a step in Process of Implementing a SCEC.

To modify SCEC files

  1. Open and modify the .cpp file generated by the ATL wizard (for example, SampleSCEC.cpp) by including one or more appropriate _i.c files.

    For example:

    #include "application_ev_i.c"

    #include "buscomp_ev_i.c"

    #include "service_ev_i.c"

    #include "applet_ev_i.c"

  2. Open the stdafx.cpp file, and add the following code above #include "stdafx.h":

    #define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA

  3. Modify the .idl files (for example, SampleSCEC.idl) as follows:
    1. Remove the definition of the interface generated by the ATL wizard. For example, remove the following code:

    import "oaidl.idl";

    import "ocidl.idl";

    import "atliface.idl";

    [

    object,

    uuid (D26E065A-3365-4A41-ACDE-486E98C204A8),

    helpstring ("ISampleSCEC Interface"),

    pointer_default (unique);

    ]

    Interface ISSampleSCEC : IUnknown{

    };

    1. Import the appropriate Siebel .idl files for the event to be implemented.

      For example, if you are implementing a business component SCEC, add the following:

    import "application_ar.idl";

    import "application_ev.idl";

    import "buscomp_ev.idl";

    1. Replace the automatically generated interface name (for example, ISampleSCEC) with the appropriate ISHCEXXXEvent interface. For example, if you are implementing a business component SCEC, change the interface name to ISHCEBusCompEvent. The final lines of code resemble the following:

    coclass SampleSCEC

    {

    [default] interface ISHCEBusCompEvent;

    };

    };

  4. Modify the SampleSCECObj.h file as follows:
    1. Add statements to include SampleSCEC.h and any Siebel templates for the implemented objects. For example:

    #include "SampleSCEC.h"

    #include "t_siebelscecbc.h"

    1. Add any events that you intend to implement to the class definition. Use the appropriate template according to the event. Possible events and templates are listed in the following table:
      Event
      Template

      Application events

      CSiebelSCECAppBase

      Business Component events

      CSiebelSCECBusCompBase

      Applet events

      CSiebelSCECAppletBase

      Service events

      CSiebelSCECServiceBase

      For example, to replace the ATL-generated class definition for CSampleSCEC, replace the following code:

    class ATL_NO_VTABLE CSampleSCEC :

    public CComObjectRootEx<CComMultiThreadModel>,

    public CComCoClass<CSampleSCEC, &CLSID_SampleSCEC>,

    public ISampleSCEC

    with this definition:

    class ATL_NO_VTABLE CSampleSCEC :

    public CSiebelSCECBusCompBase

    <CSampleSCEC, &CLSID_SampleSCEC,

    &LIBID_SampleSCECLib, IDR_SAMPLESCEC>

    Where:

    • The first parameter (CSampleSCEC) indicates the class name.
    • The second and third parameters hold class and library Ids, respectively, and are defined in the <ProjName>_i.c file.
    • The fourth parameter (IDR_xxx) is defined in the resourceppc.h file.
    1. Replace the ATL-generated interface name (for example, ISampleSCEC) with the appropriate ISHCEXXXEvent interface. For example:

    BEGIN_COM_MAP(CSampleSCEC)

    COM_INTERFACE_ENTRY(ISHCEBusCompEvent)

    END_COM_MAP()

    1. Remove the following:

    DECLARE_PROTECT_FINAL_CONSTRUCT()

    HRESULT FinalConstruct()

    {

    return S_OK;

    }

    void FinalRelease()

    {

    }

    1. Add the appropriate STDMETHODS that you want to implement. For example, to add InvokeMethod, add the following code:

    STDMETHOD (InvokeMethod) (BSTR pMethod, BSTR* args, int nArgs);

  5. Implement the SCEC in the .cpp file (for example, SampleSCECObj.cpp). To implement CSampleSCEC::InvokeMethod, add the following code:

    STDMETHODIMP CSampleSCEC::InvokeMethod(BSTR pMethod, BSTR* args, int nArgs)

    {

    // Your implementation here

    }

    The following extended example first implements a helper method (URLEncode), then queries the selected account for an address, and displays it on a map.

    #include "stdafx.h"

    #include "SampleSCECObj.h"

    // CSampleSCEC

    // METHOD NAME

    // URLEncode

    // DESCRIPTION

    // This function is used to encode a URL.

    CComBSTR URLEncode (LPCTSTR pStr)

    {

    CComBSTR pURL = _T("");

    if (!pStr)

    {

    return pURL;

    }

    TCHAR pBuffer[4];

    memset (pBuffer, 0x00, sizeof(TCHAR) * 4);

    for ( ; *pStr != _T('\0'); pStr++)

    {

    switch (*pStr)

    {

    case 0x0009 : case 0x000A : case 0x000D :

    {

    // put a 0, since these are single digit chars

    _stprintf (pBuffer, _T("%%0%x"), *pStr);

    pURL.Append (pBuffer);

    break;

    }

    case 0x0020 :

    {

    // encode space as a plus sign

    pURL.Append (_T("+"));

    break;

    }

    case 0x0021 : case 0x0022 : case 0x0023 : case 0x0024 :

    case 0x0025 : case 0x0026 : case 0x0027 : case 0x0028 :

    case 0x0029 : case 0x002B : case 0x002C : case 0x002F :

    case 0x003A : case 0x003B : case 0x003C : case 0x003D :

    case 0x003E : case 0x003F : case 0x0040 : case 0x005B :

    case 0x005C : case 0x005D : case 0x005E : case 0x0060 :

    case 0x007B : case 0x007C : case 0x007D : case 0x007E :

    {

    // encode the special characters

    _stprintf (pBuffer, _T("%%%x"), *pStr);

    pURL.Append (pBuffer);

    break;

    }

    default:

    {

    // no encoding is needed

    TCHAR pChar[1];

    _stprintf (pChar, _T("%c"), *pStr);

    pURL.Append (pChar);

    break;

    }

    }

    }

    return pURL;

    }

    STDMETHODIMP CSampleSCEC::InvokeMethod(BSTR pMethod, BSTR* args, int nArgs)

    {

    CComPtr<ISHCEBusComp> pBusComp;

    CComPtr<ISHCEBusObject> pBusObj;

    START_EVENT_ARG (CSampleSCEC::InvokeMethod);

    // Check if the Map Address button was clicked

    if (pMethod && _tcscmp (pMethod, _T("EventMethod")) == 0)

    {

    /// Make sure there is at least 1 account record present

    if (m_pRootObj->CheckActiveRow () == S_OK)

    {

    // get the primary address id

    CComBSTR bstrPrimaryAddressId;

    CALL_INT (m_pRootObj, GetFieldValue (FALSE, CComBSTR (_T("Primary Address Id")), &bstrPrimaryAddressId));

    // now get the appropriate business object and business component

    CALL_INT (m_pApp, GetBusObject (CComBSTR (_T("Account")), &pBusObj));

    CALL_INT (pBusObj, GetBusComp (CComBSTR (_T("CUT Address")), &pBusComp));

    // query for the record:

    BOOL bBool = FALSE;

    CALL_INT (pBusComp, ClearToQuery ());

    CComBSTR bstrSearchSpec = CComBSTR (_T("[Id] = '"));

    bstrSearchSpec += bstrPrimaryAddressId;

    bstrSearchSpec += CComBSTR (_T("'"));

    CALL_INT (pBusComp, SetSearchExpr (bstrSearchSpec));

    CALL_INT (pBusComp, ExecuteQuery ());

    if (pBusComp->FirstRecord (&bBool) == S_OK && bBool)

    {

    // get the required info about the address

    // get Street Address

    CComBSTR bstrStreetAddress;

    CALL_INT (pBusComp, GetFieldValue (FALSE, CComBSTR (_T("Street Address")), &bstrStreetAddress));

    // get Street Address 2

    CComBSTR bstrStreetAddress2;

    CALL_INT (pBusComp, GetFieldValue (FALSE, CComBSTR (_T("Street Address 2")), &bstrStreetAddress2));

    // get City

    CComBSTR bstrCity;

    CALL_INT (pBusComp, GetFieldValue (FALSE, CComBSTR (_T("City")), &bstrCity));

    // get State

    CComBSTR bstrState;

    CALL_INT (pBusComp, GetFieldValue (FALSE, CComBSTR (_T("State")), &bstrState));

    // get Zip Code

    CComBSTR bstrZipCode;

    CALL_INT (pBusComp, GetFieldValue (FALSE, CComBSTR (_T("Postal Code")), &bstrZipCode));

    // get Country

    CComBSTR bstrCountry;

    CALL_INT (pBusComp, GetFieldValue (FALSE, CComBSTR (_T("Country")), &bstrCountry));

    // construct and encode the URL

    CComBSTR bstrURL = CComBSTR (_T("www.mapquest.com/pda/maps.adp?address="));

    if (_tcscmp (bstrStreetAddress2, _T("")) != 0)

    {

    bstrStreetAddress += CComBSTR (_T(" "));

    bstrStreetAddress += bstrStreetAddress2;

    }

    bstrURL += URLEncode (bstrStreetAddress);

    bstrURL += CComBSTR (_T("&city="));

    bstrURL += URLEncode (bstrCity);

    bstrURL += CComBSTR (_T("&state="));

    bstrURL += URLEncode (bstrState);

    bstrURL += CComBSTR (_T("&zipcode="));

    bstrURL += URLEncode (bstrZipCode);

    bstrURL += CComBSTR (_T("&country="));

    bstrURL += URLEncode (bstrCountry);

    // map the address

    PROCESS_INFORMATION inf;

    CreateProcess (_T("\\Windows\\iexplore.exe"), bstrURL, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &inf);

    }

    else

    {

    // log message that there is no address to map

    CComBSTR bstrInfoMessage =

    CComBSTR (_T("CSampleSCEC::InvokeMethod : The currently selected account record has no address to map."));

    CALL_INT (m_pApp, Trace (bstrInfoMessage, 0));

    }

    }

    }

    ll_abort:

    FINISH_EVENT;

    }

Siebel Pharma Handheld Guide Copyright © 2013, Oracle and/or its affiliates. All rights reserved. Legal Notices.