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

讀取 Windows 通訊錄:Outlook Express 與 Outlook 2000 兩種方法完整實現

     編輯:關於VC++

前言

應用程式常需存取使用者的通訊錄資料 (姓名、Email、暱稱等)。Windows 系統內建 Outlook Express (OE) 與 Office 套件的 Outlook 2000 (OL2K) 儲存機制截然不同,本文提供兩套完整的 VC++ 實作程式碼。

方法一:讀取 Outlook Express (WAB) 通訊錄

OE 使用 Windows Address Book (WAB),儲存於 .wab 檔案,透過 WAB32.dll 介面存取。

核心步驟

  1. 載入 WAB32.dll (通常位於 Program Files\Common Files\System\)
  2. 取得 WABOpen 函數指標
  3. 呼叫 WABOpen 取得 IAddrBook 與 IWABObject 介面
  4. 取得個人通訊簿容器 (GetPAB)
  5. 開啟容器並取得內容表格 (GetContentsTable)
  6. 查詢所有列 (QueryRows) 並解析屬性標籤

關鍵程式碼


#include <wab.h>
typedef HRESULT (WINAPI *fWABOpen)(LPADRBOOK*, LPWABOBJECT*, LPWAB_PARAM, DWORD);

void CGetEmailDlg::OnOK() {
    HINSTANCE hLib = LoadLibrary("WAB32.DLL"); // 建議用完整路徑
    if (!hLib) return;

    fWABOpen pWABOpen = (fWABOpen)GetProcAddress(hLib, "WABOpen");
    if (!pWABOpen) { FreeLibrary(hLib); return; }

    LPADRBOOK pAdrBook = NULL;
    LPWABOBJECT pWABObj = NULL;
    HRESULT hr = pWABOpen(&pAdrBook, &pWABObj, NULL, 0);
    if (FAILED(hr)) { FreeLibrary(hLib); return; }

    // 取得 PAB 容器
    ULONG cbEntryID; LPENTRYID pEntryID;
    hr = pAdrBook->GetPAB(&cbEntryID, &pEntryID);
    if (FAILED(hr)) { pWABObj->Release(); pAdrBook->Release(); FreeLibrary(hLib); return; }

    // 開啟容器
    LPUNKNOWN pUnk = NULL; ULONG ulObjType;
    hr = pAdrBook->OpenEntry(cbEntryID, pEntryID, NULL, MAPI_BEST_ACCESS, &ulObjType, &pUnk);
    pWABObj->FreeBuffer(pEntryID);
    if (FAILED(hr) || ulObjType != MAPI_ABCONT) { /* 清理 */ return; }

    IABContainer* pCont = (IABContainer*)pUnk;
    LPMAPITABLE pTable = NULL;
    hr = pCont->GetContentsTable(0, &pTable);
    if (FAILED(hr)) { /* 清理 */ return; }

    ULONG cRows;
    pTable->GetRowCount(0, &cRows);
    SRowSet* pRows = NULL;
    hr = pTable->QueryRows(cRows, 0, &pRows);
    if (SUCCEEDED(hr)) {
        for (ULONG i = 0; i < pRows->cRows; i++) {
            SRow* pRow = &pRows->aRow[i];
            CString str;
            for (ULONG j = 0; j < pRow->cValues; j++) {
                SPropValue* pProp = &pRow->lpProps[j];
                switch (pProp->ulPropTag) {
                    case PR_DISPLAY_NAME_A: str += " 姓名: " + CString((char*)pProp->Value.lpszA); break;
                    case PR_EMAIL_ADDRESS_A: str += " Email: " + CString((char*)pProp->Value.lpszA); break;
                    case PR_NICKNAME_A: str += " 暱稱: " + CString((char*)pProp->Value.lpszA); break;
                    case PR_ADDRTYPE_A: str += " 類型: " + CString((char*)pProp->Value.lpszA); break;
                }
            }
            m_ListEmail.AddString(str);
            pWABObj->FreeBuffer(pRow);
        }
        pWABObj->FreeBuffer(pRows);
    }

    // 清理介面與庫
    pTable->Release(); pCont->Release(); pAdrBook->Release(); pWABObj->Release();
    FreeLibrary(hLib);
}

編譯注意事項

  • 需包含 wab.h,若 WABTAGS.H 編譯錯誤,請參考範例附帶的修正版本
  • 連結 mapi32.lib

方法二:讀取 Outlook 2000 通訊錄 (COM 介面)

OL2K 公開標準 COM 介面,透過 #import 匯入型別庫最為便利。

匯入型別庫


#import "C:\\Program Files\\Microsoft Office\\Office\\mso9.dll" named_guids
#import "C:\\Program Files\\Microsoft Office\\Office\\MSOUTL9.olb" \
    no_namespace exclude("_IRecipientControl", "_DRecipientControl")
路徑請依實際 Office 安裝位置調整

核心程式碼


_ApplicationPtr pApp;
_NameSpacePtr pNs;
MAPIFolderPtr pFolder;
_ItemsPtr pItems;
_ContactItemPtr pContact;

try {
    hr = pApp.CreateInstance(__uuidof(Application));
    if (FAILED(hr)) { MessageBox("Outlook 實例建立失敗"); return; }

    // 取得預設聯絡人資料夾
    pFolder = pApp->GetNamespace(_bstr_t("MAPI"))->GetDefaultFolder(olFolderContacts);
    if (!pFolder) { MessageBox("找不到預設聯絡人資料夾"); return; }

    // 或讓使用者選擇資料夾
    // pFolder = pApp->GetNamespace(_bstr_t("MAPI"))->PickFolder();
    // if (!pFolder || pFolder->GetDefaultItemType() != olContactItem) return;

    pItems = pFolder->GetItems();
    if (!pItems) { MessageBox("無法取得聯絡人項目"); return; }

    pContact = pItems->GetFirst();
    m_ListEmail.ResetContent();

    while (pContact) {
        CString str;
        str = (char*)(_bstr_t)pContact->GetFullName();
        str += " <";
        str += (char*)(_bstr_t)pContact->GetEmail1Address();
        str += ">";
        m_ListEmail.AddString(str);
        pContact = pItems->GetNext();
    }
}
catch (_com_error& e) {
    MessageBox((char*)e.Description());
}

比較與選擇建議

特性Outlook Express (WAB)Outlook 2000 (COM)
部署需求系統內建,無額外安裝需安裝 Office 2000
程式複雜度較高 (MAPI 介面)較低 (#import 智慧指標)
效能直接存取 .wab 檔透過 Outlook 進程
資料完整度基本欄位完整聯絡人物件模型

參考資源

  • Importing Contacts from Outlook — Deepesh Dhapola
  • Accessing the Windows Address Book — Code4Food
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved