Implementing “Sent To Mail Recipient”; in your Application

I wanted to be able to easily email a file from a utility I wrote, and thought “wouldn’t it be so much easier if I could incorporate the ‘Sent To Mail Receipient’ functionality available within Windows” so I didn’t have to worry about which email application is actually installed.  I know this will typically limit this to either Microsoft Outlook Express or Microsoft Outlook, but at least I don’t have to worry about the mechanism required to create an email with an attachment which is yet to be sent.

So the following is the C++ code which implements createEmailWithAttachment().

The GetUIObjectOfFile() routine is taken from Raymand Chen’s blog where he posted How to host an IContextMenu, part 1.

The droptarget code was taken from a discussion thread which was incomplete.

Unicode and non-unicode variants are supported.

HRESULT GetUIObjectOfFile(HWND hwnd, LPCWSTR pszPath, REFIID riid, 
                          void **ppv) 
  *ppv = NULL; 
  HRESULT hr; 
  SFGAOF sfgao; 
  hr = SHParseDisplayName(pszPath, NULL, &pidl, 0, &sfgao); 
  if (SUCCEEDED(hr)) 
    IShellFolder *psf; 
    LPCITEMIDLIST pidlChild; 
    hr = SHBindToParent(pidl, IID_IShellFolder, (void**)&psf, 
    if (SUCCEEDED(hr)) 
      hr = psf->GetUIObjectOf(hwnd, 1, &pidlChild, riid, NULL, ppv); 
  return hr; 


#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) 
        EXTERN_C const GUID name 
                = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } } 

DEFINE_GUID(CLSID_SendMail, 0x9E56BE60, 0xC50F, 0x11CF, 0x9A, 0x2C, 0x00, 
            0xA0, 0xC9, 0x0A, 0x90, 0xCE); 

static HRESULT createEmailWithAttachment(LPCTSTR pszFileName) 
  IDataObject *pDataObject = NULL; 
  IDropTarget *pDropTarget = NULL; 
  LPCWSTR pwszFileName = NULL; 
  bool bCreated = false; 
  HRESULT hr; 

#ifdef UNICODE 
  pwszFileName = pszFileName; 
  WCHAR *pwszBuffer = NULL; 

  int nLength = MultiByteToWideChar(CP_ACP, 0, pszFileName, 
                                    strlen(pszFileName), NULL, 0); 
  if (nLength DragEnter(pDataObject, MK_LBUTTON, pt, &dwEffect); 
      if (SUCCEEDED(hr)) 
        hr = pDropTarget->Drop(pDataObject, MK_LBUTTON, pt, &dwEffect); 
        if (SUCCEEDED(hr)) 
          bCreated = true; 

#ifndef UNICODE 
#endif // UNICODE 


  return hr; 

Leave a Reply