MORE INFORMATION
SimpleMapi saves all attachments in the recipients temp directory. Once you
determine the location of your OLE Object file by using lpMapiMessage->
lpFiles->lpszPathName and lpMapiMessage->lpFiles- >lpszFileName to
determine the specified file, you can take control over that file.
Simple MAPI represents OLE object files as OLE object streams. If you
already know that your attachment is a strutured storage file, then your
task is limited to OLE APIs. If don't know that your attachment is a
strutured storage file, you'll need to parse through Simple MAPI structures
in order to determine the type of the attachment.
A MapiMessage is comprised of 12 members which are:
typedef struct
{
ULONG ulReserved;
LPTSTR lpszSubject;
LPTSTR lpszNoteText;
LPTSTR lpszMessageType;
LPTSTR lpszDateReceived;
LPTSTR lpszConversationID;
FLAGS flFlags;
lpMapiRecipDesc lpOriginator;
ULONG nRecipCount;
lpMapiRecipDesc lpRecips;
ULONG nFileCount;
lpMapiFileDesc lpFiles;
} MapiMessage, FAR *lpMapiMessage;
Of these 12 members, this article will address two, nFileCount and lpFiles.
nFileCount (as this member states) is the number of attachments your
message contains. lpFiles is a pointer to another structure called
MapiFileDesc that contains six members, which are:
typedef struct
{
ULONG ulReserved;
ULONG flFlags;
ULONG nPosition;
LPTSTR lpszPathName;
LPTSTR lpszFileName;
LPVOID lpFileType;
} MapiFileDesc, FAR *lpMapiFileDesc;
You can determine if you're dealing with an OLE file if lpMapiMessage->
lpMapiFileDesc->flFlags tests true for MAPI_OLE_STATIC or MAPI_OLE.
Remember the OLE file is copied to your temp directory or whatever path
you've set in your environment variable TEMP.
Once you have determined that the attachment is an OLE object and you have
determined the location of your attachment, you can treat this file like an
ordinary structure storage. For example, you can send the information
contained in the storage to the clipboard.
Sample Code
StgCreateDocfile(OLESTR("c:\\temp\\storage.tmp"),STGM_CREATE |
STGM_READWRITE|STGM_SHARE_EXCLUSIVE,0,&pStore);
// lpMapiMessage->lpFiles->lpszPathName not only contains the full path
// of the file but also the name of the file.
OleCreateFromFile(CLSID_NULL,OLESTR(lpMapiMessage->lpFiles->lpszPathName),
IID_IDataObject,OLERENDER_DRAW,NULL,pCOleclientSite,pStore,
(LPVOID*)&pDataObject);
OleSetClipboard(pDataObject);
You'll have to implement IOleClientSite if you use the OleCreateFromFile
API. Here's an example of an implementation:
class COleclientsite : public IOleClientSite
{ ... };
STDMETHODIMP COleclientsite::QueryInterface(REFIID riid, LPVOID *ppvobj)
{
*ppvobj = NULL;
if((IID_IUnknown == riid ) || ( IID_IOleClientSite == riid)) *ppvobj =
this;
if(*ppvobj != NULL)
{
((LPUNKNOWN)*ppvobj)->AddRef();
return NOERROR;
}
else return ResultFromScode(E_NOINTERFACE);
}
/* because you are passing a pointer of IOleClientSite to
OleCreateFromFile, you need to ensure that the ref count is set to one
*/
COleclientsite::COleclientsite():refcnt(1){}
STDMETHODIMP_(ULONG)COleclientsite::AddRef(void)
{
return ++refcnt;
}
STDMETHODIMP_(ULONG)COleclientsite::Release(void)
{
unsigned int local_var = refcnt;
if(--local_var == 0)
delete this;
return local_var;
}
STDMETHODIMP COleclientsite::SaveObject()
{
return NOERROR;
}
STDMETHODIMP COleclientsite::GetMoniker(DWORD dwAssign,DWORD
dwWhichMoniker,LPMONIKER *ppmonk)
{
*ppmonk = NULL;
return ResultFromScode(E_NOTIMPL);
}
STDMETHODIMP COleclientsite::GetContainer(LPOLECONTAINER *ppCon)
{
*ppCon = NULL;
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP COleclientsite::ShowObject()
{
return ResultFromScode(E_NOTIMPL);
}
STDMETHODIMP COleclientsite::OnShowWindow(BOOL fShow)
{
return NOERROR;
}
STDMETHODIMP COleclientsite::RequestNewObjectLayout()
{
return NOERROR;
}