首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++Builder 實作 POP3 郵件接收客戶端:NMPOP3 元件完整應用教學

     編輯:關於C++

利用 C++Builder 內建的 NMPOP3 元件 (屬於 Indy / NetMasters 套件),可快速建構功能完整的 POP3 郵件接收客戶端。本文提供從介面設計、元件配置、核心事件處理到進階功能 (附件、刪除、列表) 的完整實作指南。

表單介面設計與元件配置

主要視覺元件佈局 (使用 TPageControl 分頁)

分頁元件Name關鍵屬性/用途
分頁 1: 連線設定TEditedServerPOP3 伺服器位址 (如 pop.gmail.com)
TEditedPortText="110" (標準 POP3 埠),SSL 為 995
TEditedUser使用者帳號
TEditedPassPassword=True (密碼遮罩)
TButtonbtnConnectCaption="連接"
TButtonbtnDisconnectCaption="斷開連接"
分頁 2: 郵件內容TEditedMsgNum郵件編號 (輸入/顯示)
TEditedFrom寄件者
TEditedSubject主旨
TEditedSize大小 (Bytes)
TEditedMsgIdMessage-ID
TMemommBody郵件本文 (純文字/HTML)
TMemommHeaders完整郵件標頭
分頁 2 (按鈕區)TButtonbtnDeleteCaption="刪除" (標記刪除)
TButtonbtnRetrieveCaption="取回郵件" (下載完整內容)
TButtonbtnSummaryCaption="郵件資訊" (僅下載標頭/摘要)
分頁 3: 郵件列表TButtonbtnListCaption="郵件列表" (取得清單)
TButtonbtnClearListCaption="清除列表"
TMemommList顯示列表 (編號/大小)
TStatusBarsbStatus底部狀態列 (SimplePanel=True)

核心非視覺元件

  • NMPOP3 (Name: NMPOP31) — POP3 協議客戶端核心。

核心程式碼實作

1. 連線設定與建立連線 (btnConnect.OnClick)

void __fastcall TForm1::btnConnectClick(TObject *Sender) {
    NMPOP31->AttachFilePath = ".";           // 附件儲存目錄 (當前目錄)
    NMPOP31->DeleteOnRead = false;           // 讀取後不自動刪除伺服器郵件
    NMPOP31->ReportLevel = Status_Basic;     // 狀態回報等級
    NMPOP31->TimeOut = 20000;                // 逾時 20 秒

    NMPOP31->Host = edServer->Text;          // 伺服器位址
    NMPOP31->Port = StrToInt(edPort->Text);  // 埠號
    NMPOP31->UserID = edUser->Text;          // 帳號
    NMPOP31->Password = edPass->Text;        // 密碼

    NMPOP31->Connect();                      // 發起連線
    // 連線成功後 OnConnect 事件會更新郵件數量
}

2. 斷開連線 (btnDisconnect.OnClick)

void __fastcall TForm1::btnDisconnectClick(TObject *Sender) {
    NMPOP31->Disconnect();
}

3. 郵件操作按鈕 (分頁 2)

// 刪除郵件 (標記刪除,QUIT 時生效)
void __fastcall TForm1::btnDeleteClick(TObject *Sender) {
    int msgNum = StrToIntDef(edMsgNum->Text, 0);
    if (msgNum > 0) NMPOP31->DeleteMailMessage(msgNum);
}

// 取回完整郵件 (含本文、附件、標頭)
void __fastcall TForm1::btnRetrieveClick(TObject *Sender) {
    int msgNum = StrToIntDef(edMsgNum->Text, 0);
    if (msgNum == 0) return;

    NMPOP31->GetMailMessage(msgNum); // 觸發 OnRetrieveStart/End

    // 事件完成後,MailMessage 屬性填充完成
    edFrom->Text = NMPOP31->MailMessage->From;
    edSubject->Text = NMPOP31->MailMessage->Subject;
    edMsgId->Text = NMPOP31->MailMessage->MessageId;
    edSize->Text = IntToStr(NMPOP31->MailMessage->Size);

    mmHeaders->Lines->Assign(NMPOP31->MailMessage->Head);
    mmBody->Lines->Assign(NMPOP31->MailMessage->Body);

    // 處理附件
    if (!NMPOP31->MailMessage->Attachments->Text.IsEmpty()) {
        ShowMessage("附件清單:\n" + NMPOP31->MailMessage->Attachments->Text);
        // 附件已自動儲存至 AttachFilePath 目錄
    }
}

// 僅取回摘要 (標頭 + 大小,不下載本文/附件,速度快)
void __fastcall TForm1::btnSummaryClick(TObject *Sender) {
    int msgNum = StrToIntDef(edMsgNum->Text, 0);
    if (msgNum == 0) return;

    NMPOP31->GetSummary(msgNum);

    edFrom->Text = NMPOP31->Summary->From;
    edSubject->Text = NMPOP31->Summary->Subject;
    edMsgId->Text = NMPOP31->Summary->MessageId;
    edSize->Text = IntToStr(NMPOP31->Summary->Bytes);
    // Summary 無 Body 與 Attachments
}

4. 郵件列表操作 (分頁 3)

// 取得郵件清單 (編號 + 大小)
void __fastcall TForm1::btnListClick(TObject *Sender) {
    NMPOP31->List(); // 觸發 OnList 事件逐筆回傳
}

void __fastcall TForm1::btnClearListClick(TObject *Sender) {
    mmList->Clear();
}

5. NMPOP3 關鍵事件處理 (雙擊元件 Events 頁籤)

// 連線成功
void __fastcall TForm1::NMPOP31Connect(TObject *Sender) {
    sbStatus->SimpleText = "已連線至 " + NMPOP31->Host;
    // 更新郵件總數 (連線成功後自動取得)
    LabelCount->Caption = "郵件總數: " + IntToStr(NMPOP31->MailCount);
}

// 連線失敗
void __fastcall TForm1::NMPOP31ConnectionFailed(TObject *Sender) {
    ShowMessage("連線失敗!請檢查伺服器、埠號、帳號密碼。");
}

// 需要連線時 (離線操作觸發)
void __fastcall TForm1::NMPOP31ConnectionRequired(TObject *Sender, bool &Handled) {
    if (MessageBox(Handle, "需要連線至伺服器,是否立即連線?", "連線請求", MB_YESNO | MB_ICONQUESTION) == IDYES) {
        Handled = true;
        btnConnectClick(this); // 觸發連線
    }
}

// 斷開連線
void __fastcall TForm1::NMPOP31Disconnect(TObject *Sender) {
    sbStatus->SimpleText = "已斷線";
}

// 伺服器名稱解析完成
void __fastcall TForm1::NMPOP31HostResolved(TObject *Sender) {
    sbStatus->SimpleText = "主機名稱解析完成";
}

// 無效主機名
void __fastcall TForm1::NMPOP31InvalidHost(TObject *Sender, AnsiString &NewHost, bool &Handled) {
    if (InputQuery("無效主機", "請輸入正確的 POP3 伺服器位址:", NewHost)) {
        NMPOP31->Host = NewHost;
        Handled = true;
    }
}

// 郵件列表項目接收 (List 命令回傳)
void __fastcall TForm1::NMPOP31List(TObject *Sender, int Msg, int Size) {
    if (Msg < 2) mmList->Clear(); // 第一筆前清空
    mmList->Lines->Add("編號: " + IntToStr(Msg) + "  大小: " + IntToStr(Size) + " Bytes");
}

// 列表傳輸進度
void __fastcall TForm1::NMPOP31ListPacketRecvd(TObject *Sender) {
    sbStatus->SimpleText = "已接收 " + IntToStr(NMPOP31->BytesRecvd) + " / " + IntToStr(NMPOP31->BytesTotal) + " Bytes";
}

// 郵件取回開始/結束
void __fastcall TForm1::NMPOP31RetrieveStart(TObject *Sender) {
    Screen->Cursor = crHourGlass;
    sbStatus->SimpleText = "正在取回郵件...";
}
void __fastcall TForm1::NMPOP31RetrieveEnd(TObject *Sender) {
    Screen->Cursor = crDefault;
    sbStatus->SimpleText = "郵件取回完成";
}

// 一般狀態回報
void __fastcall TForm1::NMPOP31Status(TObject *Sender, const AnsiString &Status) {
    sbStatus->SimpleText = Status;
}

// 操作成功/失敗
void __fastcall TForm1::NMPOP31Success(TObject *Sender) {
    sbStatus->SimpleText = "操作成功";
}
void __fastcall TForm1::NMPOP31Failure(TObject *Sender) {
    ShowMessage("操作失敗!");
    sbStatus->SimpleText = "操作失敗";
}

// 重設刪除標記 (RSET 命令)
void __fastcall TForm1::NMPOP31Reset(TObject *Sender) {
    ShowMessage("已重設刪除標記");
}

進階主題與注意事項

  1. SSL/TLS 加密連線:標準 POP3 (埠 110) 為明文傳輸。現代郵件伺服器 (Gmail, Outlook, Yahoo) 強制要求 SSL/TLS (埠 995)。NMPOP3 元件較舊可能不直接支援 SSL。建議改用 Indy 10 (TIdPOP3 + TIdSSLIOHandlerSocketOpenSSL) 實作加密連線。
  2. 刪除機制:DeleteMailMessage 只發送 DELE 命令標記刪除。必須正常 Disconnect() (發送 QUIT) 伺服器才會真正刪除。若程式異常結束或網路中斷未送 QUIT,標記會被清除 (等同 RSET)。
  3. 大量郵件效能:GetMailMessage 下載完整內容較慢。列表頁面建議僅用 List() + GetSummary() 顯示摘要,使用者點選再 GetMailMessage。
  4. 編碼處理:郵件標頭/主旨可能採用 MIME 編碼 (=?utf-8?B?...?=)。Indy/NMPOP3 通常自動解碼,若出現亂碼需手動處理 TIdDecoderMIME。
  5. 附件處理:AttachFilePath 目錄必須存在且可寫入。附件檔名衝突會覆蓋,建議自行管理檔名。

現代化建議:遷移至 Indy 10 (TIdPOP3)

NMPOP3 屬於舊版 NetMasters/Indy 8/9 時代元件。C++Builder 10.x+ 內建 Indy 10,提供 TIdPOP3、TIdMessage、TIdSSLIOHandlerSocketOpenSSL,支援完整 SSL/TLS、Unicode、MIME 多部分解析、非同步操作。新專案請直接使用 Indy 10 元件,架構更清晰、維護性更高。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved