How to Put OLE Attachments on the ClipBoard from SimpleMAPI

ID: Q149977

3.51       | 4.00
WINDOWS NT | WINDOWS kbole kbhowto

The information in this article applies to:

SUMMARY

SimpleMapi provides a set of structures that you can use to obtain all sorts of file attachments. This article focuses on how to deal with OLE attachments (DocFiles) from your messages.

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

REFERENCES

OLE 2 Programmer's Reference Volume One, pages 318 - 328, pg 639. Microsoft Developer Studio Online Help \win32sdk\ole\ole programmer's reference\functions

Additional reference words: kbinf 4.00 KBCategory: kbole kbhowto KBSubcategory: mapi

Keywords          : kbcode mapi 
Version           : 3.51 | 4.00
Platform          : NT WINDOWS

Last Reviewed: May 22, 1998