The Create method alters the flow of control at the point where users create a new Contact item. Instead of assuming that the contact will be for Outlook, users are given the option to create a new Contact that is associated with a particular Source Provider, which can be associated with an external service such as Windows Messenger or the SIM card.

This customization appears when users tap New in the Contacts application. At the point, the Choose Contact Type screen appears, which presents users with a list of Contact Type options to choose from—each one for a different service (and each associated with a different Source Provider). The default service is Outlook.


HRESULT Create (
  HWND hwndParent,
  IItem * pitem


  • hwndParent
    [in] Handle (HWND) to the parent window. For information on the HWND type, see GetParent.
  • pitem
    [in/out] Reference to an IItem Contact item. As in input parameter: If pitem is not NULL, then it contains data to be saved to the new contact. As in output parameter: If pitem is not NULL, then the OID of the Contact item is considered an out parameter. For more information about Item OIDs, see IItem::get_Oid.

Return Value

This method returns the following values:

  • S_OK
    The method completed successfully.
    The provider does not require special behavior. You should just display the default Contact Edit Card, and save the new Contact without a Source ID, and set the PIMPR_DO_NOT_SYNC flag. For more information, see Shared Property ID's.
    The method completed successfully, but the Summary Card should not be displayed. Providers return this value when the Create dialog box exits for a reason other than the user dismissing it. In these scenarios, the re-appearance of the Summary Card would be inappropriate and confusing.
    One of the arguments was invalid.
    The user cancelled the creation of the new item.


When Create is called with a reference to an IItem Contact item, it indicates that there is data to save to the new Contact item.

Since the data is supplied in the pItem reference, you must ensure that the Contact OID is populated so the caller can link the Contact to the data. For example, consider saving a Contact item with call history information. In this case, the OID returned in pItem is used to link the CALLLOGENTRY item to the new Contact item. If there is no OID, then the call history cannot be linked, and the display name will not be updated for that particular call history item in the Dialer or Call History user interface.

Source Providers and their associated Source ID's are part of a mechanism that supports per-provider customization of the PIM experience on Windows Mobile devices.

A Source Provider is a custom function that customizes the PIM user experience. Typically, a Source Provider has a corresponding associate function that is responsible for synchronizing PIM data with the Windows Mobile device. Data synchronized with the Windows Mobile device by this associate function is marked with a Source identification tag (Source ID). When Outlook Mobile displays a PIM item, it checks to see if the item has a Source ID. If it finds one, it invokes the Source Provider, which customizes the user interface for the PIM item.

When users enter new contacts and appointments, they can select a Source Provider to associate with them.

A valid Source ID is a DWORD with only 1 bit set (i.e., there are 32 possible Source IDs).

Although Contact and Appointment items, regardless of Source ID, are synchronized with Microsoft Exchange — Source IDs are not.

Source IDs are not supported for Task items.

Since Contacts and Appointments can be associated with only one Source Provider, your Source Provider installation implementation must select a Source ID that is unique in the domain of all Source Providers installed on the Windows Mobile device (it is considered an error to determine Source IDs prior to install). Your implementation must choose a unique Source ID by first iterating over the installed Source Providers registered in the key \HKLM\PIMSources\, and then choosing the next available Source ID.

The default Source ID value is zero (0). Contact and Appointment items with a Source ID value of zero are not associated with a Source Provider, and just use the default user interface.

Your Source Provider uninstall implementation must reset the Source ID field of all associated Contact and Appointment items back to zero.


This code example is an encapsulated function that demonstrates how to use IPimSrcContactNew::Create to create a Contact item. It creates a custom message box with default contact details, and then allows users to save the item to the data store.


To make this code example easier to read, security checking and error handling are not included. Therefore, do not use this code example "as is" in your release configuration–you need to modify the code to include them.

STDMETHODIMP CSampleProvider::Create(HWND hwndParent, IItem *pItemIn)
    HRESULT            hr = S_OK;
    IDispatch * pDispatch = NULL;
    IItem         * pItem = NULL;
    DWORD      dwSourceID;
    int   idMessageResult;

    CEPROPVAL rgpvals[] = {{PIMPR_SOURCE_ID,   0, 0, 0}, 
                           {PIMPR_FIRST_NAME,  0, 0, 0}, 
                           {PIMPR_DO_NOT_SYNC, 0, 0, 1}};

    // Display a user confirmation message box.
    idMessageResult = MessageBox(hwndParent, 
                                 _T("Would you like to create a new Contact item?"), 
                                 _T("New Contact"), MB_YESNO);

    if (idMessageResult != IDYES)
        goto Exit;                 // The user decided to not create a Contact item.

    // Create a new Contact item with default details.
    hr = m_polApp->CreateItem(olContactItem, &pDispatch);
    hr = pDispatch->QueryInterface(IID_IItem, (void**)&pItem);

    // Configure the Source Provider by reading its Source ID (REG_DWORD) registry value.
    hr = RegistryGetDWORD(PIMSRC_REGHKEY, g_wszOurKey, g_wszOurValueName, &dwSourceID);

    // Set the default properties for the new Contact item.
    rgpvals[0].val.ulVal  = dwSourceID;
    rgpvals[1].val.lpwstr = _T("TestCreateProvider");

    hr = pItem->SetProps(0, ARRAYSIZE(rgpvals), rgpvals);

    // Save the new Contact item.
    hr = pItem->Save();

    if (pDispatch)

    if (pItem)

    return hr;

If you are creating new source provider based on this code, you might find it useful to make the following references and declarations in your header file.

// Include ATL headers.
#define MAX_BUFFER 1024

extern CComModule _Module;

#include <atlbase.h>
#include <atlcom.h>
#include <windows.h>
#include <RegExt.h>         // For registry helper functions.
#include <pimstore.h>       // For POOM and PIM APIs.

// SDK macros (for example CBR, and CHR, RELEASE_OBJ).
#include "Macros.h"

Define a custom error code to handle the case where a customization is not available.


Defines the set of customizations you are implementing in this Source Provider.

                           PIMSRC_CUSTOM_CONTACTS_PAINT_LIST_ICON | \
                           PIMSRC_CUSTOM_CONTACTS_NEW | \

Defines the Outlook item types the the customizations apply to.


Constants (see Const.cpp for defined values).

extern const GUID     CLSID_SampleProvider;
extern HANDLE         g_currentInstance;
extern const LPTSTR   g_szCLSID_SampleProvider;
extern const LPWSTR   g_szDllName;
extern const COLORREF g_crCalendarBackground;
extern const WCHAR    g_wszOurKey[];
extern const WCHAR    g_wszOurValueName[];
extern const WCHAR    g_wszDisplayName[];

Forward function declarations.

// Functions to Init and UnInit POOM.
HRESULT InitPOOM(IPOutlookApp2 **ppolApp);
HRESULT UnInitPOOM(IPOutlookApp2 *polApp);

// Functions to register and unregister this Source Provider.
HRESULT LookupSourceId(DWORD *pdwSourceId);
HRESULT RegisterPIMSource();
HRESULT UnregisterPIMSource();

// Function to handle any additional setup for the Source Provider.
HRESULT ItemSetup(IPOutlookApp2 *polApp, int olItemType, BOOL bInstall);

// Function to get HMITMAP from IStream.
HBITMAP LoadImageStream(IStream *pStream);

The following code example demonstrates a typical Source Provider class definition.

class CSampleProvider :
    public CComObjectRootEx<CComMultiThreadModel>,
    public CComCoClass<CSampleProvider, &CLSID_SampleProvider>,
    public IPimSrcContactListIcon,
    public IPimSrcContactNew,
    public IPimSrcContactSummaryCard
    // Miscillaneous ATL declarations.

    // The lifetime of Source Provider is managed by CComObject<>, which derives from our class, 
    // therefore our constructor and destructor should be protected, 
    // to ensure that no other objects can create or destroy objects of this type.
    virtual ~CSampleProvider();

    HRESULT EnsurePOOM();

    // Access to methods of the Source Provider class should be through interface pointers ohly.

    // IPimSrcContactSummaryCard
    STDMETHOD(Display)(HWND hwndParent, IItem *pitem);

    // IPimSrcContactListIcon
    STDMETHOD(Paint)(const SRCCUSTOMDRAW *pscd, CEOID oid);

    // IPimSrcContactNew
    STDMETHOD(Create)(HWND hwndParent, IItem *pItem);

    IPOutlookApp2   *m_polApp;


Header pimstore.h
Library Pimstore.lib
Windows Mobile Windows Mobile 6 Classic and later, Windows Mobile 6 Professional and later, Windows Mobile 6 Standard and later

See Also


Customizing the PIM User Experience by Using Source Providers
Source Provider Customization Type Flags
Source Provider PIM Type Ownership Flags


Customizing an Appointment Item's Background Color

Other Resources

Register a Source Provider
Phone API Properties