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
|