Are you a world traveler? ZoneTick is a cool utility that'll help you stay in touch over multiple time zones!
 
Removing a MAPI Form  
Nik Okuntseff  MS Exchange Server Programming 

Removing a MAPI Form

The following sample code (Forms/RemoveForm) can be used to remove a form from the Personal Forms Library container:

#include <afxwin.h>
#include <edk.h>

int main()
{
    /*
     * Algorithm:
     *  1. Open the Personal Forms Library container.
     *  2. Remove the form.
     */

    HRESULT hr;
    LPMAPISESSION pSession = NULL;

    // Initialize MAPI
    hr = MAPIInitialize(NULL);
    if (FAILED(hr)) throw -1;

    // Obtain MAPI session
    hr = MAPILogonEx(0,    // Handle to parent window
      "MS Exchange Settings", // Profile name
      NULL,   // Password
      MAPI_NEW_SESSION |
      MAPI_EXTENDED |
      MAPI_LOGON_UI, // Logon flags
      &pSession);  // Resulting MAPI session
    if (FAILED(hr)) throw -1;

    // Open MAPI Form manager
    LPMAPIFORMMGR pFormMgr = NULL;
    hr = MAPIOpenFormMgr(pSession, &pFormMgr);
    if (FAILED(hr)) throw -1;

    // Open the "Personal Forms Library" container
    LPMAPIFORMCONTAINER pPersonalFormsLibrary = NULL;
    hr = pFormMgr->OpenFormContainer(HFRMREG_PERSONAL,
          NULL,
          &pPersonalFormsLibrary);
    if (FAILED(hr)) throw -1;

    // Remove the form!
    hr = pPersonalFormsLibrary->RemoveForm("IPM.Note.MyTestForm"); // Change the name if needed
    if (FAILED(hr)) throw -1;

    // Cleanup
    if (pPersonalFormsLibrary)
        pPersonalFormsLibrary->Release();
    if (pFormMgr)
        pFormMgr->Release();
    if (pSession)
        pSession->Release();
    ::MAPIUninitialize();
    return 0;
}

The code opens the Personal Forms Library container and then uses its IMAPIFormContainer::RemoveForm method to remove the form. Note that I supply IPM.Note.MyTestForm message class name. You will need to change it to whatever message class you form uses, otherwise the call fails with MAPI_E_NOT_FOUND error.
 

Removing Forms from Other Folders

It may seem that removing forms from other folders should be as trivial as described above. It turns out that it is not. In fact, all business of MAPI forms is not trivial at all. Here is a description of a problem that I have discovered myself.

I have modified the algorithm so that the OpenFormContainer method opened my Outbox, not the root (Personal Forms Library) folder. Then an attempt to call its RemoveForm method yielded MAPI_W_PARTIAL_COMPLETION result, and the form was not actually deleted at all. I have spent a few evenings to try to figure why with no luck. You may face this problem as well.

There exists a workaround. I have tried to use the mdbvu32.exe tool and successfully deleted a message from Outbox associated contents table. And the form was actually gone. Then I wrote my own code to do the same. You may find this code in Forms/RemoveFormFromOutbox project. The code is not trivial, simply because I needed to do a lot of things. The algorithm is simple, though:

  • Open Outbox.
  • Obtain its associated contents table.
  • Scan its rows until a given message class is found.
  • Construct an ENTRYLIST with this entry.
  • Call the IMAPIFolder::DeleteMessages method.
Everything here is simple except for knowing how to determine the form message class. First of all, the default set of columns returned by IMAPITable::QueryRows does not contain PR_MESSAGE_CLASS. In fact it only returns 3 columns, of which the most useful is PR_ENTRYID. Thus, it is necessary to set table columns explicitly with IMAPITable::SetColumns call. Further investigation shows that PR_MESSAGE_CLASS property for each form is always equal to IPM.Microsoft.FolderDesign.FormsDescription. You may notice, however, that the property 0x6800001e looks like correct message class string. So, by comparing it to what you intend to delete, it is possible to determine whether the row is the correct one.
 
[ Contents | Home ]

Send comments and suggestions to niko@wrconsulting.com
Copyright © 1997-1998 by Nik Okuntseff