HOWTO: Create an Entry in the Personal Address Book
ID: Q178172
|
The information in this article applies to:
-
Extended Messaging Application Programming Interface (MAPI), version 1.0
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.
MORE INFORMATION
Step-by-Step Instructions
- Initialize MAPI Subsystem with the MAPIInitialize() function.
- Start a MAPI session by calling the MAPILogonEx() function.
- Call IMAPISession::OpenAddressBook() to get an IAddrBook interface.
- Open the root address book container by calling IAddrBook::OpenEntry().
Pass NULL as the EntryID to specify the root. This returns an
IABContainer interface.
- Get a list of all of the sub-containers of the root address book
containers by calling IABContainer::GetHierarchyTable(). This returns a
populated MAPITable.
- Next, set up a restriction on the table to find the "Personal Address
Book." Once found, get its EntryID.
- 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.
- 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.
- Setup a restriction to find the EntryID of the template you want.
- 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.
- Set the following three properties on the new entry via the IMAPIProp
interface:
- PR_DISPLAY_NAME
- PR_EMAIL_ADDRESS
- PR_ADDRTYPE
- 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 <stdio.h>
#include <mapiutil.h>
#include <conio.h> // Just for getch()
#include <mapidefs.h>
#include <mapiguid.h>
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;
}
REFERENCES
For information on how to obtain the Mapiasst.h header file that contains
helpful debugging routines, please see the following article in the
Microsoft Knowledge Base:
Q177542
FILE: MAPIASST.EXE: MAPI ASSERT Debug Routines
Additional query words:
Personal Address Book PAB CreateEntry Create Entry Add
Keywords : kbcode kbMsg kbMAPI100 MAPIIAB
Version : WINDOWS:1.0
Platform : WINDOWS
Issue type : kbhowto