程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 獲取本機通訊薄的內容

獲取本機通訊薄的內容

編輯:關於VC++

簡介

如果你想獲取本機通訊簿(Outlook Express和Outlook2000)的內容,如:聯系人名字、聯系人郵件地址等時,可以試試下面的方法。下面是把此方法用VC6編寫的示例程序運行效果:

由於讀取Outlook Express(系統自帶)和Outlook2000(Office2000中所帶)中通訊薄內容所采取的方法不同,下面將分開簡述。

第一、讀取系統自帶Outlook Express中通訊薄方法

基本思路

通過載入Wab32.dll文件(此文件一般位於路徑“<盤符>\Program Files\Common Files\System\”下面),再獲取其內部涵數WABOpen的進程地址加以調用,來讀出通訊薄中主要內容。

具體實現

一、 包含通訊薄頭文件及聲明內部函數

#include <wab.h>  // 通訊薄頭文件
// 內部函數聲明
typedef HRESULT (WINAPI *fWABOpen)(LPADRBOOK*,LPWABOBJECT*,LPWAB_PARAM,DWORD);

二、 讀取具體內容的詳細代碼

// 讀取通訊薄內容(類型、呢稱、名字、EMAIL)
void CGetEmailDlg::OnOK()
{
  HRESULT hRes;
  LPADRBOOK lpAdrBook;
  LPWABOBJECT lpWABObject;
  LPWAB_PARAM lpWABParam = NULL;
  DWORD Reserved2 = NULL;
  HINSTANCE hinstLib;
  hinstLib = LoadLibrary("D:\\Program Files\\Common Files\\System\\wab32");
  fWABOpen procWABOpen;
  if (hinstLib != NULL)
  {
    // 獲取"Wab32.dll"內部涵數WABOpen的進程地址
    procWABOpen = (fWABOpen) GetProcAddress(hinstLib, "WABOpen");
    if (procWABOpen != NULL)
    {
      hRes = (procWABOpen)(&lpAdrBook,&lpWABObject,NULL,Reserved2);
      _ASSERTE(hRes == S_OK);
      if (hRes != S_OK) exit(1);
      ULONG lpcbEntryID;
      ENTRYID *lpEntryID;
      hRes = lpAdrBook->GetPAB(
        &lpcbEntryID,
        &lpEntryID
      );
      _ASSERTE(hRes == S_OK);
      if (hRes != S_OK) exit(2);
      ULONG ulFlags = MAPI_BEST_ACCESS;
      ULONG ulObjType = NULL;
      LPUNKNOWN lpUnk = NULL;
      hRes = lpAdrBook->OpenEntry(
        lpcbEntryID,
        lpEntryID,
        NULL,
        ulFlags,
        &ulObjType,
        &lpUnk
      );
      ulFlags = NULL;

      if (ulObjType == MAPI_ABCONT)
      {
        IABContainer *lpContainer = static_cast <IABContainer *>(lpUnk);
        LPMAPITABLE lpTable = NULL;
        hRes = lpContainer->GetContentsTable(
          ulFlags,
          &lpTable
        );
        _ASSERT(lpTable);
        ULONG ulRows;
        hRes = lpTable->GetRowCount(0,&ulRows);
        _ASSERTE(hRes == S_OK);
        SRowSet *lpRows;
        hRes = lpTable->QueryRows(
          ulRows,    // 獲取所有行
          0,
          &lpRows
        );
        m_ListEmail.ResetContent();
        for(ULONG i=0;i<lpRows->cRows;i++)
        {
          SRow *lpRow = &lpRows->aRow[i];
          CString strTemp;

          for(ULONG j=0;j<lpRow->cValues;j++)
          {
            SPropValue *lpProp = &lpRow->lpProps[j];

            if (lpProp->ulPropTag == PR_DISPLAY_NAME_A)
              strTemp = strTemp + " 名字: " + (char *)lpProp->Value.lpszA;
            if (lpProp->ulPropTag == PR_EMAIL_ADDRESS_A)
              strTemp = strTemp + " Email: " + (char *)lpProp->Value.lpszA;
            if (lpProp->ulPropTag == PR_NICKNAME_A)
              strTemp = strTemp + " 呢稱: " + (char *)lpProp->Value.lpszA;
            if (lpProp->ulPropTag == PR_ADDRTYPE_A)
              strTemp = strTemp + " 類型: " + (char *)lpProp->Value.lpszA;
          }
          m_ListEmail.AddString(strTemp);
          lpWABObject->FreeBuffer(lpRow);
        }
        lpWABObject->FreeBuffer(lpRows);
      }
    }
    FreeLibrary(hinstLib);
    // 讀取成功後,置讀取按鈕無效
    CButton* pBtn = (CButton*)GetDlgItem(IDOK);
    pBtn->EnableWindow(FALSE);
  }
}

附注:在包含進頭文件Wab.h進行編釋時,有時會在WABTAGS.H等地方編釋不通,可按示例源碼中所帶WABTAGS.H文件加以修改,主要是原安裝文件的內容有部分損壞。

第二、讀取Office2000中所帶Outlook2K中通訊薄方法

基本思路

由於Outlook2000下支持內部COM接口,可以利用此接口來讀取其內部通訊薄中主要內容。

具體實現

一、 導入Outlook2000的庫文件

// 導入讀取Outlook2000中通訊薄內容所需庫
#import "e:\Program Files\Microsoft Office\Office\mso9.dll" named_guids
#import "e:\Program Files\Microsoft Office\Office\MSOUTL9.olb" \
  no_namespace exclude("_IRecipientControl", "_DRecipientControl")

二、 讀取具體內容的詳細代碼

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

HRESULT hr;
try
{
  hr=pApp.CreateInstance(__uuidof(Application));
  if (FAILED(hr))
  {
    MessageBox("Outlook實例創建失敗","錯誤",MB_OK);
    return;
  }
  // 獲取默認Outlook中聯系人文件夾
  pFolder=pApp->GetNamespace(_bstr_t("MAPI"))->GetDefaultFolder(olFolderContacts);
  if (pFolder==NULL)
  {
    MessageBox("沒有發現默認的Outlook聯系人文件夾","錯誤!");
    return;
  }
  else // 否則自行選擇Outlook中一指定文件夾
  {
    pFolder=pApp->GetNamespace(_bstr_t("MAPI"))->PickFolder();
    if (pFolder==NULL)
      return;
    if (pFolder->GetDefaultItemType()!=olContactItem)  // 不是聯系人
    {
      MessageBox("選擇不是聯系人文件夾","錯誤");
      return;
    }
  }
  pItems=pFolder->GetItems();
  if (pItems==NULL)
  {
    MessageBox("不能得到聯系人條目","錯誤");
    return;
  }

  pContact=pItems->GetFirst();

  m_ListEmail.ResetContent();
  while(1)
  {
    if (pContact==NULL)
      break;
    CString strTemp;
    strTemp=(char *)pContact->GetFullName();
    strTemp=strTemp + "<";
    strTemp=strTemp + (char *)pContact->GetEmail1Address();
    strTemp=strTemp + ">";
    m_ListEmail.AddString(strTemp);
    pContact=pItems->GetNext();
  }
}
catch(_com_error &e)
{
  MessageBox((char *)e.Description());
}

參考文獻:

Importing Contacts from Outlook -- Deepesh Dhapola

Accessing the Windows Address Book – Code4Food

本文配套源碼

  1. 上一頁:
  2. 下一頁:
欄目導航
Copyright © 程式師世界 All Rights Reserved