VC++大作业.docx
《VC++大作业.docx》由会员分享,可在线阅读,更多相关《VC++大作业.docx(7页珍藏版)》请在冰豆网上搜索。
VC++大作业
VC++大作业报告
题目:
VC++大作业
院系:
信息与电气工程学院
班级:
08级电子信息工程
学号:
12884030
学生姓名:
×××
成绩:
2011年8月
一、概述
目的是使用VisualC++用MAPI编写E-mail程序。
MAPI是包含在Windows之中的,因此不需要安装其他额外的部件。
MAPI有以下三种形式:
SMAPI,SimpleMAPI,简单的MAPICMC,CommonMessagingCalls,一般通讯调用完整的MAPI
SMAPI和CMC都包含在完整的MAPI中,当用户想执行一些高级操作,比如编写自己的E-mail服务器的时候,
必须使用完整的MAPI。
本文主要阐述如何编写能够收发电子邮件的程序,因此使用SMAPI就足够了。
二、编写电子邮件程序
1初始化MAPI
要使用MAPI,必须首先对它进行初始化。
初始化包括以下三个步骤:
装载MAPI32.DLL动态链接库
找到想要调用的MAPI函数地址
登录到电子邮件对象
1-1装载MAPI32.DLL
----要装载MAPI,用户必须程序运行时动态的装载一个动态链接库。
LoadLibrary函数提供了此功能,
它定位一个动态链接库,并返回HINSTANCE局柄(需要保存该句柄)。
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结构,是函数名称。
1-3登录到电子邮件对象
用户必须在电子邮件系统中登录,才能实现MAPI的各种功能。
MAPI提供了登录的三种选择:
登录到一个已经存在的对象。
登录到一个新对象,用编程的方法确定解释新信息。
使用对话框提示用户登录。
我们通常选择登录到一个已经存在的电子邮件对象,因为网络合作用户通常会保持自己的
电子邮件程序处于激活状态。
登录通常使用MAPI提供的函数lpfnMAPILogon。
其中,lpszProfileName指向一个256字符以内的登录名称,lpszPassword指向密码,它们均
为LPTSTR结构。
flFlags为FLAGS结构,其值详见表1。
ulReserved必须为0。
lplhSession为输出SMAPI的句柄。
MAPI_FORCE_DOWNLOAD
在函数调用返回之前下载用户的所有邮件。
如果MAPI_FORCE_DOWNLOAD没有被设置,那么信件能够在函数调用返回后在后台被下载。
MAPI_NEW_SESSION建立一个新会话,而不是获得环境的共享会话。
如果MAPI_NEW_SESSION没有被设置,MAPILogon使用现有的共享会话。
MAPI_LOGON_UI显示一个登录对话框来提示用户输入登录信息。
MAPI_PASSWORD_UIMAPILogon只允许用户输入电子邮件的密码,而不许改动账号。
2阅读电子邮件
MAPIFindNext和MAPIReadMail使用与阅读E-mail的两个基本函数。
MAPIFindNext用于定位第一封或下一封电子邮件并返回标识号,MAPIReadMail返回以该标识号为基础的电子邮件的内容。
另外,一个常用的函数是MAPIFreeBuffer,用于释放内存。
2-1定位到第一封信
要找到第一封信,需要使用MAPIFindNext函数,
指向一个字符串,用来鉴别邮件类型,并加以查找;lpszSeedMessageID为指向起始信息ID的指针,
其值为0时,MAPIFindNext获得第一封电子邮件;lpszMessageID为输出值,它是指向信息ID地址的指针。
MAPI_GUARANTEE_FIFO按邮件发送的时间顺序接受电子邮件。
2-2阅读信息
当信件ID被获取后,就可以调用MAPIReadMail
阅读实际的E-mail信息了。
除flFlags外的其他参数与lpfnFindNext函数的同名参数意义相同,
MAPI_BODY_AS_FILE将邮件信息写到一个临时文件中,
并且将它作为第一个附件添加到附件列表中。
MAPI_ENVELOPE_ONLY只读取邮件标题。
MAPI_PEEK读完邮件之后不把它标记为“已读”。
MAPI_SUPPRESS_ATTACHMAPIReadMail函数不拷贝附件,
但是将邮件文本写入MapiMessage结构中。
每一个结构包含一个文件附件。
2-3释放内存
在访问另一条信件以前应当释放内存,否则会出现内存泄漏。
2-4定位到下一条信件
定位到下一条信件依然使用MAPIFindNext函数,
3发送电子邮件
发送电子邮件的一般步骤:
1.建立MapiMessage结构对象
2.调用MAPIResolveName使发送者名称合法
3.添加附件
4.调用MAPISendMail发送电子邮件
5.调用MAPIFreeBuffer释放内存
下面详细分别详细阐述。
3-1建立MapiMessage结构对象
对于MapiMessage结构,3-2-2节已经做过介绍,下面一步步介绍如何设置其中的值:
1.为MapiMessage对象分配内存:
2.将ulReserved设置为0:
3.设置信息类型指针lpszMessageType,可以为NULL:
4.设置信件标题(lpszSubject):
5.设置信件内容:
6.设置flFlags标识
7.用一个指向MapiRecipDesc结构的指针设置发送者信息(lpOriginator),或将其设置为NULL:
8.设置接收者数目(nRecipCount),
9.设置接收者信息(lpRecips),
10.设置附件数量(nFileCount)
11.设置附件信息
3-2正确设置接收者信息
设置接收者信息时,应当使用MAPIResolveName函数来为MapiRecipDesc结构对象分配内存,
并返回一个指针,该指针将被保存在MapiMessage结构的lpRecips中。
其中lppRecip即为前面提到的返回的指针。
除flFlags外其余参数与前几个函数意义相同。
MAPI_AB_NOMODIFY对话框为只读。
如果MAPI_DIALOG被设置,那么该项将被忽略。
3-3添加附件
----下面的程序示例将演示如何在电子邮件中包含附件。
程序示例:
//设置附件信息
CStringsPath,sFileName;
MapiFileDescFileInfo;
charpath[512];
charfilename[512];
if(sAttachment==“”)
message.nFileCount=0;
else
{
intnPos=sAttachment.ReverseFind(‘\\');
if(nPos==-1)
{
sPath=sAttachment;
}
else
{
sPath=sAttachment;
sFilename=sAttachment.Mid(nPos+1);
}
strcpy(path,sPath);
strcpy(filename,sFilename);
message.nFileCount=1;
FileInfo.ulReserved=0;
FileInfo.flFlags=0;
FileInfo.nPosition=sMessage.GetLength()–1;
FileInfo.lpszPathName=path;
FileInfo.lpszFileName=filename;
FileInfo.lpFileType=NULL;
message.lpFiles=&m_FileInfo;
}
3-4发送电子邮件
----使用MAPISendMail发送电子邮件,
----其中,flFlags的允许值为MAPI_DIALOG、MAPI_LOGON_UI和MAPI_NEW_SESSION,
其意义与前几个函数中同名标识意义相同。
3-5释放内存
四、小结
本文比较具体的介绍并演示了编写一个电子邮件程序的核心部分,C++语言相对于C语言来说引入了两个大的新东西,一个就是面向对象(具体来将就是类),另外就是模板技术(模板编程或者叫泛型编程是进来非常流行的技术,在C#中虽然还没有对泛型编程的支持,但是相信在将来也一定会加入这一功能),模板是C++中比较复杂的部分,但是作为一个真正的C++程序员,这部分很重要。
尤其是对C++标准程序库的掌握尤为重要。
刚开始的时候千万不要直扑VC中的各种向导和设计器。
因为依赖开发环境生成的很多代码会把我们搞糊涂,也不利于我们学习C++语言本身。
我的建议就是生成一个空的控制台工程,然后自己向里面添加文件。
C++是一门广泛用于工业软件研发的大型语言。
具有很高的复杂和解决问题的能力。
C++不仅在开发上极具价值,同时在学术界也就有很高的价值。
有关C++的文章应该可以用浩如烟海来形容了吧。
C++的世界级经典书籍也是数不胜数。
然而,目前开发语言是如此地繁荣,就连微软也在推出了新的开发语言C#。
一个不可否认的现实是,在低阶程序设计领域,C++挤压着C同时也在承受着C的强烈反弹,前段时间看了据说是微软操作系统源代码的东东,其中很多还是C语言。
而在高阶程序设计领域,Java和C#正在不断蚕食着C++的地盘。
也许Java和C#的狂潮终将迫使C++回归本位—回到它有着根本性优势的开发领域:
低级系统程序设计、高级大规模高性能应用设计、嵌入式程序设计、通用程序设计以及数值科学计算等。
果真如此,我认为这未尝不是一件好事。
电力系统软件所要求的高性能和大规模数值计算正是C++所擅长的。
就我所接触的南瑞和鲁能,很多涉及到电力系统计算的软件如PAS等,都是用C++来开发的。
在电力系统软件开发这块阵地,C++大有用之
地。
C++吸引如此之多的智力投入,以至于这个领域的优秀作品,包括重量级的软件产品、程序库以及书籍等,数不胜数。