VC++编写电子邮件程序www.diybl.com时间:2008-08-27作者:佚名编辑:本站点击:635[评论]VC++编写电子邮件程序一、概述----本文主要讲述如何使用VisualC++用MAPI编写E-mail程序。MAPI是包含在Windows之中的,因此不需要安装其他额外的部件。MAPI有以下三种形式:SMAPI,SimpleMAPI,简单的MAPICMC,CommonMessagingCalls,一般通讯调用完整的MAPI----SMAPI和CMC都包含在完整的MAPI中,当用户想执行一些高级操作,比如编写自己的E-mail服务器的时候,必须使用完整的MAPI。本文主要阐述如何编写能够收发电子邮件的程序,因此使用SMAPI就足够了。二、编写电子邮件程序3-1初始化MAPI----要使用MAPI,必须首先对它进行初始化。初始化包括以下三个步骤:装载MAPI32.DLL动态链接库找到想要调用的MAPI函数地址登录到电子邮件对象3-1-1装载MAPI32.DLL----要装载MAPI,用户必须程序运行时动态的装载一个动态链接库。LoadLibrary函数提供了此功能,它定位一个动态链接库,并返回HINSTANCE局柄(需要保存该句柄)。LoadLibrary的语法如下:LoadLibrary(lpLibFileName);其中lpLibFileName为LPCTSTR结构变量,是所要调用的库的路径和名称。程序示例://调用MAPI32.DLL并计算函数地址HINSTANCEhInstMail;hInstMail=::LoadLibrary(“MAPI32.DLL”);if(hInstMail==NULL){//错误处理//受篇幅限制,下面的错误处理部分省略}3-1-2确定函数地址----由于MAPI32.DLL是被动态装载的,因此不知道所要调用的函数地址,也就不能一开始就调用它们,而要通过函数名获得函数的地址,并在动态链接库中查找每一个函数并核实。因此首先必须为这些函数声明指针程序示例://为MAPI32.DLL中的函数声明函数指针ULONG(PASCAL*lpfnMAPISendMail)(LHANDLElhSession,ULONGulUIParam,lpMapiMessagelpMessage,FLAGSflFlags,ULONGulReserved);ULONG(PASCAL*lpfnMAPIResolveName)(LHANDLElhSession,ULONGulUIParam,LPTSTRlpszName,FLAGSulFlags,ULONGulReserved,lpMapiRecipDescFAR*lppRecip);ULONG(FARPASCAL*lpfnMAPILogon)(ULONGulUIParam,LPSTRlpszProfileName,LPSTRlpszPassword,FLAGSflFlags,ULONGulReserved,LPLHANDLElplhSession);ULONG(FARPASCAL*lpfnMAPILogoff)(LHANDLElhSession,ULONGulUIParam,FLAGSflFlags,ULONGulReserved);ULONG(FARPASCAL*lpfnMAPIFreeBuffer)(LPVOIDlpBuffer);ULONG(FARPASCAL*lpfnMAPIAddress)(LHANDLElhSession,ULONGulUIParam,LPSTRlpszCaption,ULONGnEditFields,LPSTRlpszLabels,ULONGnRecips,lpMapiRecipDesclpRecips,FLAGSflFlags,ULONGulReserved,LPULONGlpnNewRecips,lpMapiRecipDescFAR*lppNewRecips);ULONG(FARPASCAL*lpfnMAPIFindNext)(LHANDLElhSession,ULONGulUIParam,LPSTRlpszMessageType,LPSTRlpszSeedMessageID,FLAGSflFlags,ULONGulReserved,LPSTRlpszMessageID);ULONG(FARPASCAL*lpfnMAPIReadMail)(LHANDLElhSession,ULONGulUIParam,LPSTRlpszMessageID,FLAGSflFlags,ULONGulReserved,lpMapiMessageFAR*lppMessage);----为了决定每一个函数的地址,必须为每一个函数调用GetProcAddress。GetProcAddress的语法为:GetProcAddress(hModule,lpProcName);其中,hModule为HMODULE结构,是所调用DLL模块的句柄;lpProcName为LPCSTR结构,是函数名称。程序示例://找到MAPI32.DLL函数的地址,并将它们保存在函数指针变量里(FARPROC&)lpfnMAPISendMail=GetProcAddress(hInstMail,“MAPISendMail”);(FARPROC&)lpfnMAPIResolveName=GetProcAddress(hInstMail,“MAPIResolveName”);(FARPROC&)lpfnMAPILogon=GetProcAddress(hInstMail,“MAPILogon”);(FARPROC&)lpfnMAPILogoff=GetProcAddress(hInstMail,“MAPILogoff”);(FARPROC&)lpfnMAPIFreeBuffer=GetProcAddress(hInstMail,“MAPIFreeBuffer”);(FARPROC&)lpfnMAPIAddress=GetProcAddress(hInstMail,“MAPIAddress”);(FARPROC&)lpfnMAPIFindNext=GetProcAddress(hInstMail,“MAPIFindNext”);(FARPROC&)lpfnMAPIReadMail=GetProcAddress(hInstMail,“MAPIReadMail”);3-1-3登录到电子邮件对象----用户必须在电子邮件系统中登录,才能实现MAPI的各种功能。MAPI提供了登录的三种选择:登录到一个已经存在的对象。登录到一个新对象,用编程的方法确定解释新信息。使用对话框提示用户登录。----我们通常选择登录到一个已经存在的电子邮件对象,因为网络合作用户通常会保持自己的电子邮件程序处于激活状态。登录通常使用MAPI提供的函数lpfnMAPILogon。lpfnMAPILogon的语法为:lpfnMAPILogon(lpszProfileName,lpszPassword,flFlags,ulReserved,lplhSession);----其中,lpszProfileName指向一个256字符以内的登录名称,lpszPassword指向密码,它们均为LPTSTR结构。flFlags为FLAGS结构,其值详见表1。ulReserved必须为0。lplhSession为输出SMAPI的句柄。表1:lpfnMAPILogon函数中flFlags的值值意义MAPI_FORCE_DOWNLOAD在函数调用返回之前下载用户的所有邮件。如果MAPI_FORCE_DOWNLOAD没有被设置,那么信件能够在函数调用返回后在后台被下载。MAPI_NEW_SESSION建立一个新会话,而不是获得环境的共享会话。如果MAPI_NEW_SESSION没有被设置,MAPILogon使用现有的共享会话。MAPI_LOGON_UI显示一个登录对话框来提示用户输入登录信息。例如Outlook检查用户电子邮件时便是如此。MAPI_PASSWORD_UIMAPILogon只允许用户输入电子邮件的密码,而不许改动账号。程序示例:LHANDLElhSession;ULONGlResult=lpfnMAPILogon(0,NULL,NULL,0,0,&lhSession);if(lResult!=SUCCESS_SUCCESS)//SUCCESS_SUCCESS在MAPI.H中被定义{//错误处理}3-2阅读电子邮件----MAPIFindNext和MAPIReadMail使用与阅读E-mail的两个基本函数。MAPIFindNext用于定位第一封或下一封电子邮件并返回标识号,MAPIReadMail返回以该标识号为基础的电子邮件的内容。另外,一个常用的函数是MAPIFreeBuffer,用于释放内存。3-2-1定位到第一封信----要找到第一封信,需要使用MAPIFindNext函数,其函数声明如下:ULONGFARPASCALMAPIFindNext(LHANDLElhSession,ULONGulUIParam,LPTSTRlpszMessageType,LPTSTRlpszSeedMessageID,FLAGSflFlags,ULONGulReserved,LPTSTRlpszMessageID)----其中,lhSession为提交SMAPI的会话句柄;ulUIParam为父窗体的句柄;lpszMessageType指向一个字符串,用来鉴别邮件类型,并加以查找;lpszSeedMessageID为指向起始信息ID的指针,其值为0时,MAPIFindNext获得第一封电子邮件;flFlags的值见表2;ulReserved必须为0;lpszMessageID为输出值,它是指向信息ID地址的指针。----表2:MAPIFindNext函数中flFlags的值值意义MAPI_GUARANTEE_FIFO按邮件发送的时间顺序接受电子邮件。MAPI_LONG_MSGID返回信件标识符可达512字符。MAPI_UNREAD_ONLY只列举没有阅读过的电子邮件。程序示例://找到第一条没有阅读的电子邮件charpMessageID[513];ULONGlResult=lpfnMAPIFindNext(lhSession,NULL,NULL,NULL,MAPI_LONG_MSGID|MAPI_UNREAD_ONLY,0,pMessageID);3-2-2阅读信息当信件ID被获取后,就可以调用MAPIReadMail阅读实际的E-mail信息了。MAPIReadMail的函数声明如下:ULONGFARPASCALMAPIReadMail(LHANDLElhSession,ULONGulUIParam,LPTSTRlpszMessageID,FLAGSflFlags,ULONGulReserved,lpMapiMessageFAR*lppMessage);其中,lppMessage为指向MapiMessage的指针;除flFlags外的其他参数与lpfnFindNext函数的同名参数意义相同,flFlags参数的值见表3:表3:MAPIReadMail函数中flFlags的值:值意义MAPI_BODY_AS_FILE将邮件信息写到一个临时文件中,并且将它作为第一个附件添加到附件列表中。MAPI_ENVELOPE_ONLY只读取邮件标题。MAPI_PEEK读完邮件之后不把它标记为“已读”。MAPI_SUPPRESS_ATTACHMAPIReadMail函数不拷贝附件,但是将邮件文本写入MapiMessage结构中。程序示例://读取电子邮件longnFlags=MAPI_SUPPRESS_ATTACH;if(!bMarkAsRead)nFlags=nFlags|MAPI_PEEK;lResult=lpfnMAPIReadMail(lhSes