Microsoft KB Archive/241566

= MAPI: ShowForm Causes Out-Of-Memory Error From Outlook =

Article ID: 241566

Article Last Modified on 10/26/2006

-

APPLIES TO


 * Microsoft Messaging Application Programming Interface

-



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; }



STATUS
Microsoft has confirmed that this is a problem in the Microsoft products that are 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: kbbug kbmsg kbnofix KB241566

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.