Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

SendTo mail recipient

, 31 Mar 2003
Programmatically use the SendTo mail recipient shortcut
sendtomail_src.zip
sendtomail_srccode.zip
SendMail.dsp
SendMail.dsw
// SendMail.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <ole2.h> // IDataObject
#include <shlobj.h> // DROPFILES
#include <tchar.h> // TCHAR

class CDataObject : public IDataObject, IEnumFORMATETC
{
	// Members
protected:
	BOOL m_bReset;
	LPTSTR m_szFiles;
	int m_nLen;

	// Constructor
public:
	CDataObject(LPTSTR szFiles)
	{
		Reset();
		
		if (!szFiles)
		{
			m_szFiles = NULL;
			return;
		}

		// replace \n chars with \0 chars
		m_nLen = _tcslen(szFiles)+1;
		m_szFiles = new TCHAR[m_nLen];
		memcpy(m_szFiles, szFiles, m_nLen * sizeof(TCHAR));

		LPTSTR szTmp = m_szFiles;
		while ( szTmp=_tcschr(szTmp,'\n') )
			*szTmp++ = '\0';

	}
	virtual ~CDataObject()
	{
		delete [] m_szFiles;
	}

public:
	HRESULT __stdcall QueryInterface(REFIID iid, void ** ppvObject)
	{
		*ppvObject = (IDataObject*) this;
		return S_OK;
	}

	ULONG __stdcall AddRef()
	{
		return 1;
	}
	ULONG __stdcall Release()
	{
		return 0;
	}

	

	// IDataObject implementation
	//
	HRESULT __stdcall GetData(FORMATETC *pFormatetc, STGMEDIUM * pmedium)
	{
		if (pFormatetc->cfFormat != CF_HDROP  || !pmedium)
			return S_FALSE;

		if (!m_szFiles)
			return S_FALSE; // make sure to set the files before (see constructor)

		pmedium->tymed = TYMED_HGLOBAL;

		// set DROPFILES structure
		HGLOBAL hglbCopy = ::GlobalAlloc(GMEM_MOVEABLE, sizeof(DROPFILES) + (m_nLen + 2) * sizeof(TCHAR)); 
		LPDROPFILES pDropFiles = (LPDROPFILES) ::GlobalLock(hglbCopy);
		pDropFiles->pFiles = sizeof(DROPFILES);
		pDropFiles->pt.x = pDropFiles->pt.y = 0;
		pDropFiles->fNC = TRUE;
		pDropFiles->fWide = FALSE; // ANSI charset
		LPTSTR lptstrCopy = (LPTSTR) pDropFiles;
		lptstrCopy += pDropFiles->pFiles;
		memcpy(lptstrCopy, m_szFiles, m_nLen * sizeof(TCHAR)); 
		lptstrCopy[m_nLen] =  '\0';    // null character 
		lptstrCopy[m_nLen+1] = '\0';    // null character 
		::GlobalUnlock(hglbCopy); 

		pmedium->hGlobal = hglbCopy;
		pmedium->pUnkForRelease = NULL;

		return S_OK;
	}

	HRESULT __stdcall GetDataHere(FORMATETC * pFormatetc, STGMEDIUM * pmedium)
	{
		return S_OK;
	}

    HRESULT __stdcall QueryGetData(FORMATETC * pFormatetc)
	{
		return S_OK;
	}

	HRESULT __stdcall GetCanonicalFormatEtc(FORMATETC * pFormatetcIn, FORMATETC * pFormatetcOut)
	{
		return S_OK;
	}

	HRESULT __stdcall SetData(FORMATETC * pFormatetc, STGMEDIUM * pmedium, BOOL fRelease)
	{
		return S_OK;
	}

	HRESULT __stdcall EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC ** ppenumFormatetc)
	{
		if (dwDirection==DATADIR_GET)
		{
			*ppenumFormatetc = this;
			return S_OK;
		}
		else
			return S_FALSE;
	}

	HRESULT __stdcall DAdvise(FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection)
	{
		return S_OK;
	}

	HRESULT __stdcall DUnadvise(DWORD dwConnection)
	{
		return S_OK;
	}

	HRESULT __stdcall EnumDAdvise(IEnumSTATDATA ** ppenumAdvise)
	{
		return S_OK;
	}


	// IEnumFORMATETC implementation
	//
	HRESULT __stdcall Next( 
            /* [in] */ ULONG celt,
            /* [length_is][size_is][out] */ FORMATETC __RPC_FAR *rgelt,
            /* [out] */ ULONG __RPC_FAR *pceltFetched)
	{
		if (!m_bReset) return S_FALSE;

		m_bReset = FALSE;

		FORMATETC fmt;
		fmt.cfFormat = CF_HDROP;
		fmt.dwAspect = DVASPECT_CONTENT;
		fmt.lindex = -1;
		fmt.ptd = NULL;
		fmt.tymed = TYMED_HGLOBAL;
		*rgelt = fmt; // copy struct
		if (pceltFetched) *pceltFetched = 1;

		return S_OK;
	}
        
    HRESULT __stdcall Skip(/*[in]*/ ULONG celt)
	{
		return S_FALSE;
	}
        
    HRESULT __stdcall Reset()
	{
		m_bReset = TRUE;
		return S_OK;
	}
        
    HRESULT __stdcall Clone( 
            /* [out] */ IEnumFORMATETC __RPC_FAR *__RPC_FAR *ppenum)
	{
		return S_OK;
	}
};



// helper
//
// purpose:tells us whether the file exists
BOOL FileExists(LPTSTR szFilename)
{
	BOOL bFound = FALSE;

	WIN32_FIND_DATA findFile;
	HANDLE hContext;
	hContext=::FindFirstFile(szFilename, &findFile);
	if (  hContext != INVALID_HANDLE_VALUE )
	{
		::FindClose(hContext);
		bFound = TRUE;
	}
	return bFound;
}

int main(int argc, char* argv[])
{
	long nTotalLength = 0, i;

	// read cmdline, and make sure that files actually exist before they are sent
	for (i=1; i<argc; i++)
		nTotalLength += FileExists(argv[i]) ? (_tcslen(argv[i]) + 1) : 0;	

	if ( nTotalLength==0 )
		return 0; // good bye!

	LPTSTR szCmdLine = new TCHAR[nTotalLength+1];
	if (!szCmdLine)
		return 0;

	*szCmdLine = 0;

	for (i=1; i<argc; i++)
	{
		_tcscat(szCmdLine, argv[i]);	
		_tcscat(szCmdLine, "\n");
	}

	if ( szCmdLine )
	{

		// sendmail helper (requires either OE or Outlook)
		static const IID CLSID_SendMail = { 0x9E56BE60, 0xC50F, 0x11CF, 
		   { 0x9A, 0x2C, 0x00, 0xA0, 0xC9, 0x0A, 0x90, 0xCE } 
		};

 		CDataObject cdobj(szCmdLine);
		IDataObject *pDataObject = &cdobj;

		::CoInitialize(NULL);

		IDropTarget *pDropTarget = NULL;

		HRESULT hr;

		// sendmail object
		hr = ::CoCreateInstance(CLSID_SendMail, NULL, CLSCTX_ALL,
								IID_IDropTarget, 
								(void **)&pDropTarget);
		if (SUCCEEDED(hr))
		{
			POINTL pt = {0,0};
			DWORD dwEffect = 0;
			pDropTarget->DragEnter(pDataObject, MK_LBUTTON, pt, &dwEffect);
			pDropTarget->Drop(pDataObject, MK_LBUTTON, pt, &dwEffect);

			::Sleep(6*1000);

			pDropTarget->Release();
		}

		::CoUninitialize();

	}

	delete [] szCmdLine;

	return 0;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Addicted to reverse engineering. At work, I am developing business intelligence software in a team of smart people (independent software vendor).
 
Need a fast Excel generation component? Try xlsgen.
 

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141220.1 | Last Updated 1 Apr 2003
Article Copyright 2003 by Stephane Rodriguez.
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid