收发电子邮件实例程序参考

上传人:抢*** 文档编号:132988448 上传时间:2022-08-09 格式:DOC 页数:46 大小:353.50KB
返回 下载 相关 举报
收发电子邮件实例程序参考_第1页
第1页 / 共46页
收发电子邮件实例程序参考_第2页
第2页 / 共46页
收发电子邮件实例程序参考_第3页
第3页 / 共46页
点击查看更多>>
资源描述
7.6 接收电子邮件的程序实例7.6.1 实例程序的目的和实现的技术要点通过这个实例,读者可以进一步了解POP3的有关原理和内容。程序的用户界面如图7.6所示:图7.6 pop3电子邮件接收程序的用户界面这个实例不太复杂,用户可以利用某个网站的pop3电子邮件接收服务器来接收你在该网站的电子邮箱里的信件。首先填入pop3服务器地址、邮箱用户名和口令,并决定是否要删除邮箱里的邮件;然后点击“连接”按钮,程序会与服务器建立TCP连接,然后发送用户名和口令,经过验证,进入POP3会话。通过命令交互,将邮箱中的所有邮件取回。在此过程中,左下方的多文本列表框(RichTextBox)会显示全部的会话信息。信件全部下载完毕后,左上方的组合列表框中就有了所有信件的标题字段。用户可以从中选择一封信件,查看或者存储。然后可以断开连接。实例只介绍了接收邮件,提取信头标题字段的有关内容,能正确显示符合Rfc822规范的邮件。由于目前邮件结构非常复杂,限于篇幅,程序没有对收到的信件作进一步的分析,也没有对编码的信息进行译码,读者看到的是收信的原始信息,有兴趣的读者可以进一步扩展程序的功能,例如,对信件进行MIME格式分析,将附件提取出来。程序实现的技术要点是:1运用Windows的消息驱动机制除了由MFC创建的应用程序类和对话框类以外,程序从CAsyncSocket类派生了自己的套接字类,并为它添加了OnConnect()、OnClose()和OnReceive()三个事件处理函数。程序的会话过程几乎完全是由FD_READ消息驱动的。建立连接后,服务器会返回信息,接到命令后,服务器也会返回信息。当信息到达客户端套接字的接收缓冲区时,会触发FD_READ消息,并自动执行OnReceive()函数。该函数接收服务器发来的信息,进行分析处理,然后再发送相应的命令。这命令又会引来服务器的响应,又会触发客户端的FD_READ消息。如此周而复始,完成POP会话的全过程。2通过状态转换来控制会话命令的发布顺序程序定义了一个枚举类型STATE,并为套接字类定义了一个STATE类型的变量state,用来表示POP会话的实际状态。容易看出,枚举的成员符号是客户端向POP3服务器发送的命令。typedef enum FIRST=0,USER,PASS,STAT,LIST,RETR,ENDRETR,DELE,GOON STATE;STATE state;当用户点击“连接”按钮与服务器建立TCP连接时,将state置为初值FIRST;然后,每当收到服务器的信息,一方面根据会话的当前状态作响应的分析处理,决定应当继续发送哪条命令,另一方面发出下一个命令以后,改变state的值,将它置为该命令的状态对应的值,这就实现了会话过程中的状态转换,并保证会话按照既定的顺序进行。读者可仔细分析mySock:AnalyzeMsg()函数。3用结构向量来缓存信件信息首先程序定义了一个结构类型,用来缓存一封信件信息。typedef struct CString text; /存储信件的文本int msgSize; /信件的大小int retrSize; /信件实际下载的大小,在下载过程中动态变化 MESSAGEPROP;然后为套接字类定义了一个向量型的成员变量,相当于一个数组,其成员是上述的结构。vector msgs; 在pop会话中,一次性地将信箱中所有信件的信息转入这个向量,然后可以查阅,存储到文件中,或者进行其他处理。7.6.2 创建应用程序的过程1使用MFC AppWizard创建应用程序框架工程名是pop3,应用程序的类型是基于对话框的,对话框的标题是“接收电子邮件客户端程序”,需要Windows Sockets的支持,其它部分接受系统的默认设置就可以。向导自动为应用程序创建了两个类:应用程序类:CPop3App,基类是CWinApp,对应的文件是pop3.h和pop3.cpp。对话框类:CPop3Dlg,基类是CDialog,对应的文件是pop3Dlg.h和pop3Dlg.cpp。2为对话框添加控件在程序的主对话框界面中按照图7.6添加相应的可视控件对象,并按照表7.6修改控件的属性。表7.6 对话框中的控件属性控件类型控件IDCaption静态文本 static textIDC_STATICpop3服务器地址静态文本 static textIDC_STATIC用户名静态文本 static textIDC_STATIC口令编辑框 edit boxIDC_EDIT_SERVER编辑框 edit boxIDC_EDIT_USER编辑框 edit boxIDC_EDIT_PASS复选框 Check BoxIDC_CHECK_DEL删除邮箱中的邮件多文本框 RichEdit BoxIDC_RICH_INFO组合选择框ComboBoxIDC_COMB_LIST(Drop List型)命令按钮 buttonIDC_BTN_CONN连接命令按钮 buttonIDC_BTN_DISC断开命令按钮 buttonIDCANCAL取消命令按钮 buttonIDC_BTN_VIEW查看邮件命令按钮 buttonIDC_BTN_SAVE存 储3定义控件的成员变量按照表7.7,用类向导(Class Wizard)为对话框中的控件对象定义相应的成员变量。表7.7 控件对象的成员变量控件IDControl IDs变量名称Member Variable Name变量类别Category变量类型Variable TypeIDC_EDIT_SERVERm_strServerValueCStringIDC_EDIT_USERm_strUserValueCStringIDC_EDIT_PASSm_strPassValueCStringIDC_CHECK_DELm_bolDelValueBOOLIDC_COMB_LISTm_ctrListControlCComboBoxIDC_RICH_INFOm_InfoValueCStringm_ctrlnfoControlCRichEditCtrl4为对话框中的控件对象添加事件响应函数按照表7.8,用类向导(Class Wizard )为对话框中的控件对象添加事件响应函数。表7.8 对话框控件的事件响应函数控件类型对象标识 ObjectID消息 Message函数Member functions命令按钮IDC_BTN_CONNBN_CLICKEDOnBtnConn命令按钮IDC_BTN_DISCBN_CLICKEDOnBtnDisc命令按钮IDC_BTN_VIEWBN_CLICKEDOnBtnView命令按钮IDC_BTN_SAVEBN_CLICKEDOnBtnSave5为Cpop3Dlg类添加其它的成员void Disp(LONG flag); /在不同的会话阶段显示不同的信息mySock pop3Socket; /套接字类对象实例6创建从CAsyncSocket类继承的派生类为了能够捕获并响应socket事件,应创建用户自己的套接字类,可利用类向导添加。Class Type选择MFC Class,类名为mySock,基类是CAsyncSocket类,创建后对应的文件是mysock.h和mysock.cpp。在利用类向导为mysock类添加OnConnect,OnClose和OnReceive三个事件处理函数,并为它添加一般的成员函数和变量。可参看下一小节的程序代码。7手工添加包含语句以及事件函数和成员函数的代码8分阶段编译执行,进行测试7.6.3 程序清单1CPop3App应用程序类对应的文件pop3.h不动,在pop3.cpp的InitInstance()函数中添加一句初始化多文本框控件的函数。BOOL CPop3App:InitInstance()if (!AfxSocketInit()AfxMessageBox(IDP_SOCKETS_INIT_FAILED);return FALSE;AfxEnableControlContainer(); /MFC自动创建的代码AfxInitRichEdit(); /用户添加的.2CPop3Dlg对话框类对应的文件(1)pop3Dlg.h包含文件.#include mySock.h /添加套接字类的包含文件.class CPop3Dlg : public CDialog/ Constructionpublic:void Disp(LONG flag); /在不同的会话阶段显示不同的信息mySock pop3Socket; /套接字类对象实例CPop3Dlg(CWnd* pParent = NULL); / standard constructor.(2)pop3Dlg.cpp实现文件#include stdafx.h#include pop3.h#include pop3Dlg.h#include mySock.h /手工添加的包含语句.BOOL CPop3Dlg:OnInitDialog()./ TODO: Add extra initialization here/用户在这里添加控件成员变量的初始化代码m_strServer = _T(); /POP3服务器地址m_strUser = _T(example); /邮箱的用户名m_strPass = _T(123456); /口令m_bolDel = FALSE; /下载邮件后不删除m_Info = _T(); /多文本框清空return TRUE; / return TRUE unless you set the focus to a control./以下是事件处理函数和其他成员函数的代码/当用户点击连接按钮时,执行此函数void CPop3Dlg:OnBtnConn() /设定pop3类的对话框指针变量,使之指向本对话框,以便传递信息pop3Socket.SetParent(this); UpdateData(TRUE); /取来用户在对话框中输入的数据pop3Socket.Create(); /创建套接字对象的底层套接字pop3Socket.Connect(LPCSTR)m_strServer,110); /连接pop3服务器m_Info = ; /多文本列表框清空UpdateData(FALSE); /更新用户界面/当用户点击断开按钮时,执行此函数void CPop3Dlg:OnBtnDisc() pop3Socket.Close();/当用户点击查看邮件按钮时,执行此函数void CPop3Dlg:OnBtnView() int i;i = m_ctrList.GetCurSel(); /获得用户在组合框中的选择/获得并显示指定信件的基本属性及信件内容m_Info += pop3Socket.GetMsgStuff(i);m_Info += pop3Socket.GetMsgBody(i);/在不同的情况下,向用户显示不同的信息void CPop3Dlg:Disp(LONG flag)CString s;switch(flag)case S_CONNECT: /已连接到服务器,显示信息s = 已连接到+m_strServer+.rn;m_Info+=s;/禁用连接按钮GetDlgItem(IDC_BTN_CONN)-EnableWindow(FALSE);/启用断开按钮GetDlgItem(IDC_BTN_DISC)-EnableWindow(TRUE);/禁用查看邮件按钮GetDlgItem(IDC_BTN_VIEW)-EnableWindow(FALSE);break;case S_RECEIVE:/收到服务器发来的响应,显示它的内容m_Info+=pop3Socket.lastMsg;break; case S_CLOSE: /显示关闭连接的信息m_Info+=pop3Socket.error;s = 连接已经关闭rn;m_Info+=s; /启用连接按钮GetDlgItem(IDC_BTN_CONN)-EnableWindow(TRUE);/禁用断开按钮GetDlgItem(IDC_BTN_DISC)-EnableWindow(FALSE); break;case S_GETNUM: /已经知道了邮箱中信件的总数s.Format(邮箱中共有 %d 封信rn,pop3Socket.numMsg);m_Info+=s;break;case S_GETSIZE: /显示信件的大小s.Format(信箱中信件大小为:%d字节rn,pop3Socket.sizeMsg);m_Info+=s; break;case S_ENDRETR: /所有信件已下载完毕,显示信息s.Format(共下载了 %d 封信件rn,pop3Socket.msgs.size();m_Info+=s;/如果有信件下载,启用查看邮件按钮if(pop3Socket.msgs.size()0)GetDlgItem(IDC_BTN_VIEW)-EnableWindow(TRUE);break;UpdateData(FALSE); /更新用户界面/当点击“存储”按钮时,执行此函数。void CPop3Dlg:OnBtnSave() int i;CString s;i = m_ctrList.GetCurSel();/获得指定信件的基本属性及信件内容s = pop3Socket.GetMsgStuff(i);s += pop3Socket.GetMsgBody(i);CFileDialog dlg(FALSE);if(dlg.DoModal()=IDOK)CFile file(dlg.GetPathName(),CFile:modeCreate | CFile:modeWrite | CFile:typeBinary);file.Write(LPCSTR)s,s.GetLength();file.Close();3mySock套接字类对应的文件(1)mysock.h包含文件.#include #include #include using namespace std;class CPop3Dlg;/显示不同信息的标志#define S_CLOSE 1 /当关闭连接时,显示关闭信息#define S_CONNECT 2 /当连接成功时,显示连接信息#define S_RECEIVE 3 /当收到服务器发来的信息时,显示该信息#define S_GETNUM 4 /当所有信件下载完毕后,显示信箱中的信件总数#define S_GETSIZE 5 /当所有信件下载完毕后,显示信箱中的信件总大小#define S_ENDRETR 6 /当所有信件下载完毕后,显示相关信息/描述pop3会话状态的枚举类型typedef enum FIRST=0,USER,PASS,STAT,LIST,RETR,ENDRETR,DELE,GOON STATE;/用来缓存一封信件信息的结构typedef struct CString text; /存储信件的文本int msgSize; /信件的大小int retrSize; /信件实际下载的大小,在下载过程中动态变化 MESSAGEPROP;/自己的套接字类class mySock : public CAsyncSocket/ Attributespublic:CString lastMsg;CString error;int numMsg, sizeMsg, retrMsg;vector msgs; /盛放信件信息的向量/ Operationspublic:/获得基本的邮件信头字段: From, To, Date, Subject, BodyCString GetMsgStuff(int i); CString GetMsgBody(int i); /获得信件体CString GetMsgSubject(int i); /获得信件标题CString GetMsg(int i); /获得整封信的内容void Close(); /退出服务器void SetParent(CPop3Dlg * pDlg);mySock();virtual mySock();/ Overridespublic:/ ClassWizard generated virtual function overrides/AFX_VIRTUAL(mySock)public:virtual void OnConnect(int nErrorCode);virtual void OnClose(int nErrorCode);virtual void OnReceive(int nErrorCode);/AFX_VIRTUAL/ Generated message map functions/AFX_MSG(mySock)/ NOTE - the ClassWizard will add and remove member functions here./AFX_MSG/ Implementationprotected:private:void ReadLn(int index,CString src, CString &dst);void AnalyzeMsg();CPop3Dlg* m_pDlg;STATE state;int delMsg;.(2)mysock.cpp实现文件#include stdafx.h#include pop3.h#include mySock.h#include pop3Dlg.h /自己添加的包含语句.#define MAX_BUFF 20000/构造函数,对某些成员变量初始化mySock:mySock()m_pDlg = NULL;state=FIRST;error=Not connected to serverrn;mySock:mySock()m_pDlg = NULL;./如果连接成功,执行此函数。/接到此消息仅仅显示了一句话,开关了一些按钮连接成功后,服务器发来响应,因此/又立即收到了OnReceive消息,后来的会话过程中,一来一往,程序总是收到/OnReceive消息,所以真正的事情在那里作。void mySock:OnConnect(int nErrorCode) if(nErrorCode=0) m_pDlg-Disp(S_CONNECT);/服务器端关闭连接,才会收到此消息。void mySock:OnClose(int nErrorCode) if(nErrorCode=0) m_pDlg-Disp(S_CLOSE);/套接字收到服务器发来的数据时,执行此函数void mySock:OnReceive(int nErrorCode) if(nErrorCode=0)char buffMAX_BUFF; /接收缓冲区int rec=Receive(buff,MAX_BUFF); /接收服务器发来的数据buffrec=NULL; /结尾置为NULL。lastMsg=buff;AnalyzeMsg(); /分析收到的数据,作不同的处理 else error=在接收数据时发送了错误!rn;m_pDlg-Disp(S_CLOSE); /显示信息/设置套接字类的对话框指针变量void mySock:SetParent(CPop3Dlg *pDlg)m_pDlg = pDlg;/获得第 i 封信件的标题信息CString mySock:GetMsgStuff(int i)CString ret;int where=msgsi.text.Find(From:);ReadLn(where,msgsi.text,ret);ret+=rn;where=msgsi.text.Find(To:);if (where!=-1)ReadLn(where,msgsi.text,ret);ret+=rn;where=msgsi.text.Find(Date:);if (where!=-1)ReadLn(where,msgsi.text,ret);ret+=rn;ret+=GetMsgSubject(i);ret+=rn;return ret;/获得第 i 封信件的信件体CString mySock:GetMsgBody(int i)CString ret;int where=msgsi.text.Find(rnrn);if(where!=-1) where+=4;else where=0;ret=msgsi.text.Right(msgsi.text.GetLength()-where);ret=ret.Left(ret.GetLength()-3);return ret;/获得第 i 封信件的标题CString mySock:GetMsgSubject(int i)int where=msgsi.text.Find(Subject:);CString ret;if (where!=-1) ReadLn(where,msgsi.text,ret);return ret;/获得第 i 封信整封信的内容CString mySock:GetMsg(int i)return msgsi.text;/从src串中,从index所指的位置开始,取子字串,直到行末符r为止。/dst是一个串的地址,取出的行追加在该串的原内容之后void mySock:ReadLn(int index,CString src, CString &dst)CString comp;comp=srcindex;while(comp!=r)dst+=comp;comp=src+index;/退出服务器void mySock:Close()CString str;str.Format(quit%c%c,13,10);Send(LPCSTR)str,str.GetLength();m_pDlg-Disp(S_CLOSE);state=FIRST;CAsyncSocket:Close();error=Not connected to serverrn;void mySock:AnalyzeMsg()CString s;strstream str;string check;strcheck; /提取所收到信息的第一段代码if(check=-ERR) /如果有错误error=Received -ERR from server :+lastMsg;Close(); /断开连接,然后关闭return;/如果没有错误,则根据不同的会话阶段响应来处理switch(state) case FIRST: /如果已经连接成功,类初始化的时候state为FIRSTmsgs.clear();/显示连接成功后服务器返回的消息m_pDlg-Disp(S_RECEIVE); /发送 user 用户名 命令s.Format(user %s%c%c,m_pDlg-m_strUser,13,10);Send(LPCSTR)s,s.GetLength(); /发送用户帐号state=USER;break;case USER:/显示服务器对于user命令的响应m_pDlg-Disp(S_RECEIVE);/发送 pass 口令命令,发送密码s.Format(pass %s%c%c,m_pDlg-m_strPass,13,10); Send(LPCSTR)s,s.GetLength(); state=PASS;break;case PASS:/显示服务器对 pass 命令的响应m_pDlg-Disp(S_RECEIVE);/发送 stat 命令,请求服务器返回信箱中/邮件的数量和所占空间的大小s.Format(stat%c%c,13,10);Send(LPCSTR)s,s.GetLength();state=STAT; break;case STAT:string s1;str.seekg(0); /将字符流的当前指针置为0strs1numMsgsizeMsg; /获得数量和大小flush(str);m_pDlg-Disp(S_GETNUM);m_pDlg-Disp(S_GETSIZE);if(numMsg0) /如果有邮件,则发送RETR获得邮件信息retrMsg=1; /要取第一封信MESSAGEPROP prop; /准备存放信件的地方prop.msgSize=0; /成员置初值prop.retrSize=0;prop.text=;msgs.push_back(prop); /压入向量表s.Format(retr 1%c%c,13,10);Send(LPCSTR)s,s.GetLength(); state=RETR;else /如果没有邮件,则断开error=No new messagesrn;Close();break;case RETR:/显示取回来的信件文本m_pDlg-Disp(S_RECEIVE);/一封信的内容可能多次才能接受回来,但是对于一封信,第一次/接收到数据的时候,对应向量结构的msgSize成员变量为0if(msgsretrMsg-1.msgSize=0) string temp;str.seekg(0);/将该信件的大小存放到成员变量中strtempmsgsretrMsg-1.msgSize; /将数据追加保存到text成员变量中msgsretrMsg-1.text+=lastMsg; /将数据大小累加到retrSize成员变量中,代表已经取回来的数量msgsretrMsg-1.retrSize+=lastMsg.GetLength();/判断是否获得所有数据if(msgsretrMsg-1.retrSize=msgsretrMsg-1.msgSize) /检查是否有其他邮件if(retrMsgm_bolDel & numMsg0) state=DELE;delMsg=1;s.Format(dele %d%c%c,delMsg,13,10);Send(LPCSTR)s,s.GetLength(); else /否则退出state=ENDRETR;m_pDlg-Disp(S_ENDRETR);error=Session endedrn;s.Format(quit%c%c,13,10);Send(LPCSTR)s,s.GetLength();Close();for(int i=0;im_ctrList.AddString(LPCSTR)GetMsgSubject(i);m_pDlg-m_ctrList.SetCurSel(0);break;case DELE:/删除剩余邮件if(delMsgDisp(S_ENDRETR);state=GOON;error=Deleted all messagesrn;s.Format(quit%c%c,13,10);Send(LPCSTR)s,s.GetLength();Close();break;case GOON:default:m_pDlg-Disp(S_RECEIVE);break;7.7 发送电子邮件的程序实例7.7.1 实例程序的目的和实现的技术要点通过这个实例,读者可以进一步了解SMTP的有关原理和内容。程序的用户界面如图7.7所示:图7.7 smtp电子邮件发送程序的用户界面这个实例实现了smtp电子邮件发送程序的一些功能,用户可以利用某个网站的smtp电子邮件发送服务器来发送电子邮件。你必须是该网站的注册用户,并在该网站申请了免费邮箱。首先填入smtp服务器地址、邮箱用户名和口令,端口号是25,并填入发信人,发信地址填入你在该网站的免费邮箱地址。在对话框的右面填入发送电子邮件的相关信息,选择一个附件,然后点击“发送”按钮,程序会与服务器建立TCP连接,然后按照ESMTP协议发送ELHO命令,然后发送用户名和口令,经过验证,进入SMTP会话。通过命令交互,将邮件和附件发送出去,然后断开连接。在此过程中,右下方的多文本列表框(RichTextBox)会显示全部的会话信息。现在的SMTP服务器与以前不一样,一般都要经过验证身份后,才为你提供传输邮件的服务,验证的方法有很多种,这里只实现了一种,仅仅为了说明问题。程序实现的技术要点是:1运用Windows的消息驱动机制与7.6节的实例基本相同。2通过状态转换来控制会话命令的发布顺序与7.6节的实例基本相同。3实现了base64编码和译码。7.7.2 创建应用程序的过程1使用MFC AppWizard创建应用程序框架工程名是smtp,应用程序的类型是基于对话框的,对话框的标题是“电子邮件发送客户端程序”,需要Windows Sockets的支持,其它部分接受系统的默认设置就可以。向导自动为应用程序创建了两个类:应用程序类:CSmtpApp,基类是CWinApp,对应的文件是smtp.h和smtp.cpp。对话框类:CSmtpDlg,基类是CDialog,对应的文件是smtpDlg.h和smtpDlg.cpp。2为对话框添加控件在程序的主对话框界面中按照图7.7添加相应的可视控件对象,并按照表7.9修改控件的属性。表7.9 对话框中的控件属性控件类型控件IDCaption静态文本 static textIDC_STATIC发信人静态文本 static textIDC_STATIC发信地址静态文本 static textIDC_STATICSMTP服务器静态文本 static textIDC_STATIC端口静态文本 static textIDC_STATIC用户名静态文本 static textIDC_STATIC口令编辑框 edit boxIDC_EDIT_NAME编辑框 edit boxIDC_EDIT_ADDR编辑框 edit boxIDC_EDIT_SERVER编辑框 edit boxIDC_EDIT_PORT编辑框 edit boxIDC_EDIT_USER编辑框 edit boxIDC_EDIT_PASS静态文本 static textIDC_STATIC收信静态文本 static textIDC_STATIC主题静态文本 static textIDC_STATIC抄送静态文本 static textIDC_STATIC暗送静态文本 static textIDC_STATIC附件静态文本 static textIDC_STATIC信件内容编辑框 edit boxIDC_EDIT_RECEIVER编辑框 edit boxIDC_EDIT_TITLE编辑框 edit boxIDC_EDIT_CC编辑框 edit boxIDC_EDIT_BCC编辑框 edit boxIDC_EDIT_ATTACH编辑框 edit boxIDC_EDIT_LETTER命令按钮 buttonIDC_BTN_VIEW浏览静态文本 static textIDC_STATICsmtp 会话的状态信息多文本框 RichEdit BoxIDC_RICH_LIST命令按钮 buttonIDOK发送命令按钮 buttonIDCANCEL取消3定义控件的成员变量按照表7.10,用类向导(Class Wizard)为对话框中的控件对象定义相应的成员变量。表7.10 控件对象的成员变量控件IDControl IDs变量名称Member Variable Name变量类别Category变量类型Variable TypeIDC_EDIT_NAMEm_NameValueCStringIDC_EDIT_ADDRm_AddrValueCStringIDC_EDIT_SERVERm_ServerValueCStringIDC_EDIT_PORTm_PortValueUINTIDC_EDIT_USERm_UserValueCStringIDC_EDIT_PASSm_PassValueCStringIDC_EDIT_RECEIVERm_ReceiverValueCStringIDC_EDIT_TITLEm_TitleValueCStringIDC_EDIT_CCm_CCValueCStringIDC_EDIT_BCCm_BCCValueCStringIDC_EDIT_ATTACHm_AttachValueCStringIDC_EDIT_LETTERm_LetterValueCStringIDC_RICH_INFOm_InfoValueCString4为对话框中的控件对象添加事件响应函数按照表7.11,用类向导(Class Wizard )为对话框中的控件对象添加事件响应函数。表7.11 对话框控件的事件响应函数控件类型对象标识 ObjectID消息 Message函数Member functions命令按钮IDC_BTN_VIEWBN_CLICKEDOnBtnView命令按钮IDOKBN_CLICKEDOnIDOK5创建一个普通的类CBase64,用来实现base64编码和解码。6创建从CAsyncSocket类继承的派生类为了能够捕获并响应socket事件,应创建用户自己的套接字类,可利用类向导添加。Class Type选择MFC Class,类名为mySock,基类是CAsyncSocket类,创建后对应的文件是mysock.h和mysock.cpp。在利用类向导为mysock类添加OnConnect,OnClose和OnReceive三个事件处理函数,并为它添加一般的成员函数和变量。可参看下一小节的程序代码。7手工添加包含语句以及事件函数和成员函数的代码8分阶段编译执行,进行测试7.7.3 程序清单1CSmtpApp应用程序类对应的文件smtp.h不动,在smtp.cpp的InitInstance()函数中添加一句初始化多文本框控件的函数。BOOL CSmtpApp:InitInstance()if (!AfxSocketInit()AfxMessageBox(IDP_SOCKETS_INIT_FAILED);return FALSE;AfxEnableControlContainer(); /MFC自动创建的代码AfxInitRichEdit(); /用户自己添加的.2CSmtpDlg对话框类对应的文件(1)smtpDlg.h包含文件.#include mySock.h /自己添加的包含语句#include Base64.h /自己添加的包含语句.class CSmtpDlg : public CDialog/ Constructionpublic:void Disp(LONG flag); /显示信息void GetHeader(); /创建电子邮件的头部mySock smtpSocket; /套接字类对象CSmtpDlg(CWnd* pParent = NULL); / standard constructor/类向导自动产生的窗口控件变量的声明/ Dialog Data/AFX_DATA(CSmtpDlg)enum IDD = IDD_SMTP_DIALOG ;CString m_Addr; /发信地址CString m_Attach; /附件CString m_BCC; /暗送CString m_CC; /抄送CString m_Letter; /信件内容CString m_Name; /发信人CString m_Pass; /口令UINT m_Port; /端口CString m_Receiver; /收信CString m_Server; / SMTP服务器CString m_Title; /主题CString m_User; /用户名CString m_Info; /会话状态信息/AFX_DATA./类向导自动生成的消息映射函数声明/AFX_MSG(CSmtpDlg)virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();afx_msg void OnBtnView(); /点击“浏览”按钮时执行virtual void OnOK(); /点击“发送“按钮时执行/AFX_MSGDECLARE_MESSAGE_MAP()private:CBase64 coder; /进行Base64编码的变量BOOL GetBody(LPSTR& pszBody, int& nBodySize);/构造邮件体;.(2)smtpDlg.cpp实现文件#include stdafx.h#include smtp.h#include smtpDlg.h#include mySock.h /自己添加的包含语句#include Base64.h /自己添加的包含语句#define SMTP_MAXLINE 76./ CSmtpDlg dialogCSmtpDlg:CSmtpDlg(CWnd* pParent /*=NULL*/): CDialog(CSmtpDlg:IDD, pParent)/AFX_DATA_INIT(CSmtpDlg)m_Addr = _T(); /这一部分是由类向导自动添加的变量初始化代码m_Attach = _T();m_BCC = _T();m_CC = _T();m_Letter = _T();m_Name = _T();m_Pass = _T();m_Port = 0;m_Receiver = _T();m_Server = _T();m_Title = _T();m_User = _T();m_Info = _T();/AFX_DATA_INIT/ Note that LoadIcon does not require a subsequent DestroyIcon in Win32m_hIcon = AfxGetApp()-LoadIcon(IDR_MAINFRAME);/类向导自动添加的窗口控件与相应控件变量的映射关系void CSmtpDlg:DoDataExchange(CDataExchange* pDX)CDialog:DoDataExchange(pDX);/AFX_DATA_MAP(CSmtpDlg)DDX_Text(pDX, IDC_EDIT_ADDR, m_Addr);DDX_Text(pDX, IDC_EDIT_ATTACH, m_Attach);D
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 小学资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!