Terry C. Gao 的专栏

Begin each day as for long purpose

获取本机通讯薄的内容

第一、读取系统自带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());
    }    

附注:
    使用读取Outlook2000通讯薄内容的代码时,请注意下面要点:
    要在InitInstance()涵数内部加入下面语句来先初始化COM对象:AfxOleInit();  这样才可以正确读出内容。


参考文献:
Importing Contacts from Outlook -- Deepesh Dhapola
Accessing the Windows Address Book – Code4Food
阅读更多
个人分类: Programming Tips
上一篇wab文件格式分析
下一篇如何获得outlook Express地址簿的文件夹名
想对作者说点什么? 我来说一句

获取本机通讯薄的内容(源码)

2006年03月16日 343KB 下载

OUTLOOK全球通讯薄导出工具

2009年04月19日 367KB 下载

获取本机的MAC地址

2009年07月28日 20KB 下载

获取本机所有已安装的软件

2011年11月11日 28KB 下载

Java调用jpcap获取本机所有get请求

2016年05月20日 284KB 下载

java 获取本机mac地址

2016年01月11日 2KB 下载

没有更多推荐了,返回首页

关闭
关闭