MAPI: Outlook Gives Out-of-Memory Error
ID: Q241566
|
The information in this article applies to:
-
Microsoft Outlook Windows NT client, version 9.0
-
Microsoft Outlook Windows 95/98 client, version 9.0
-
MAPI
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:
Q239795 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();
}
STATUS
Microsoft has confirmed this to be a problem in the Microsoft products listed
at the beginning of this article.
MORE INFORMATION
In the following code fragment, the ShowForm function may cause an out-of-memory error while running multiple times in the loop. The error happens most often when attachments are added to successive messages.
.....
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;
//Create twenty messages
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;
}
//Always clean up your memory here!
Cleanup:
....
Additional query words:
sgriffin
Keywords : kbMsg kbOutlook
Version : WINDOWS:9.0
Platform : WINDOWS
Issue type : kbbug