Click here to Skip to main content
Click here to Skip to main content

SendTo mail recipient

By , 31 Mar 2003
 

Introduction

This article provides a code snippet in order to programmatically send one or more files to the mail recipient, mimicking the SendTo mail recipient shell extension. I have heard many people searching for this feature, and actually I thought that, as there doesn't seem to be such source code posted on the net, I could just as well post it.

Introducing the SendTo mail shortcut

You may skip this section if you are not interested in the r.e. technique.

The SendTo mail shortcut is a shell extension. See Mike Dunn's complete idiot guide for further info.

The trick is to find out that the SendTo mail recipient shortcut is actually essentially an empty file with .MAPIMAIL as (hidden) extension name. Then, by looking up file type association in the registry (HKCR\.MAPIMAIL), it's straight forward to figure out that it is targeting a COM object with clsid = {9E56BE60-C50F-11CF-9A2C-00A0C90A90CE}. This object is sendmail.dll, a COM helper which takes advantage of either Outlook Express or Outlook to send e-mail file attachments. Next, looking up this CLSID in OLE View clearly showed that the sendmail COM component also implements the IDropTarget, IShellExtInit and IPersistFile interfaces, just like any drop handler.

Ok, basically I need to prepare a bag with dropped filenames, make sure they can be retrieved by implementing the IDataObject interface, a simple communication interface, and then mimic a standard drag and drop sequence, with two check points : DragEnter(IDataObject*) and Drop(IDataObject*).

One of the interesting points is to start implementing the IDataObject interface starting with contract, i.e. the methods it is supposed to expose. And then cowardly insert a breakpoint into any default method implementation only to get to know whether it's called or not, and in what order.

If you are interested in mimicking other SendTo shortcuts, don't hesitate to check out this registry key: HKLM\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved.

IDataObject implementation

The following code implements the IDataObject interface. In fact, only a few methods are required to be implemented. Those are, in order:

  • EnumFormatEtc(), called by the sendmail helper to know what content formats the IDataObject is holding
  • IEnumFORMATETC::Next(),Reset(), called to list all formats. We are expected to let the sendmail helper know that we do hold the CF_HDROP clipboard format (standard used for file drag-and-drop support), even if in fact we are not using the clipboard at all.
  • GetData(), called to actually get the list of files we are willing to send.

Because on Windows file drag-and-drop operations rely on the CF_HDROP / DROPFILES structure, we simply prepare such a structure to play with. Here is the code :

#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

    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,
            /*[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** ppenum)
  {
    return S_OK;
  }
};

Using it

And here is how to use it to send c:\346.jpg and c:\tmp\myfile.zip:

  ::CoInitialize(NULL);

  CDataObject cdobj("c:\\346.jpg\nC:\\tmp\\myfile.zip");
  IDataObject *pDataObject = &cdobj;


  IDropTarget *pDropTarget = NULL;

  // create an instance, and mimic drag-and-drop
  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();

To compile this code, you only need WIN32.

Why SendTo is better than the mailto trick

You could tell me that shell-executing a mailto URL is just as fine, and much simpler code in practice. Yes and no. Yes, it does so, and it can't be simpler since that's only one line of code (just remember to escape ASCII chars in the body with hex replacements of the form %0D, %20, ...).

No, it does not provide support for file attachment(s), which is why the SendTo shortcut comes handy. And there is more to it. The truth is that ::ShellExecute() cannot handle parameter strings over 2048 bytes, which means your e-mail body size cannot go beyond 2048 bytes. If you try to send a large e-mail, it will result in a GPF. At this point, you could replace ::ShellExecute with a well thought ::WinExec call, using the actual mailto command line declared in the registry and target the current e-mail client (for instance, "%ProgramFiles%\Outlook Express\msimn.exe" /mailurl:%1). But then the limitation is 32 KB. As a conclusion, there is no way to send e-mails larger than 32KB using the mailto protocol. The SendTo shortcut explained in this article is definitely the way to go !

History

  • First relaese -March 22, 2003.
  • Updated on April 1st, removal of the clipboard use (Chris Guzak).

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

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.
 

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralThe most simple solutionmemberLord_Crow10-Jul-09 1:57 
Using Mapi32.dll
 
MAPISendMail(IntPtr.Zero, IntPtr.Zero, lastMsg, 8, 0);
 
lastMsg is a pointer to a MapiMessage struct wich defines all information about message (including attachs)
 
The key parameter is the fourth "8"
GeneralFabulous - but would like a small changememberStroudPete14-May-09 3:27 
This is a great utility. Having written an big system in dotnet for a small company who could not handle an smtp server, I was annoyed to find no way in .net of simulating mailto but with attachments. Surely there must be lots of people wanting to send (say) an invoice from an app as an email attachment - getting the installed email client's new email window with attachment done is the perfect way, allowing the rest of the info to be typed. This is perfect for that - launch SendTo with a Process.Start command having set the appropriate parameters (including WindowStyle = ProcessWindowStyle.Hidden) works perfectly.
 
However I would like a small change, the ability to omit the destination (-to) and NOT get the default"someone@domain.com". Without a destination address, the email can't be sent, but with a default an inattentive user can send it without entering the correct address. This is what happens with Send To - Mail Recipient. Smile | :)
GeneralHelp with other send to methodsmemberWillRGV2-Nov-07 5:20 
I have converted this project over to c# and the send to Mail recipient works fine. But I cant get any of the other send to items to work. Note I get the clsId by looking up file extension of a send to short cut located in the Environment.GetFolderPath(Environment.SpecialFolder.SendTo) folder in the registry key [HKEY_CLASSES_ROOT]. Any Ideas why these other send to item's dont do anything? Thanks Will.
GeneralRe: Help with other send to methodsmemberWillRGV2-Nov-07 6:57 
Ok it turns out my DragDropEffects were set to none. Now most of the send to items work except 'Desktop(create shortcut)' I have tried DragDropEffects dwEffect = DragDropEffects.Copy | DragDropEffects.Move; and DragDropEffects dwEffect = DragDropEffects.All. But 'Desktop(create shortcut)' returns a bad HRESULT on the drop -2147467259. Any Ideas on how to get the Send To 'Desktop(create shortcut)' working.
Thanks in advance,
Will.
GeneralRe: Help with other send to methodsmemberjkjhcjbhj12-Feb-08 3:25 
Can you share your code?
GeneralSendTo.exememberjbergetun5-Mar-07 1:01 
Hi, I realize that this is an old article but what the heck.
I can't seem to find the sendto.exe program that the author is recommending when you want to fill out the body and To: when sending a email. ..
 
Anyone know where i can find it ?
GeneralUnhandled exception in ntdll.dllmemberBen Kial17-Oct-05 14:05 
I just compiled the code in Visual Studio 2003 on WinXP SP2. When I run it I got the following error right after I got the following stack...
 
Does anybody hnow how to work around this problem.
 
SendMail.exe!CDataObject::Release() Line 58 C++
sendmail.dll!CMailRecipient::v_DropHandler() + 0x54
sendmail.dll!CSendTo::Drop() + 0x16
SendMail.exe!main(int argc=2, char * * argv=0x009916b0)
SendMail.exe!mainCRTStartup() Line 259 + 0x19 C
kernel32.dll!_BaseProcessStart@4() + 0x23
 

Unhandled exception at 0x0012fe79 in SendMail.exe: 0xC0000005: Access
violation writing location 0x7c90eb94.

QuestionNo way to specify recipient ?memberWeird Alexis15-Sep-05 6:28 
Great code, and very easy to use as a prebuild executable.
 
However it seems difficult, if not impossible, to specify a recipient for the e-mail.
 
I first thought I would change your code to take the first argument as a recipient's e-mail address.
 
But how to pass this argument to the SendTo handler???
 
Has anyone a clue how to do this?
AnswerRe: No way to specify recipient ?memberStephane Rodriguez.19-Sep-05 2:28 

I think you haven't understood what the intent of the source code. This code mimics the SendTo shortcut.
GeneralRe: No way to specify recipient ?memberWeird Alexis19-Sep-05 3:39 
You're right, the behaviour of the "SendTo" shortcut is is not what I needed (open a compose window with recipient and attached file)
 
After a little searching, I found another source code that meets my requirements:
 
http://www.arstdesign.com/articles/sendto.exe.html
GeneralRe: No way to specify recipient ?memberStephane Rodriguez.20-Sep-05 1:08 

Glad to see you found useful another piece of code of mine Wink | ;-)

Generaloutlook express message window is closedmemberAnton Heidelwalder22-Aug-05 4:01 
I tried to use this code for Outlook Express.
I called this code from my .exe. So I can open a new outlook message window with attachment from my application. But as soon my application is closed, this outlook express window disappears.
Any idea?
Thanks Anton
GeneralDoesn't work :(memberAndrew Ovcharov16-Jul-05 13:00 
I compile given code with Visual Studio .NET 2003 and run under Windows XP SP2. It falls somewhere inside of ntdll module without call stack in pDropTarget->Drop call
GeneralSame Problem Herememberidliiyer3-Nov-05 10:03 
Hi,
 
First let me thank Stephane Rodriguez for the enlightening article. I downloaded the source code for this article and compiled it in VS .NET 2003 under windows XP. It didn't work though. As Andrew Occharov pointed out it seems to fail in
pDropTraget.Drop call. It might be because the "dwEffect" returned by pDropTarget.DragEnter is "DROPEFFECT_NONE" which apparently means (MSDN DOC.)that the target doesn't want to accept the drop! All I know is that the pDropTarget.Drop actually calls "QueryInterface" twice. Is that because my defualt clien is Eudora and the CLSID used in the code doesn't work with Eudora? But the actual right click "Sent To mail recipient" button works for me and the .MAPIMAIL extension in the registry seems to point to the same CLSID used in the code so it cant be because of the mail client!!
 
Now I also downloaded the code at http://www.arstdesign.com/articles/sendto.exe.html whose functionality works better for my purposes than the "Sent To mail recipient" anyway and this code worked like a charm. Thanks again Stephane! But I am curious as to why the "Send To mail Recipient" code didn't work? Any ideas any one?
 
Thanks!
QuestionRe: Same Problem HerememberBen Kial19-Apr-07 11:17 
Hi Idliiyer,
 
I was having the same problem as you compiled on VS .Net 2003 and I have Outlook Express Version 6.00.2900.2180. The "dwEffect" restured from pDropTarget.DragEnter is "0". So, did you got any reply on how to fix the problem?
 
Thanks in advance,
 

Ben
Generalsend mail failure --;memberchunghansu13-Feb-05 21:43 
at first, this is a great job for me...
I have been looking for this kind of program...
I implemented your MAPI source code in my application.
when e-mail button clicked, the new message pop up with attached files.
everything works well but when I click the send button the mail send operation
is failded...
with your sendto.exe works well...
what is the problem? please tell me why?
I guess this is related with mail account...
If you have the solution with it please let me know...
have a nice day
 
--- thunder ---
GeneralRe: send mail failure --;memberStephane Rodriguez.26-Feb-05 9:38 

If you explain your problem a little more in details, ie show a code snippet, I guess some people may take a look at it. Alternatively, you can post it in the C++ forum.
GeneralC# source codesussAudimar25-Jan-05 8:35 
Hello Stephane,
 
Congratulations on an excellent article -- very close to what I'm looking for! I wonder if you have an equivalent source code written in C#. Any hint on how to translate your Visual C++ code to C# would be greatly appreciated.
 
Thanks!
 
Audimar
apbangi@yahoo.com
GeneralRe: C# source codememberrinofarina11-Aug-10 5:03 
//
    // format of CF_HDROP and CF_PRINTERS, in the HDROP case the data that follows
    // is a double null terinated list of file names, for printers they are printer
    // friendly names
    //
    struct DROPFILES
    {
        public int pFiles;       // offset of file list
        public Point pt;         // drop point (client coords)
        public int fNC;          // is it on NonClient area
        // and pt is in screen coords
        public int fWide;        // WIDE character switch
    }
 
    class DropTargetDataObject : IDataObject, IEnumFORMATETC
    {
        private const int CF_HDROP = 15;
        //
        // Success codes
        //
        private const int S_OK = 0;
        private const int S_FALSE = 1;
 
        private StringBuilder mFilePaths;
 
        public DropTargetDataObject(IEnumerable<string> filePaths)
        {
            if (filePaths == null)
                throw new ArgumentNullException("filePaths");
 
            mFilePaths = new StringBuilder();
            IEnumerator<string> enu = filePaths.GetEnumerator();
            while (enu.MoveNext())
            {
                string file = enu.Current;
                mFilePaths.Append(file);
                mFilePaths.Append('\0');
            }
            mFilePaths.Append('\0');
        }
 
        public int DAdvise(ref FORMATETC pFormatetc, ADVF advf, IAdviseSink adviseSink, out int connection)
        {
            throw new NotImplementedException();
        }
 
        public void DUnadvise(int connection)
        {
            throw new NotImplementedException();
        }
 
        public int EnumDAdvise(out IEnumSTATDATA enumAdvise)
        {
            throw new NotImplementedException();
        }
 
        public IEnumFORMATETC EnumFormatEtc(DATADIR direction)
        {
            if (direction == DATADIR.DATADIR_GET)
                return this;
            return null;
        }
 
        public int GetCanonicalFormatEtc(ref FORMATETC formatIn, out FORMATETC formatOut)
        {
            throw new NotImplementedException();
        }
 
        public void GetData(ref FORMATETC format, out STGMEDIUM medium)
        {
            if (format.cfFormat != CF_HDROP)
            {
                medium = new STGMEDIUM();
                return;
            }
 
            DROPFILES dropFiles = new DROPFILES();
            dropFiles.pFiles = Marshal.SizeOf(dropFiles);
            dropFiles.pt = new Point();
            dropFiles.fNC = 1;
            dropFiles.fWide = 1;
 
            int size = Marshal.SizeOf(dropFiles);
            size += (mFilePaths.Length * sizeof(char));
            IntPtr hglbCopy = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(dropFiles, hglbCopy, false);
 
            //copy the string into the memory following the structure
            for (int i = 0; i < mFilePaths.Length; i++)
            {
                char c = mFilePaths[i];
                Marshal.WriteInt16(hglbCopy, dropFiles.pFiles + (i * 2), c);
            }
 
            medium = new STGMEDIUM();
            medium.tymed = TYMED.TYMED_HGLOBAL;
            medium.unionmember = hglbCopy;
            medium.pUnkForRelease = 0;
        }
 
        public void GetDataHere(ref FORMATETC format, ref STGMEDIUM medium)
        {
            throw new NotImplementedException();
        }
 
        public int QueryGetData(ref FORMATETC format)
        {
            throw new NotImplementedException();
        }
 
        public void SetData(ref FORMATETC formatIn, ref STGMEDIUM medium, bool release)
        {
            throw new NotImplementedException();
        }
 
        public void Clone(out IEnumFORMATETC newEnum)
        {
            throw new NotImplementedException();
        }
 
        public int Next(int celt, FORMATETC[] rgelt, int[] pceltFetched)
        {
            rgelt[0].cfFormat = CF_HDROP;
            rgelt[0].dwAspect = DVASPECT.DVASPECT_CONTENT;
            rgelt[0].lindex = -1;
            rgelt[0].ptd = IntPtr.Zero;
            rgelt[0].tymed = TYMED.TYMED_HGLOBAL;
 
            pceltFetched = new int[] { 1 };
 
            return S_OK;
        }
 
        public int Reset()
        {
            throw new NotImplementedException();
        }
 
        public int Skip(int celt)
        {
            throw new NotImplementedException();
        }
    }
 
And then using it, you need to define the interface:
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("00000122-0000-0000-C000-000000000046")] // This is the value of IID_IDropTarget from the Platform SDK.
    [ComImport]
    interface IDropTarget
    {
        void DragEnter([In] System.Runtime.InteropServices.ComTypes.IDataObject dataObject, [In] uint keyState, [In] System.Drawing.Point pt, [In, Out] ref uint effect);
        void DragOver([In] uint keyState, [In] System.Drawing.Point pt, [In, Out] ref uint effect);
        void DragLeave();
        void Drop([In] System.Runtime.InteropServices.ComTypes.IDataObject dataObject, [In] uint keyState, [In] System.Drawing.Point pt, [In, Out] ref uint effect);
    }
 
...and the #defines:
 
private const uint MK_LBUTTON = 0x0001;
 
...Then actually call it from code:
 
Type oType = Type.GetTypeFromCLSID(new Guid("9E56BE60-C50F-11CF-9A2C-00A0C90A90CE"));
                            instance = Activator.CreateInstance(oType);
                            if (instance != null)
                            {
                                IDropTarget dropTarget = instance as IDropTarget;
                                if (dropTarget != null)
                                {
                                    DropTargetDataObject dataObject = new DropTargetDataObject(new string[] { destination });
 
                                    System.Drawing.Point pt = new System.Drawing.Point(0, 0);
                                    uint dwEffect = 0;
                                    dropTarget.DragEnter(dataObject, MK_LBUTTON, pt, ref dwEffect);
                                    dropTarget.Drop(dataObject, MK_LBUTTON, pt, ref dwEffect);
                                }
                            }

Generalmessage bodymemberSarfraz Anwar15-Jun-04 21:41 
hi
first of all i would like to thnak to u on writing such a great article that realy solved one of my problems, now i was hopping to have some idea to also add some text or html in message body. previously i was using mailto to do so but i was having problem to add attachments. now i want to add attachments and also add some text or html to message body of email. any suggestions will be a great help for me. thanks
 
sarfraz
GeneralRe: message bodymemberStephane Rodriguez.16-Jun-04 1:06 

I am afraid this has nothing to do with the intent of the article. If you want to do that, you can stick to :
- ::ShellExecute("mailto:ddd@ff.com?subject=xxx&body=xxxx",...); but then you have no file attachment
- Use SimpleMAPI (there are a couple articles on MSDN and Codeproject), in which the scenarios you mention are supported.
- Use any proprietary mechanism of your choice, for instance if you know the client is using Outlook then you could use the MS CDO run-time to do this.
 
In each and every point of view, this has not much to do with the article : how to simulate the "SendTo mail recipient" with code.
 


GeneralRe: message bodymemberSarfraz Anwar17-Jun-04 2:18 
hi
thanks for your reply. i realy appritiate ur efforts to guide me.
actually the main idea behind this sendmail was drag and drop ,prepare a list of files and drop it in to mail recipient folder. right
my point is if u could drag and drop some files, u could also drop some text / html into the mail . the idea is similer but implemntation could be a little differnt.
i had used automation to perform the same task in ms outlook which is very easy thing to do , but i need to do this in all the email programs which is not possible with mapi and autmation .
anyhow, i again thank u for paying attention to my problem and helping me.
 

 
sarfraz
GeneralRe: message bodymemberStephane Rodriguez.17-Jun-04 5:07 
Sarfraz Anwar wrote:
but i need to do this in all the email programs which is not possible with mapi and autmation .
 
I disagree. Simple MAPI will use the default email client, be it Outlook Express, Outlook, or anything else.
 
Automation though, if you are talking about CDO is indeed a different animal, it only knows how to deal with Outlook, and only Outlook. Which is why it is not recommended unless you target Outlook.

GeneralRe: message bodymemberAndrew Foss29-Aug-04 18:57 
Like Sarfraz and probably many others I just want to call up the default email client with an email address, some text, and a file attached. Almost every application can do this but how? All I can find after two days of searching is people saying ShellExecute won't work, your code snippet, you say, won't do it (btw it throws an access violation at or just after pDropTarget->Drop(pDataObject, MK_LBUTTON, pt, &dwEffect);) and nothing on MSDN that I can find. I understand I could write my own email client but that's too crazy just to send a file and you give up all the services and user preference that the default client offers. If there is a MAPI solution is any code anywhere?
Stephanie, your articles are great I do hope you can give us a few clues here.
 
andrew
GeneralRe: message bodymemberStephane Rodriguez.29-Aug-04 20:53 

Try this article and piece of code I have posted on my website : http://www.arstdesign.com/articles/sendto.exe.html
 
It uses MAPI to do exactly what you want.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

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