Microsoft KB Archive/178172

= How To Create an Entry in the Personal Address Book =

Article ID: 178172

Article Last Modified on 8/18/2005

-

APPLIES TO


 * Microsoft Messaging Application Programming Interface

-



This article was previously published under Q178172



SUMMARY
This article details the process of creating an entry in the Personal Address Book using Extended MAPI and C++. Below are step-by-step instructions and sample code for the process.



Step-by-Step Instructions

 * 1) Initialize MAPI Subsystem with the MAPIInitialize function.
 * 2) Start a MAPI session by calling the MAPILogonEx function.
 * 3) Call IMAPISession::OpenAddressBook to get an IAddrBook interface.
 * 4) Open the root address book container by calling IAddrBook::OpenEntry. Pass NULL as the EntryID to specify the root. This returns an IABContainer interface.
 * 5) Get a list of all of the sub-containers of the root address book containers by calling IABContainer::GetHierarchyTable. This returns a populated MAPITable.
 * 6) Next, set up a restriction on the table to find the "Personal Address Book." Once found, get its EntryID.
 * 7) Use IAddrBook::OpenEntry to open the Personal Address Book (PAB). Pass OpenEntry the EntryID from the step above to specify the PAB. This returns an IABContainer interface.
 * 8) Now you need to find the template for the address type you wish to add. To do this, call IABContainer::OpenProperty. OpenProperty returns a MAPITable of all of its templates.
 * 9) Setup a restriction to find the EntryID of the template you want.
 * 10) Call IABContainer::CreateEntry with the EntryID from the previous step to create the new entry. This new entry still needs to be populated with data. The call to CreateEntry will return a IMAPIProp interface.
 * 11) Set the following three properties on the new entry via the IMAPIProp interface:


 * 1) * PR_DISPLAY_NAME
 * 2) * PR_EMAIL_ADDRESS
 * 3) * PR_ADDRTYPE
 * 4) Call IMAPIProp::SaveChanges to write the changes to the object.

Sample Code
// NOTE: You will need to add Mapi32.lib as an input module in the // Link tab of the Project Settings dialog box.

#define INITGUID #define USES_IID_IMAPITable

// See the "References" section below for information on  // obtaining this header file. #include "MAPIASST.H" // For MAPI_ASSERT_EX and SHOWTABLE

#include   #include    #include    // Just for getch

#include   #include 

HRESULT AddToPab(LPTSTR lpszDisplayName, LPTSTR lpszAddress,          LPTSTR lpszAddrType);

// This gives an example of calling the AddToPab function. void main {    HRESULT      hr = S_OK; char sDone[64];

hr = AddToPab("Created By MyCode", "email@domain.com", "SMTP"); sprintf(sDone, "Done, hr=0x%x\n", hr); OutputDebugString(sDone); getch; }

HRESULT AddToPab(LPTSTR lpszDisplayName, LPTSTR lpszAddress,          LPTSTR lpszAddrType) {   HRESULT      hr = S_OK; LPMAPISESSION  lpSession = NULL; LPADRBOOK     lpAddrbk = NULL; LPMAPICONTAINER  lpAddrRoot = NULL; LPMAPITABLE     lpBooks = NULL; ULONG     ulCount = NULL; ULONG     ulObjType = NULL; LPSRowSet     pRows =   NULL; SRestriction          srName; SPropValue     spv; LPSPropValue   lpProp; LPABCONT     lpABC = NULL; LPMAPITABLE     lpTPLTable = NULL; LPMAPIPROP     lpNewEntry = NULL;

SizedSPropTagArray(2, Columns) = {2, {PR_DISPLAY_NAME, PR_ENTRYID}}; SizedSPropTagArray(2, TypeColumns) = {2, {PR_ADDRTYPE, PR_ENTRYID}};

// Initialize MAPI Subsystem. hr = MAPIInitialize(NULL); MAPI_ASSERT_EX(hr);

// Logon to MAPI. hr = MAPILogonEx(0,NULL,NULL,MAPI_LOGON_UI,&lpSession); MAPI_ASSERT_EX(hr);

hr = lpSession->OpenAddressBook(0,NULL,0,&lpAddrbk); MAPI_ASSERT_EX(hr);

// Open root address book (container). hr = lpAddrbk->OpenEntry(0L,NULL,NULL,0L,&ulObjType,                 (LPUNKNOWN*)&lpAddrRoot); MAPI_ASSERT_EX(hr);

// Get a table of all of the Address Books. hr = lpAddrRoot->GetHierarchyTable(0, &lpBooks); MAPI_ASSERT_EX(hr); //SHOWTABLE(lpBooks);

// Restrict the table to just its name and ID. hr = lpBooks->SetColumns((LPSPropTagArray)&Columns, 0); MAPI_ASSERT_EX(hr);

// Build a restriction to find the Personal Address Book. srName.rt = RES_PROPERTY; srName.res.resProperty.relop = RELOP_EQ; srName.res.resProperty.ulPropTag = PR_DISPLAY_NAME; srName.res.resProperty.lpProp = &spv; spv.ulPropTag = PR_DISPLAY_NAME; spv.Value.lpszA = "Personal Address Book"; // Address Book to open

// Apply the restriction hr = lpBooks->Restrict(&srName,0); MAPI_ASSERT_EX(hr);

// Get the total number of rows returned. Typically, this will be 1. hr = lpBooks->GetRowCount(0,&ulCount); MAPI_ASSERT_EX(hr);

// Get the row properties (trying to get the EntryID). hr = lpBooks->QueryRows(ulCount,0,&pRows); MAPI_ASSERT_EX(hr);

// Get a pointer to the properties. lpProp = &pRows->aRow[0].lpProps[1];  // Point to the EntryID Prop

// Open the Personal Address Book (PAB). hr = lpAddrbk->OpenEntry(lpProp->Value.bin.cb,                 (ENTRYID*)lpProp->Value.bin.lpb,                  NULL,MAPI_MODIFY,&ulObjType,                  (LPUNKNOWN FAR *)&lpABC); MAPI_ASSERT_EX(hr);

// Get a table of templates for the address types. hr = lpABC->OpenProperty( PR_CREATE_TEMPLATES,                 (LPIID) &IID_IMAPITable,                   0, 0,                  (LPUNKNOWN *)&lpTPLTable); MAPI_ASSERT_EX(hr); //SHOWTABLE(lpTPLTable); // Restrict the table to just its name and ID  hr = lpTPLTable->SetColumns((LPSPropTagArray)&TypeColumns, 0); MAPI_ASSERT_EX(hr);

// Get the EntryID of the Internet Mail Address Template // Build a restriction to find the SMTP Template srName.rt = RES_PROPERTY; srName.res.resProperty.relop = RELOP_EQ; srName.res.resProperty.ulPropTag = PR_ADDRTYPE; srName.res.resProperty.lpProp = &spv; spv.ulPropTag = PR_ADDRTYPE; spv.Value.lpszA = lpszAddrType;  // Name of Template ID you want // passed into the function

// Apply the restriction hr = lpTPLTable->Restrict(&srName,0); MAPI_ASSERT_EX(hr); // Get the total number of rows returned. Typically, this will be 1. hr = lpTPLTable->GetRowCount(0,&ulCount); MAPI_ASSERT_EX(hr);

// Get the row properties (trying to get the EntryID). hr = lpTPLTable->QueryRows(ulCount,0,&pRows);

// Get a pointer to the properties. lpProp = &pRows->aRow[0].lpProps[1];  // Point to the EntryID of                                         // the template.

// Now, you can actually create the new entry. // It is blank when created. hr = lpABC->CreateEntry(lpProp->Value.bin.cb,              (ENTRYID*)lpProp->Value.bin.lpb,               CREATE_CHECK_DUP_LOOSE,               &lpNewEntry); MAPI_ASSERT_EX(hr);

if (S_OK == hr && lpNewEntry) {     // Ok, now you need to set some properties on the new Entry. const unsigned long cProps = 3; SPropValue  aPropsMesg[cProps]; LPSPropProblemArray  lpPropProblems = NULL;

// Setup your properties. aPropsMesg[0].dwAlignPad  = 0; aPropsMesg[0].ulPropTag  = PR_EMAIL_ADDRESS; aPropsMesg[0].Value.LPSZ  = lpszAddress; aPropsMesg[1].dwAlignPad  = 0; aPropsMesg[1].ulPropTag  = PR_DISPLAY_NAME; aPropsMesg[1].Value.LPSZ  = lpszDisplayName; aPropsMesg[2].dwAlignPad  = 0; aPropsMesg[2].ulPropTag  = PR_ADDRTYPE; aPropsMesg[2].Value.LPSZ  = lpszAddrType;

// Set the properties on the object. hr = lpNewEntry->SetProps(cProps, aPropsMesg, &lpPropProblems); MAPI_ASSERT_EX(hr);

// Explictly save the changes to the new entry. hr = lpNewEntry->SaveChanges(NULL); if (MAPI_E_COLLISION == hr) {      // You tried to add an entry that already exists. OutputDebugString("Collision! The entry Already Exists.\n"); hr = S_OK;  // Handled the error.... }     MAPI_ASSERT_EX(hr); }

// Cleanup if (lpNewEntry) lpNewEntry->Release; if (lpTPLTable) lpTPLTable->Release; if (lpABC) lpABC->Release; if (lpBooks) lpBooks->Release; if (lpAddrRoot) lpAddrRoot->Release; if (lpAddrbk) lpAddrbk->Release; if (lpSession) lpSession->Release;

FreeProws(pRows); return hr; }

