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;
  LPITEMIDLIST pidl;
  SFGAOF sfgao;
  hr = SHParseDisplayName(pszPath, NULL, &pidl, 0, &sfgao);
  if (SUCCEEDED(hr))
  {
    IShellFolder *psf;
    LPCITEMIDLIST pidlChild;
    hr = SHBindToParent(pidl, IID_IShellFolder, (void**)&psf,
                        &pidlChild);
    if (SUCCEEDED(hr))
    {
      hr = psf->GetUIObjectOf(hwnd, 1, &pidlChild, riid, NULL, ppv);
      psf->Release();
    }
    CoTaskMemFree(pidl);
  }
  return hr;
} 

#ifdef DEFINE_GUID
#undef DEFINE_GUID
#endif 

#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;
#else
  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;
      }
      pDropTarget->Release();
    } 

#ifndef UNICODE
    free(pwszBuffer);
#endif // UNICODE 

    pDataObject->Release();
  } 

  return hr;
}

Sphere: Related Content

No comments yet.

Write a comment: