|Important||This document may not represent best practices for current development, links to downloads and other resources may no longer be valid. Current recommended version can be found here.|
This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
Builds a new IMessage object on top of an existing OLE IStorage object, to be used within a message session.
Client applications and service providers
Property attributes can only be accessed on property objects, that is, objects implementing the IMAPIProp : IUnknown interface. To make MAPI properties available on an OLE structured storage object, OpenIMsgOnIStg builds an IMessage : IMAPIProp object on top of the OLE IStorage object. The property attributes on such objects can be set or altered with SetAttribIMsgOnIStg and retrieved with GetAttribIMsgOnIStg.
A message session should be opened with OpenIMsgSession before OpenIMsgOnIStg is called. Supplying a valid lpMsgSess parameter make sures that the new message is created within a message session so that it is closed when the session is closed. If lpMsgSess is NULL, the message is created independently of any message session. If the client application or service provider that created the message does not release it, as well as all its attachments and open tables, memory is leaked and may cause the application to terminate.
MAPI uses the functions pointed to by lpAllocateBuffer, lpAllocateMore, and lpFreeBuffer for most memory allocation and deallocation, in particular to allocate memory for use by client applications when calling object interfaces such as IMAPIProp::GetProps and IMAPITable::QueryRows. The lpAllocateBuffer, lpAllocateMore, and lpFreeBuffer pointers are optional when the OpenIMsgOnIStg function is called with a valid lpMapiSup parameter.
Because it is dealing with an underlying OLE object, MAPI also needs to use OLE memory allocation. For more information about OLE structured storage objects and OLE memory allocation, see the OLE Programmer's Reference.
If a valid value is supplied for lpMapiSup, IMessage supports the MAPI_DIALOG and ATTACH_DIALOG flags by calling the IMAPISupport::DoProgressDialog method to supply a progress user interface for the IMAPIProp::CopyTo and IMessage::DeleteAttach methods. Also, the IMessage::ModifyRecipients method attempts to convert short-term entry identifiers to long-term entry identifiers by calling the IMAPISupport::OpenAddressBook method and making calls on the resulting address book object. If NULL is passed for lpMapiSup, IMessage ignores MAPI_DIALOG and ATTACH_DIALOG and stores short-term entry identifiers without conversion.
The IStorage object pointed to by the lpStg parameter must be opened in either the STGM_READ or STGM_READWRITE mode. If the STGM_READWRITE mode is used, the STGM_TRANSACTED mode must also be set.
The callback function pointed to by the lpfMsgCallRelease parameter is optional; if provided, it should be based on the MSGCALLRELEASE function prototype. The IMessage interface calls it when the reference count of the IMessage-on-IStorage object is set to zero by the last call to its Release method. The callback function is commonly used to free the underlying IStorage interface. IMessage will not attempt to access the IStorage object pointed to by the lpStg parameter after making the callback.
Some clients or providers might write additional data to the IStorage object beyond what IMessage itself writes when its SaveChanges method is called. The client or provider can use the IMSG_NO_ISTG_COMMIT flag to prevent IMessage from calling the OLE IStorage::Commit method while processing a SaveChanges call; in this case the client or provider must itself commit the IStorage object when the additional data is written. To aid in this, the IMessage implementation guarantees to name all substorages it creates in the IStorage object starting with the string "__", that is, with two underscores. The client or provider can avoid name collisions by keeping its substorage names out of this namespace.
MAPI does not define the behavior of multiple open operations performed on a subobject of a message, such as an attachment, a stream, or an embedded message. MAPI currently allows a subobject that is already open to be opened once more, but MAPI performs the open operation by incrementing the reference count for the existing open object and returning it to the client or provider that called the IMessage::OpenAttach or IMAPIProp::OpenProperty method. This means the access requested for the first open operation on a subobject is the access provided for all subsequent open operations, regardless of the access requested by the operations.
The correct procedure for placing a message into an attachment is to call the IMAPIProp::OpenProperty method with an interface identifier of IID_IMessage. OpenProperty currently also supports creation of message attachments available directly on the OLE IStorage interface, that is, using the IID_IStorage interface identifier. IStorage access is supported to allow an easy way to put a Microsoft Word for Windows document into an attachment without converting it to or from the OLE IStream interface. However, IMessage may not behave predictably if OpenIMsgOnIStg is passed an IStorage pointer to the attachment data and then the objects are released in the wrong order.