MAPI: ShowForm Causes Out-Of-Memory Error From Outlook (241566)
The information in this article applies to:
This article was previously published under Q241566 SYMPTOMS
On slower computers, if you run the IMAPISession::PrepareForm and IMAPISession::ShowForm functions in a loop to display multiple Outlook forms, it may cause errors. The first call to ShowForm will work. Subsequent calls to ShowForm may display the following error message if you try to add an attachment with drag and drop:
Out of memory or system resources. Close some windows and try again.
See the "More Information" section for sample code that demonstrates this behavior.
CAUSE
A bad reference count causes an internal object creation failure. This returns an error code, which is interpreted as out of memory.
RESOLUTION
When an application invokes ShowForm, the form server for the which the form is registered is loaded. MAPI adds a reference to the form server when it runs the form. When the form is closed, MAPI releases the reference. When there are no references left on the form server, it shuts down.
In this case, IPM.Note is registered to use Outlook.exe as its form server. When you dismiss the displayed message, Outlook begins to shut down. While Outlook is shutting down, it is not in a state where it can accept calls to open a new form. There is a timing issue here: If Outlook does not fully shut down before the next form is invoked, MAPI interprets this as a failure caused by limited memory. However, if Outlook can shut down completely first, the next form will open without a problem.
If an application knows it will be opening multiple forms that use Outlook as their form server, it will want to ensure that Outlook stays in memory continuously while it is displaying forms. One way to do this, demonstrated in the "Workaround" section of this article, is to create an Outlook.Application object. This causes Outlook to load and stay running until the object is released. The application can then create and destroy as many items as it needs and not have the timing problems or the performance hit of Outlook constantly starting and stopping.
If the application only wants to create an Outlook.Application object when Outlook is the registered mail client, check the following registry key:
HKEY_LOCAL_MACHINE\Software\Clients\Mail
If the default value is set to "Microsoft Outlook," Outlook is the application that handles the ShowForm function.
WORKAROUND
Here is sample code which demonstrates the workaround.
For sample code that implements OpenDefaultMessageStore and OpenInbox, please see the following article in the Microsoft Knowledge Base:
239795 HOWTO: List Messages in the Inbox with MAPI
HRESULT CreateObject(LPOLESTR pszProgID, IDispatch FAR* FAR* ppdisp)
{
CLSID clsid; // CLSID of automation object
HRESULT hr;
LPUNKNOWN punk = NULL; // IUnknown of automation object
LPDISPATCH pdisp = NULL; // IDispatch of automation object
*ppdisp = NULL;
// Retrieve CLSID from the progID that the user specified
hr = CLSIDFromProgID(pszProgID, &clsid);
if (FAILED(hr))
goto error;
// Create an instance of the automation object and ask for the IDispatch interface
hr = CoCreateInstance(clsid, NULL, CLSCTX_SERVER,
IID_IUnknown, (void FAR* FAR*)&punk);
if (FAILED(hr))
goto error;
hr = punk->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdisp);
if (FAILED(hr))
goto error;
*ppdisp = pdisp;
punk->Release();
return NOERROR;
error:
if (punk) punk->Release();
if (pdisp) pdisp->Release();
return hr;
}
void main(void)
{
HRESULT hRes;
LPMAPISESSION lpMAPISession = NULL;
LPMDB lpMDB = NULL;
LPMAPIFOLDER lpInboxFolder = NULL;
LPMESSAGE lpMessage = NULL;
ULONG ulToken = 0;
int i = 0;
hRes = MAPIInitialize(NULL);
if (!CHECKHRES(hRes)) goto Cleanup;
hRes = MAPILogonEx(0,
NULL,
NULL,
MAPI_LOGON_UI ||
MAPI_NEW_SESSION ,
&lpMAPISession);
if (!CHECKHRES(hRes)) goto Cleanup;
//some function to open a message store
hRes = OpenDefaultMessageStore(
lpMAPISession,
&lpMDB);
if (!CHECKHRES(hRes)) goto Cleanup;
//some function to open the inbox
hRes = OpenInbox(
lpMDB,
&lpInboxFolder);
if (!CHECKHRES(hRes)) goto Cleanup;
LPDISPATCH pOutlook;
hRes = CreateObject(OLESTR("Outlook.Application"), &pOutlook);
if (!CHECKHRES(hRes)) goto Cleanup;
//First Message
for (i = 1 ; i<=20 ; i++)
{
hRes = lpInboxFolder->CreateMessage(
NULL,
NULL,
&lpMessage);
if (!CHECKHRES(hRes)) goto Cleanup;
hRes = lpMAPISession->PrepareForm(
NULL,
lpMessage,
&ulToken);
if (!CHECKHRES(hRes)) goto Cleanup;
UlRelease(lpMessage);
hRes = lpMAPISession->ShowForm(
NULL,
lpMDB,
lpInboxFolder,
NULL,
ulToken,
NULL,
MAPI_NEW_MESSAGE,
NULL,
MSGFLAG_UNSENT | MSGFLAG_READ,
NULL,
"IPM.NOTE");
if (hRes == MAPI_E_USER_CANCEL) hRes = S_OK;
if (!CHECKHRES(hRes)) goto Cleanup;
}
pOutlook->Release();
//Always clean up your memory here!
Cleanup:
UlRelease(lpInboxFolder);
UlRelease(lpMDB);
UlRelease(lpMAPISession);
MAPIUninitialize();
if (FAILED(hRes))
{
printf("Failed with hRes of %x\n",hRes);
}
printf("Type something to quit:");
while (!_kbhit()){}
_getch();
}
STATUSMicrosoft has confirmed that this is a problem in the Microsoft products that are listed at the beginning of this article.
Modification Type: | Major | Last Reviewed: | 10/2/2003 |
---|
Keywords: | kbbug kbMsg kbnofix KB241566 |
---|
|