C++调用outlook发送电子邮件替代shellexecute

 公司有个即时通讯软件,以前调用shellexecute发送电子邮件,发现这个函数在有些机器经常失效,后上codeproject.com找了些资料,自己修改封装,测试效果不错,好东西大家共分享:

 

#ifndef __SENDFILETO_H__
#define __SENDFILETO_H__

#include <mapi.h>
#include <string>

class CSendFileTo
{
public:
    static bool SendMailAttach(const std::string& strAttachmentFileName, const std::string& strSubject=_T(""))
 {
  if (strAttachmentFileName.empty())
   return false;

  HINSTANCE hMAPI = ::LoadLibraryA(_T("MAPI32.DLL"));
  if (!hMAPI)
   return false;

  ULONG (PASCAL *SendMail)(ULONG, ULONG_PTR, MapiMessage*, FLAGS, ULONG);
  (FARPROC&)SendMail = GetProcAddress(hMAPI, _T("MAPISendMail"));

  if (!SendMail)
        {
            ::FreeLibrary(hMAPI);
            return false;
        }
   

  char szFileName[_MAX_PATH];
  char szPath[_MAX_PATH];
  char szSubject[_MAX_PATH];
       
        strcpy(szFileName,strAttachmentFileName.c_str());
        strcpy(szPath, strAttachmentFileName.c_str());
        strcpy(szSubject, strSubject.c_str());

  /*::StrCpy(szFileName, strAttachmentFileName.GetString());
  ::StrCpy(szPath, strAttachmentFileName.GetString());
  ::StrCpy(szSubject, strSubject.GetString());*/

  MapiFileDesc fileDesc;
  ::ZeroMemory(&fileDesc, sizeof(fileDesc));
  fileDesc.nPosition = (ULONG)-1;
  fileDesc.lpszPathName = szPath;
  fileDesc.lpszFileName = szFileName;

  MapiMessage message;
  ::ZeroMemory(&message, sizeof(message));
  message.lpszSubject = szSubject;
  message.nFileCount = 1;
  message.lpFiles = &fileDesc;

  int nError = SendMail(0, (ULONG)::GetDesktopWindow(), &message, MAPI_LOGON_UI|MAPI_DIALOG, 0);

  if (nError != SUCCESS_SUCCESS && nError != MAPI_USER_ABORT && nError != MAPI_E_LOGIN_FAILURE)
        {
            ::FreeLibrary(hMAPI);
            return false;
        }
   
        ::FreeLibrary(hMAPI);
  return true;
 }

    static bool SendMail(char* szToEmail, char* szToName = "")
    {
        /*
        MapiFileDesc fileDesc;
        memset(&fileDesc, 0, sizeof(fileDesc));
        fileDesc.nPosition = (ULONG)-1;

        //USES_CONVERSION;

        CString strFullPath("c://test.txt");
        CString strFileName;
        int nPos = strFullPath.ReverseFind(_T('//'));
        if (nPos != -1)
        {
            strFileName = strFullPath.Right(strFullPath.GetLength() - nPos - 1);
        }
        else
        {
            strFileName = strFullPath;
        }

        fileDesc.lpszPathName = strFullPath.GetBuffer();
        fileDesc.lpszFileName = strFileName.GetBuffer();
        */

        MapiMessage message;
        memset(&message, 0, sizeof(message));

        message.lpszSubject = "";
        message.nFileCount = 0;
        message.lpFiles = NULL;
        message.flFlags = MAPI_SENT;
        message.ulReserved = 0;

        /*
        MapiRecipDesc sender = {0};
        sender.ulRecipClass = MAPI_ORIG;
        sender.lpszName = T2A("ken");
        char szAdderss[100] = "SMTP:";
        strncat(szAdderss, sender.lpszName, 100);
        sender.lpszAddress = szAdderss;
        sender.ulReserved = 0;


        message.lpOriginator = &sender;
        */

        MapiRecipDesc recv = {0};
        recv.ulRecipClass = MAPI_TO;
        recv.lpszAddress = szToEmail;
        recv.lpszName = szToName;

        message.lpRecips = &recv;
        message.nRecipCount = 1;

        HINSTANCE hMAPI = ::LoadLibraryA(_T("MAPI32.DLL"));
        if ( hMAPI == NULL )
            return false;

        ULONG (PASCAL *SendMail)(ULONG, ULONG_PTR, MapiMessage*, FLAGS, ULONG);
        (FARPROC&)SendMail = GetProcAddress(hMAPI, _T("MAPISendMail"));

        if (!SendMail)
        {
          
            ::FreeLibrary(hMAPI);
            return false;
        }


        int nError = SendMail(0, (ULONG)::GetDesktopWindow(),
            &message, MAPI_DIALOG | MAPI_LOGON_UI , 0);

        if (nError != SUCCESS_SUCCESS &&
            nError != MAPI_USER_ABORT && nError != MAPI_E_LOGIN_FAILURE)
        {
            ::FreeLibrary(hMAPI);
            return false;
        }

        ::FreeLibrary(hMAPI);
        return true;

    }
};

#endif

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Outlook 2003 addin<br> 赵果(apple) 2008年3月7日星期五<br><br><br>摘要:<br> 目前随着蓝牙、红外通信的不断展,同步协议的应用变得越来越广泛。而同步引擎需要修改日志changelog的协助。本文的目的是记录用户对outlook2003联系人的操作日志,供同步引擎使用。<br>Outlook 2003 addin属于microsoft office com中的应用。目的是用于捕捉outlook2003 联系人(contacts)的增加、删除、修改的消息。<br><br>关键词:同步, changelog<br><br>工程介绍:<br>office com插件必须实现IDTExtensibility2接口。所有继承于IDTExtensibili ty2接口的COM插件必须实现5个方法:OnConnection,OnDisconnection,OnAddinUpdate,OnBeginShutDown,OnStartupComplete <br><br>1. 建立addin工程<br>(1) 启动VC++环境,新建一个工程,选择ATL COM AppWizard,为工程命名为Outlook Addin,确定。选择Dynamic Link Library完成。然后,点击菜单“插入”->“新建ATL对象”,选择“Simple Object”,命名为Addin,选择Attributes标签,选中Support ISupportErrorInfo,其他选项默认。<br>(2) 在新建的类上右键implement Interface->AddTypelib->Microsoft Add-in Designer-> IDTExtensibility2。如下图所示:<br> <br>图1 添加outlook2003接口图示<br> <br>图2 添加addin designer接口图示<br><br> <br>图3 添加接口图示<br>(3) 添加注册表信息<br>向导实现了我们所选择的接口,并为IDTExtensibility2接口的5个方法提供了默认实现。现在,一个基本的自动化COM对象就准备好了。通过向rgs文件添加注册条目,我们就可以用Outlook来注册这个插件。打开文件OAddin.rgs,在文件末尾插入以下代码:<br>HKCU_Software<br> {<br> Microsoft<br> {<br> Office<br> {<br> Outlook<br> {<br> Addins<br> {<br> 'OAddin.OAddin'<br> {<br> val FriendlyName = s 'SMIME Addin'<br> val Description = s 'ATLCOM Outlook Addin'<br> val LoadBehavior = d '00000003'<br> val CommandLineSafe = d '00000000' <br> }<br> }<br> }<br> }<br> }<br> }<br>}<br>注册条目看起来是很简单的。<br>1)LoadBehavior DWORD类型表明了Outlook装载COM插件的时机。我们的插件要在启动时装载,所以它的值设为3。LoadBehavior == 3 表示启动和连接时就自动运行;<br>• 0 = Disconnect - 不加载。<br>• 1 = Connected - 被加载。 <br>• 2 = Bootload - 宿主程序启动时加载。<br>• 8 = DemandLoad - 需要时加载。<br>• 16 = ConnectFirstTime - 只在下次运行时加载一次。<br>2)FriendlyName: 字符串类型,插件的名称,将在相应程序的COM加载对话框中看到。<br> 3)Description: 字符串类型,插件的描述信息。<br> 4)CommandLineSafe: DWORD类型,命令行方式,可以设置为0x01(真)或0x00(假)。<br><br>2. 代码分析:<br>(1)需要向outlook注册add, modify, delete事件<br>A. 申明outlook events;<br> SINK_ENTRY_INFO( 1, __uuidof(Outlook::ItemsEvents), 0xf001, getOutlookaddItemsEvents, &OnItemAddInfo )<br> SINK_ENTRY_INFO( 2, __uuidof(Outlook::ItemsEvents), 0xf002, getOutlookmodifyItemsEvents, &OnItemModifyInfo )<br> SINK_ENTRY_INFO( 3, __uuidof(Outlook::ItemsEvents), 0xf003, getOutlookdeleteItemsEvents, &OnItemDeleteInfo )<br>0xf001:add 0xf002 modify 0xf003 delete<br><br>B. 在onconnection中注册事件;<br>outlookItem_add::DispEventAdvise( (IDispatch*)m_spItemsEvents_Add, &__uuidof(Outlook::ItemsEvents) );<br><br>C. 在ondisconnection中释放事件,也是在outlook关闭时停止捕捉消息;<br><br>(2)在outlook回调你的函数中实现changeglog功能。<br>Eg: void __stdcall CAddin::getOutlookaddItemsEvents( IDispatch* pdispItemsEvents )<br>{<br> CComQIPtr<Outlook::_ContactItem> ct(pdispItemsEvents);<br>}<br><br><br>结论:<br>本人文笔不好,请各大蝦不要见笑,详细还是见代码吧,但本人能够保证程序没有任何问题。<br>本人对office系列的产品有较深的见解,并具有浓厚的兴趣。目前在研究outlook express的事件捕捉,希望有跟我志同道合的朋友欢迎跟我联系一起分享开的快乐。QQ:35912467<br><br><br><br><br> 邮箱:my716917@sina.com<br> Hugo.zhao@mic.com.tw<br>电话:13458588397<br>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值