Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

CMapiAdmin - MAPI wrapper

0.00/5 (No votes)
25 Jan 2000 1  
A class to encapsulate extended MAPI functions.

Overview

The CMapiAdmin class contains functions that make using extended MAPI a bit easier. Having the functionality encapsulated in a class reduces the overhead of coding, research, and the learning curve involved in getting some of these things done for the first time. The illustration below shows the structure of the class. Nodes in the tree with a key associated with the icon are protected functions or members and are used internally to the class (explained for developers not familiar with the Microsoft Visual C++ IDE) and are therefore not 'exposed'.

A bit of dipping into the registry has proved to be essential for the ability to remove a service when only given the StoreID (a.k.a. EntryID). In the source code, there is a CRegistryKey class which is used by CMapiAdmin. They can't be separated unless you want to use Win32 registry functions instead of the class.

CMapiAdmin Class Outline

Public Methods

bool GetStorePath(CString strStoreID (in), CString& strStorePath (out))

Requires a string representation of the binary InformationStoreID. This function is typically used to find out the full pathname of a PST file used for "Personal Folders".

bool RemoveService(BYTE* pbyEntryID, DWORD dwSize)

Requires a binary array representing the InformationStoreID. This function will remove the specified store. This is a more accurate way to remove such a service (see other version(s) of this function). Having said that, I recently found that you can have more than one service with the same EntryID (a.k.a. StoreID), and this function now removes all that are found (er... with the same EntryID)

bool RemoveService(LPTSTR lpszDisplayName)

Requires a pointer to a string containing the display name of the service you want removed. This function will remove all the services found with that name. WARNING: It is possible to have more than one service with the same name.

bool GetProfileName(LPTSTR& lpszProfileName)

If you log on using an existing session, you may then want to know exactly which profile you are using.

bool CreateMessage(DWORD dwRecipientCount, 
                   LPCTSTR* ppRecipents, 
                   LPCTSTR pMessageSubject, 
                   LPCTSTR pMessageText, 
                   BOOL bHighImportance);
bool CreateNewProfile(LPTSTR lpszNewName)
bool CreateMsgService(LPTSTR lpszService, LPTSTR lpszDisplayName)
bool Logon(ULONG ulUIParam=NULL, 
           LPTSTR lpszProfileName=NULL, 
           LPTSTR lpszPassword=NULL, 
           FLAGS flFlags=NULL);

If you do not supply parameters, this function will use MapiLogonEx to attempt to log on using an existing session. This method of logging on is useful for projects which work with or within applications like Microsoft Outlook.

Example use of CMapiAdmin:

Note: Make sure you've called Co(Un)Initialise():

HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
    MessageBox(0, "CoInitialize Failed", "InitInstance Error", MB_OK);
        return FALSE;
}

and:

CoUninitialize();

Simple send message to single recipient:

CMapiAdmin mapi;
if ( mapi.Logon() )
{
    LPCTSTR ppRecipients[1] = {"jason.hattingh@csfb.com"};
    mapi.CreateMessage(1, ppRecipients, "Hello Geezah!", 
                       "Here is a test message", TRUE);
    if (mapi.SendMessage())
        AfxMessageBox("Message sent successfully");
}

Example use inside COM object:

There are 2 sample projects that make use of CMapiAdmin.

The Visual Basic Project uses CDO (DLL included in the zip) to display the stores available. When a user clicks the "GetPath" or the "Delete Service" button, the appropriate function is called in the COM object (who's Visual C++ Project is included in a zip file).

For example, the following code in VB:

Private Sub Command1_Click()
    Dim cStore As MAPI.InfoStore
    Dim sStoreID As String

    Set cStore = cStores.Item(List1.ListIndex + 1)
    sStoreID = cStore.ID

    Dim MsgAdmin As New MessageServiceAdmin

    Dim nReturn As Integer

    nReturn = MsgAdmin.RemoveByEntryID(sStoreID)

    If nReturn = 0 Then
        MsgBox "Service Removed Successfully"
    Else
        MsgBox "Failed to Remove the Service"
    End If
End Sub

...relates to the following C++ code in the COM object (which uses CMapiAdmin):

STDMETHODIMP CMessageServiceAdmin::RemoveByEntryID(VARIANT vEntryID, 
                                                   VARIANT* pvReturn)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState())

    // Start by setting the default return value to S_FALSE:

    V_VT(pvReturn) = VT_I2;
    V_I2(pvReturn) = S_FALSE;

    ////////////////////////////////////////////////////////

    // CONVERT THE STRING TO A BYTE ARRAY:


    ...Conversion code here...

    // END STRING TO BYTE ARRAY CONVERSION

    /////////////////////////////////////////////////////////////


    CMapiAdmin MapiAdmin;

    if (! MapiAdmin.Logon() ) 
        return S_FALSE;

    if ( ! MapiAdmin.RemoveService( pByte, (DWORD)nSize ) )
        return S_FALSE;

    // Set the return to ZERO which means all is ok (a non zero normally

    // represents an error code)

    V_VT(pvReturn) = VT_I2;
    V_I2(pvReturn) = S_OK;
    return S_OK;
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here