The MAPI folder object is used to organize both messages and subfolders in a message store. Each message store will typically contain at least five folders that are commonly used: Deleted Items, Drafts, Inbox, Outbox, and Sent Items. Every folder in the message store implements the IMAPIFolder interface, which can be used to create new messages, as well as copy and delete them. In addition, you can use IMAPIFolder to manage any subfolders.
Because a MAPI folder can contain objects that have multiple subfolders, or hierarchy, management of the tables supported in the folder object is handled by the IMAPIContainer interface, from which all IMAPIFolder objects are derived.
The IMAPIContainer interface supports the methods described in Table 11.16.
Method | Description |
---|---|
GetContentsTable() | Returns an IMAPITable interface for a table that lists the contents of the container |
GetHierarchyTable() | Returns an IMAPITable interface for a table that lists the container's hierarchy table |
OpenEntry() | Returns an interface for a specific MAPI object based on its ENTRYID |
As you can see, two different types of tables are available to a client application from the IMAPIContainer interface. Contents tables are used to return data about the objects contained within the current folder, and hierarchy tables are used only to return data about child objects within the current folder.
More specifically, if you wanted to get a table of the messages in a folder, you would use the IMAPIContainer::GetContentsTable() function. To get a list of subfolders for the current folder, you would use IMAPIContainer::GetHierarchyTable() instead.
The IMAPIContainer object is also derived from IMAPIProp, and supports the properties described in Table 11.17.
Property Tag | Property Type | Description |
---|---|---|
PR_DISPLAYNAME | PT_TSTRING | The display name of the object |
PR_ENTRYID | PT_BINARY | The object's entry identifier |
PR_LAST_MODIFICATION_TIME | PT_SYSTIME | The last date and time the object was modified |
PR_NULL | PT_NULL | A NULL value |
PR_OBJECT_TYPE | PT_LONG | The type of object |
PR_PARENT_ENTRYID | PT_BINARY | The parent object's entry identifier |
The IMAPIFolder interface supports the methods described in Table 11.18.
Method | Description |
---|---|
CopyFolder() | Copies or moves a folder |
CopyMessages() | Copies or moves messages |
CreateFolder() | Creates a new subfolder and returns a new IMAPIFolder interface |
CreateMessage() | Creates a new message and returns a new IMessage interface |
DeleteFolder() | Deletes a subfolder |
DeleteMessages() | Deletes a message |
In order to get the interface pointer for a specific MAPI folder object, you need to determine the ENTRYID for the folder to be used with the IMsgStore::OpenEntry() function.
One way to get the table of the folders in a message store is to use the IMAPIProp::GetProps() function on the message store to get the ENTRYID for the root object (using the PR_IPM_SUBTREE_ENTRYID property):
// After we have the pointer to the store we are interested // in (pPop3Store) get the PR_IPM_SUBTREE_ENTRYID to get the // entry identifer for the root folder. LPSPropValue rgStoreProps = NULL; ULONG cStoreValues = 0; IMAPIFolder *pPOPRootFolder = NULL; SizedSPropTagArray(2, rgStoreTags) = {2,{PR_IPM_SUBTREE_ ENTRYID, PR_OBJECT_TYPE}}; // Now get the root folder. hr = pPop3Store->GetProps((LPSPropTagArray)&rgStoreTags, MAPI_UNICODE, &cStoreValues, &rgStoreProps); if(FAILED(hr)) return FALSE; hr = pPop3Store->OpenEntry(rgStoreProps[0].Value.bin.cb, (LPENTRYID)rgStoreProps[0].Value.bin.lpb, NULL, MAPI_MODIFY, NULL, (LPUNKNOWN*)&pPOPRootFolder); if(FAILED(hr)) return FALSE; // Get the hierarchy table to get the entry identifier and // name of each folder. IMAPITable *pIFoldersTable = NULL; hr = pPOPRootFolder->GetHierarchyTable(0, &pIFoldersTable); while(1) { SRowSet *pRowSet = NULL; SizedSPropTagArray(2, tblColumns) = {2,{PR_DISPLAY_NAME, PR_ENTRYID}}; pIFoldersTable->SetColumns((LPSPropTagArray)&tblColumns, 0); hr = pIFoldersTable->QueryRows(1, 0, &pRowSet); if(pRowSet->cRows != 1) break; // Do something, such as display the name OutputDebugString(pRowSet->aRow[0].lpProps[0].Value.lpszW); // Free buffers allocated by MAPI FreeProws(pRowSet); };
The message store object on Pocket PC also supports properties that can be used to specify any of the following standard folders:
PM_IPM_OUTBOX_ENTRYID, for the Outbox folder
PM_IPM_SENTMAIL_ENTRYID, for the Sent Items folder
PM_IPM_WASTEBASKET_ENTRYID, for the Deleted Items folder
PM_CE_IPM_DRAFTS_ENTRYID, for the Drafts folder
PM_CE_IPM_INBOX_ENTRYID, for the Inbox folder
Once you have the pointer to the IMAPIFolder interface that you are interested in, you can then perform any operations on the folder, such as creating a new message, copying a message, or even creating a new subfolder.
To get a list of the subfolders for a particular folder object, you can use the IMAPIContainer::GetHierarchyTable() function:
HRESULT IMAPIContainer::GetHierarchyTable(ULONG ulFlags, LPMAPITABLE *lppTable);
The first parameter is ignored and can be set to 0. The lppTable parameter will point to a new IMAPITable interface when the function returns.