POP3 協議: 采用對等的會話方式完成郵件的收取。過程為交互式的請求應答模式。 客戶端首先要和POP3服務器110號端口進行連接。然后使用標準命令進行對話 //-----------------------------------標準命令 USER 標識用戶進行驗證 PASS發送密碼進行驗證 APOP轉換驗證機制 QUIT終止會話 NOOP空操作 STAT提供信箱大小信息 LIST提供郵件大小信息 RETR從服務器取出郵件 TOP取出信頭和郵件的前N行 DELTE標記郵件被刪除 RSET復位POP會話 UIDL取出郵件的唯一標識符 //------------------------------------------------------ 1(USER)該命令用來驗證用戶信箱 Client:USER caucy Server:+OK/-ERR 2(PASS) 該命令用來為USER命令指定的信箱提供密碼 Client:PASS ***** Server:+OK/-ERR 3(QUIT) 該命令終止會話,斷開與服務器的連接 Client:QUIT ***** Server:+OK/-ERR 如果會話在驗證狀態,QUIT引起服務器關閉連接,如果會話在事務狀態,POP服務器進入更新狀態,在關閉連接前刪除標記為刪除的任何郵件。如果用戶不是通過QUIT命令關閉連接的,而是在客戶端強行關閉,則在事務狀態標記刪除的郵件并沒有被刪除如果在更新狀態時郵件碰到錯誤,服務器應答一個錯誤信息。但不管QUIT命令成功與否,信箱鎖都被釋放,連接關閉 4NOOP 命令什么都不做,只是檢測服務器的連接 該命令只能在事務狀態中使用,除了檢測與服務器的連接是否正常,還可以防止自動注銷定時器定時關 閉連接 5(STAT) 該命令請求服務器返回信箱大小的信息,但是不包過標記為刪除的郵件 Client:STAT Server:+OK 2 4065 服務器的應答包含信箱的數量以及所有郵件的大小。stat命令僅在事務狀態時可用的 6列表(LIST) 該命令請求服務器返回一個信箱中特定郵件的大小信息或者沒有刪除標記的所有郵件的大小信息 Client: LIST 1 Server:+OK 1 1046 該命令有兩種使用情形,帶參和不帶參。List后面如果指定郵件,則返回郵件大小信息,如上所示。 List指定的郵件如果被標識為刪除或者不存在,則出錯,如下所示: Client:LIST 5 Server:-ERR no such message ,only message 1 thru 1 are PResent in your inbox 如果List不帶參數,如下所示: Client:LIST Server將返回多行應答。 +OK 1 1045 2 2204 . 應答成功先是相應+OK,接著每一行含有一個郵件號和郵件的大小(字節數),最后是以句點"."作為結束 行。 (7)取出郵件(RETR) 該命令用于取出指定郵件號的郵件 Client:RETR 1 Server: +OK ... 如果請求成功,服務器返回的是對多行應答,先是"+OK"表示相應成功,接著返回郵件的所有內容,包括信頭和信體。如果有附件,附件的內容也以文本的形式返回。最后以一個句點"."表示結束。為了防止單個句點引起客戶機提前結束郵件的讀取,對Retr命令使用與前面介紹SMTP標準DATA相同的點填補 8提取前幾行(TOP) Client:TOP 1 1 Server: +OK ... 9(Top命令格式)(Top 郵件序號 行數) TOP命令取出指定郵件的信頭和指定信體的行數。該命令僅在事務狀態中才是可用的 TOP 1 2 取出的是郵件號為1的信件頭和前2行的內容 與Retr命令一樣,使用Top命令。服務器返回的內容結束標志為句點"." Top命令對于服務器是可選的,有些服務器上并沒有實現。只是在可以實現Top的服務器才可以使用該命 令 10(DELE) Client:DELE 1 Server:+OK message 1 deleted 該命令標志指定的郵件為刪除郵件,用于事務狀態中 需要注意的是只有QUIT命令之后進入更新狀態,標志為刪除的郵件才會被真正地刪除 11(復位RSET) Client:RSET Server:+OK 該命令在事務狀態中復位POP會話,被標記為刪除的郵件取消標記,以后發出的QUIT命令不刪除以前標記為刪除的郵件 12唯一ID列表(UIDL) Client:UIDL Server: +OK ... 該命令用戶請求返回郵件的唯一標志符 UIDL命令可以返回該POP3服務器上的郵件的唯一編號,客戶機可以在不同的POP3會話中辨認郵件 命令格式:UIDL[郵件序號] 可選的 如果帶參數 返回指定郵件的唯一的ID,且應答是但行的;如果不帶參數,則返回多行應答,最后以句點 "."作為結束。 在整個會話過程中,客戶端處于3個狀態中:驗證狀態(authorization status),事務狀態(transaction status)和更新狀態(update status). 每個狀態是會話過程中的特定階段。 當連接服務器后,首選進入驗證狀態,在這個階段里,可以使用的POP3命令是USER,PASS,APOP和QUIT 通過服務器驗證后,服務器鎖定信箱,這樣做可以防止多個POP客戶端進行郵件操作,比如刪除,取信 等,但可以讓新郵件加入。這時會話過程轉變為事務狀態,接受郵件的POP對話大部分時間都是處在事 務狀態中 事務狀態可以使用POP3命令有:Noop,Stat,Quit,List,Retr,Top,Dele,Rset和Uidl。 會話過程的最后一個狀態為更新狀態,在事務狀態結束后,發出Quit命令進入該狀態,但是由于異常原因導致的與服務器終止對話并沒進入更新狀態。步驟: 1連接POP3服務器 2發送用戶信箱名 3發送用戶信箱密碼 4對信箱郵件進行操作 5接受郵件完畢,結束會話
例子:需要建一個POP3類class CPop3 {public: BOOL Reset(void); //獲得郵件主題 LPCTSTR GetMailHeader(UINT nIndex); //發送NOOP命令,進行一次空操作 BOOL Noop(void); //獲得出錯信息 LPCTSTR GetErrorString(void); //發送STAT命令,獲得郵件總體的狀態信息 BOOL GetState(void); //發送List命令,獲得郵件的具體狀態信息 BOOL List(void); //發送RETR命令,接受郵件正文 BOOL RetrieveMail(UINT nIndex,CString &strMsg); //發送DELE命令,將所選郵件標記為刪除 BOOL Delete(UINT nIndex); //發送TOP命令,獲得所有的郵件主題 BOOL ListHeader(void); //私有變量接口函數,返回給定索引的郵件大小 DWord GetMsgSize(UINT nID); //私有變量接口函數,返回郵件數目 UINT GetMailCount(void)const; //發送命令 BOOL Send(LPCTSTR lpszSend,UINT nLength); //斷開連接,發送QUIT命令,并請求真正刪除所要求的郵件 BOOL Disconnect(void); //建立與服務器的連接,其中包括登陸的過程 BOOL Connect(LPCTSTR strAddress,LPCTSTR strUser,LPCTSTR strPassword,UINT nPort=110);
CPop3(); virtual ~CPop3();
protected: //所有郵件的總體大小 UINT m_nSize; //通信的套接字 SOCKET m_sock; //郵件數目,以GetMailCount為接口函數 UINT m_nMails; //記錄是否發送過有效的List命令 BOOL m_bList; //記錄是否發送過有效的STAT命令 BOOL m_bState; //記錄每個郵件大小的MFC數組變量 CDWordArray m_arSizes; //記錄每個郵件主題的MFC數組變量 CStringArray m_arHeaders; //記錄是否已經與服務器建立連接 BOOL m_bConnected; //記錄回應的消息 CString m_sResponse; //確定是否超時,只要用去的時間超過該值就表示超時 DWORD m_dwTimeout;private: //記錄出錯信息,以GetErrorString為接口函數 CString m_sError; //去除開頭的+OK標識,獲得回應的有效信息 //從返回的信息中提取數目和大小信息,主要用于List命令的回應信息 BOOL ParseNumAndSize(UINT &nNum,UINT &nSize,LPCTSTR lpszBuf,UINT &nEnd); //讀取回應信息,與GetResponse函數不同,它進行實際的工作 BOOL ReadResponse(TCHAR* pChar,UINT nSize,BOOL bDouble); BOOL GetResponse(void); //讀取針對LIST命令的返回信息 //由于對LIST命令的返回信息較特殊,所以用單獨的函數 BOOL ReadList(void); //對STAT命令的返回信息,原因同上 BOOL ReadState(void);};
1初始化DlgBOOL CPOP3Dlg::OnInitDialog(){ SetDlgItemText(IDC_ADDRESS,"pop.126.com"); SetDlgItemText(IDC_USERNAME,"mazhiyuan_"); SetDlgItemText(IDC_PASSWORD,"");
CString strText; this->SetDlgItemInt(IDC_PORT,110,FALSE); strText=_T("序號"); m_lstMail.InsertColumn(0,strText,LVCFMT_CENTER,48); strText=_T("郵件主題"); m_lstMail.InsertColumn(1,strText,LVCFMT_CENTER,318); strText=_T("大小"); m_lstMail.InsertColumn(2,strText,LVCFMT_CENTER,48);
(this->GetDlgItem(IDC_REVERSE))->EnableWindow(FALSE); (this->GetDlgItem(IDC_DELETE))->EnableWindow(FALSE); (this->GetDlgItem(IDC_DISCONNECT))->EnableWindow(FALSE); return TRUE; } 2收取郵件:void CPOP3Dlg::OnReceive() { // TODO: Add your control notification handler code here GetDlgItemText(IDC_ADDRESS,m_sAddr); GetDlgItemText(IDC_USERNAME,m_sUser); GetDlgItemText(IDC_PASSWORD,m_sPassword);
if(m_sAddr.IsEmpty()||m_sUser.IsEmpty()||m_sPassword.IsEmpty()) { AfxMessageBox(_T("輸入POP3信息不全")); return ; }
if(!m_pop3.Connect(m_sAddr,m_sUser,m_sPassword))//連接POP3服務器 { // 連接失敗 AfxMessageBox(_T("無法與服務器建立連接!")); return; }
//進行一次空操作 if(!m_pop3.Noop()) { AfxMessageBox(m_pop3.GetErrorString()); return ; }
Refresh();//獲得郵件信息 // 更新界面 GetDlgItem(IDC_REVERSE)->EnableWindow(TRUE); GetDlgItem(IDC_DELETE)->EnableWindow(TRUE); GetDlgItem(IDC_DISCONNECT)->EnableWindow(TRUE);}
//連接POP3服務器并發送用戶名和密碼的功能是在COnnect中完成BOOL CPop3::Connect(LPCTSTR strAddress,LPCTSTR strUser,LPCTSTR strPassword,UINT nPort){ //初始化本地套接字 m_sock=socket(AF_INET,SOCK_STREAM,0); if(m_sock==INVALID_SOCKET) { //AfxMessageBox(_T("初始化套接字失敗")); m_sError=_T("初始化套接字失敗"); return FALSE; }
SOCKADDR_IN sockAddr; memset(&sockAddr,'/0',sizeof(sockAddr)); sockAddr.sin_family=AF_INET; sockAddr.sin_port=htons((u_short)nPort); sockAddr.sin_addr.S_un.S_addr=inet_addr(strAddress);
//如果主機名不是ip地址,用gethostbyname獲得其IP地址 if(sockAddr.sin_addr.S_un.S_addr==INADDR_NONE) { LPHOSTENT lphost; lphost=gethostbyname(strAddress); if(lphost) sockAddr.sin_addr.s_addr=((LPIN_ADDR)lphost->h_addr)->s_addr; else { m_sError=_T("無法解析地址"); return FALSE; } }
//嘗試與服務器連接 if(connect(m_sock,(SOCKADDR*)(&sockAddr),sizeof(sockAddr))==SOCKET_ERROR) { m_sError=_T("無法與服務器建立連接!"); return FALSE; }
//接受回應信息 if(!GetResponse()) { //回應失敗 m_sError=_T("無法收到回應信息或收到錯誤信息"); Disconnect(); return FALSE; }
//發送用戶名 CString strTemp; strTemp.Format("USER %s/r/n",strUser); if(!Send((LPCTSTR)strTemp,strTemp.GetLength())) { m_sError=_T("發送用戶名失敗"); return FALSE; }
//接受回應信息 if(!GetResponse()) { //接受回應信息回應失敗 m_sError=_T("無法收到回應信息或收到錯誤信息"); Disconnect(); return FALSE; }
//發送密碼 strTemp.Format("PASS %s/r/n",strPassword); if(!Send((LPCTSTR)strTemp,strTemp.GetLength())) { //發送密碼失敗 m_sError=_T("發送密碼失敗"); Disconnect(); return FALSE; }
//接受回應信息 if(!GetResponse()) { //接受回應信息回應失敗 m_sError=_T("無法收到回應信息或收到錯誤信息"); Disconnect(); return FALSE; }
m_bConnected=TRUE; return TRUE;}
//得到服務器端的響應碼是在GetResponse函數中完成的,他通過調用ReadResponse函數完成的BOOL CPop3::GetResponse(void){ TCHAR chArray[1188]; if(!ReadResponse(chArray,1188,FALSE)) { return FALSE; }
m_sResponse=chArray; return TRUE;}
BOOL CPop3::ReadResponse(TCHAR* pChar,UINT nSize,BOOL bDouble){ CString strTemp; //讀取回應信息 BOOL bEnd=FALSE; UINT nReceived=0; DWORD dwStart=::GetTickCount(); while(!bEnd) { //------------------------------------------------------------------------------------------------------------- //嘗試時間到 if((::GetTickCount()-dwStart)>m_dwTimeout) { pChar[nReceived]='/0'; m_sError=_T("超時"); //保存當前回應的消息 m_sResponse=pChar; return FALSE; } //------------------------------------------------------------------------------------------------------------- //看到套接字是否可讀 timeval timeout={0,0}; fd_set fds; FD_ZERO(&fds); FD_SET(m_sock,&fds); int nStatus=select(0,&fds,NULL,NULL,&timeout); if(nStatus==SOCKET_ERROR) { //套接字不可讀 m_sError=_T("套接字不可讀"); return FALSE; } else if(!nStatus) { //沒有接受到數據 ::Sleep(688); continue; }
//------------------------------------------------------------------------------------------------------------------- //從套接字中接受數據 ::Sleep(288); nStatus=recv(m_sock,pChar+nReceived,nSize,0); if(nStatus==SOCKET_ERROR) { pChar[nReceived]='/0'; //套接字錯誤 m_sError=_T("未能從套接字中收到數據"); //保存當前回應信息 m_sResponse=pChar; return FALSE; } else if(nStatus) { //重置計時器 dwStart=::GetTickCount(); //已經收到的數據又增加了 nReceived+=nStatus; }
//將pChar設為字符串,并賦給CString 型的變量 pChar[nReceived]='/0'; strTemp=pChar;
//檢查是否收到了結束標志 LPCTSTR lpszComp=bDouble ? "/r/n./r/n" : "/r/n"; bEnd=(strTemp.Find(lpszComp)!=-1); //--------------------------------------------------------------------------------------------------------------------- }
//--------------------------------------------------------------------------------------------------------------------------- //去掉結束標志 nReceived-=bDouble ? 3 : 0; pChar[nReceived]='/0'; //--------------------------------------------------------------------------------------------------------------------------- //檢查回應信息是否有效 strTemp=pChar; strTemp.MakeUpper(); int nStart=strTemp.Find("+OK"); if(nStart==-1) { //收到無效信息 m_sError=_T("回應信息無效"); return FALSE; } //-------------------------------------------------------------------------------------------------------------------------- //提取有效信息 strTemp=pChar; m_sResponse=strTemp.Right(strTemp.GetLength()-nStart-3); return TRUE;}
//進行一次空操作BOOL CPop3::Noop(){ CString strTemp="NOOP/r/n"; if(!Send((LPCTSTR)strTemp,strTemp.GetLength())) { // 發送失敗 m_sError = _T("進行空操作失敗!"); Disconnect(); return FALSE; }
// 接收回應信息 if (!GetResponse()) { // 接收回應信息失敗 m_sError = _T("無法收到回應信息或收到無效信息!"); Disconnect(); return FALSE; } return TRUE;}
//獲得郵件信息void CPOP3Dlg::Refresh(){
// 查詢郵箱狀態 if(!m_pop3.GetState()) { AfxMessageBox(m_pop3.GetErrorString()); return ; }
// 列舉郵件大小 if(!m_pop3.List()) { AfxMessageBox(m_pop3.GetErrorString()); return ; }
// 接收郵件的主題 if(!m_pop3.ListHeader()) { AfxMessageBox(m_pop3.GetErrorString()); return ; }
m_lstMail.DeleteAllItems(); UINT nIndex,nMails=m_pop3.GetMailCount(); CString strText; for(nIndex=0;nIndex<nMails;nIndex++) { strText.Format("%d",nIndex+1); m_lstMail.InsertItem(nIndex,strText); m_lstMail.SetItemText(nIndex,1,m_pop3.GetMailHeader(nIndex)); strText.Format("%d",m_pop3.GetMsgSize(nIndex)); m_lstMail.SetItemText(nIndex,2,strText); }}
BOOL CPop3::GetState(){ CString strTemp = "STAT/r/n"; if (m_bState) return TRUE; if (!Send((LPCTSTR)strTemp,strTemp.GetLength())) { // 發送失敗 m_sError = _T("查詢郵箱狀態失敗!"); Disconnect(); return FALSE; }
if (!ReadState()) { // 接收回應信息失敗 m_sError = _T("無法收到郵箱狀態信息或收到無效信息!"); Disconnect(); return FALSE; }
return TRUE;}
BOOL CPop3::ReadState(){ // 獲得返回的狀態信息 if (!GetResponse()) { // 接收返回信息失敗 m_sError = _T("接收返回信息失敗!"); return FALSE; }
// 看返回的信息是否有效 m_sResponse.MakeUpper(); UINT nEnd = 0; if (m_sResponse.Find("+OK") == -1) { // 收到無效的回應信息 m_sError = _T("返回信息無效!"); return FALSE; } else { // 分析郵件數和大小,首先分析數目 return this->ParseNumAndSize(m_nMails,m_nSize,(LPCTSTR)m_sResponse,nEnd); }}
BOOL CPop3::ParseNumAndSize(UINT &nNum,UINT &nSize,LPCTSTR lpszBuf,UINT &nEnd){ BOOL bNum=TRUE; for(int i=nEnd,j=-1;lpszBuf[i];i++) { if(isdigit(lpszBuf[i]))//是數字 j=(j==-1) ? i : j; else { if(j==-1) { //還未讀入數據 continue; } else if(bNum)//分析完一個字段 { //分析數目 m_nMails=atoi(&lpszBuf[j]); nNum=m_nMails; bNum=FALSE; j=-1; } else { //分析大小 m_nSize=atoi(&lpszBuf[j]); nSize=m_nSize; nEnd=i; return TRUE; } } } nEnd=i; return FALSE;}
//列取郵件的功能BOOL CPop3::List(){ CString strTemp="LIST/r/n"; if(m_bList) return TRUE; if(!Send((LPCTSTR)strTemp,strTemp.GetLength())) { //發送失敗 m_sError=_T("查詢郵箱狀態失敗"); Disconnect(); return FALSE; }
if(!ReadList()) { //接受回應信息回應失敗 m_sError=_T("無法收到回應信息或收到錯誤信息"); Disconnect(); return FALSE; } return TRUE;}
BOOL CPop3::ReadList(){ UINT nBuf=m_nMails*18+188; char *pBuf=new char[nBuf]; if(!pBuf) { return FALSE; }
if(!ReadResponse(pBuf,nBuf,TRUE)) { return FALSE; }
m_arSizes.RemoveAll(); m_arSizes.SetSize(m_nMails); UINT nNum,nSize,nEnd=0; while(ParseNumAndSize(nNum,nSize,m_sResponse,nEnd)) { m_arSizes.SetAt(nNum-1,nSize); } return TRUE;}
BOOL CPop3::ListHeader(){ m_arHeaders.RemoveAll(); m_arHeaders.SetSize(m_nMails); CString strTemp; for(UINT nMsg=1;nMsg<=m_nMails;nMsg++) { strTemp.Format("TOP %d 0/r/n",nMsg); if(!Send((LPCTSTR)strTemp,strTemp.GetLength())) { m_sError = _T("發送TOP命令失敗!"); return FALSE; }
if (!GetResponse()) { m_sError = _T("列舉郵件主題失敗!"); return FALSE; }
strTemp=m_sResponse; strTemp.MakeUpper();
// 查找SUBJECT段 UINT nStart=strTemp.Find("/r/nSUBJECT:"); if(nStart==-1) { m_arHeaders.SetAt(nMsg - 1,_T("")); return TRUE; } strTemp = m_sResponse.Right(m_sResponse.GetLength() - nStart - 10); nStart = strTemp.Find("/r/n"); if (nStart != -1) strTemp = strTemp.Left(nStart); strTemp.TrimLeft(); strTemp.TrimRight(); m_arHeaders.SetAt(nMsg - 1,strTemp); } return TRUE;
}
3斷開函數void CPOP3Dlg::OnDisconnect() { // TODO: Add your control notification handler code here if(!m_pop3.Disconnect()) { return ; }
// 重置用戶界面狀態 GetDlgItem(IDC_REVERSE)->EnableWindow(FALSE); GetDlgItem(IDC_DELETE)->EnableWindow(FALSE); GetDlgItem(IDC_DISCONNECT)->EnableWindow(FALSE); m_lstMail.DeleteAllItems();
MessageBox("斷開連接...");}
//斷開連接BOOL CPop3::Disconnect(){ BOOL bSuccess;
//如果還保持連接狀態則斷開 if(m_bConnected) { CString strSend="QUIT/r/n"; //發送斷開請求 if(!this->Send((LPCTSTR)strSend,strSend.GetLength())) { AfxMessageBox(_T("發送斷開請求失敗")); return FALSE; }
bSuccess=this->GetResponse();
//將有關的變量復位 m_bConnected=FALSE; m_bList=FALSE; m_bState=FALSE; m_nMails=0; m_nSize=0; m_arHeaders.RemoveAll(); m_arSizes.RemoveAll();
//關閉套接字 closesocket(m_sock); m_sock=INVALID_SOCKET; } return bSuccess;}
4刪除函數 void CPOP3Dlg::OnDelete() { POSITION pos=m_lstMail.GetFirstSelectedItemPosition(); while(pos) { if(!m_pop3.Delete(m_lstMail.GetNextSelectedItem(pos)+1)) { return ; } }
MessageBox("刪除成功..."); }
//刪除郵件功能BOOL CPop3::Delete(UINT nIndex){ CString strSend; strSend.Format("DELE %d/r/n",nIndex); //發送DELE命令 if(!Send((LPCTSTR)strSend,strSend.GetLength())) { //未能成功發送 m_sError=_T("刪除郵件失敗"); return FALSE; }
//接受返回信息 if(!GetResponse()) { m_sError=_T("收到無效信息"); return FALSE; }
//上一次STAT和LIST命令得到的信息無效 m_bState=FALSE; m_bList=FALSE; return TRUE;}
//打開郵件4 void CPOP3Dlg::OnClickListMail(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here if (m_lstMail.GetSelectedCount() != 1) { AfxMessageBox("請明確要打開的email!"); return; }
POSITION pos = m_lstMail.GetFirstSelectedItemPosition(); UINT nIndex = m_lstMail.GetNextSelectedItem(pos); CString strMail; m_pop3.RetrieveMail(2 ,strMail); this->SetDlgItemText(IDC_EDIT_TEXT,strMail);
*pResult = 0;}
//接受郵件的功能BOOL CPop3::RetrieveMail(UINT nIndex,CString &strMsg){ CString strSend; strSend.Format("RETR%d/r/n",nIndex); if(!Send((LPCTSTR)strSend,strSend.GetLength())) { m_sError=_T("收取郵件失敗"); return FALSE; }
if(!GetResponse()) { m_sError=_T("無法受到送回的郵件"); return FALSE; }
//以CONTENT-DISPOSTION:INLINE為其實標志 strMsg=m_sResponse; strMsg.MakeUpper(); int nStart=strMsg.Find("CONTENT-DISPOSTION: INLINE/r/n"); strMsg=m_sResponse.Right(m_sResponse.GetLength()-nStart-4); //空行表示郵件正文結束 nStart=strMsg.Find("/r/n/r/n");
if(nStart!=-1) strMsg=strMsg.Left(nStart); return TRUE;}
//-------------------OK下面是附加函數
CPop3::CPop3(){ // 初始化變量 m_sError = _T(""); m_sock = INVALID_SOCKET; m_nMails = 0; m_nSize = 0; m_bList = FALSE; m_bState = FALSE; m_arSizes.RemoveAll(); m_arHeaders.RemoveAll(); m_bConnected = FALSE; m_dwTimeout = 2000;}
CPop3::~CPop3(){
}
DWORD CPop3::GetMsgSize(UINT nID){ BOOL bSuccess; if(!m_bList) bSuccess=this->List(); if (!bSuccess) return 0;
return m_arSizes.GetAt(nID);
}
LPCTSTR CPop3::GetMailHeader(UINT nIndex){ return (LPCTSTR)m_arHeaders.GetAt(nIndex);}
UINT CPop3::GetMailCount() const{ return m_nMails;}
新聞熱點
疑難解答