日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CEMAPI实战攻略(二)——建立与短信信箱的连接

發布時間:2023/12/20 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CEMAPI实战攻略(二)——建立与短信信箱的连接 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

CEMAPI實戰攻略

by 吳春雷

QQ:819543772

Email:wuchunlei@163.com

二.建立與短信信箱的連接

上一部分已經討論過,如何搭建開發和測試環境,以及如何初始化CEMAPI,再繼續這一部分的討論之前,我們先要澄清幾個概念。第一個是會話(Seesion),相信開發網絡應用的朋友都不陌生,為了提高通訊效率降低通訊開銷,有時候我們需要再目標與本地之間創建一個通道,在通道創建之初,目標與本地先做一些列的響應和請求確認兩邊的身份,當通道建立以后,目標與本地之間的通訊過程中就不再涉及兩邊的身份確認,這通常目標與本地之間的建立的通道,通常被稱作會話,也就是Session。在使用Cemapi讀取短信之前,應用程序也需要與設備上的信息(郵件)系統之間建立一個Session,用以 確認雙方的身份,這是采用Cemapi讀取短信的第一步。第二個概念是短消息(郵件)倉庫(MsgStore),在WM中,郵件和短消息是屬于一個系統的,Session建立了與這個系統之間的連接,然后必須告訴系統,我們的程序是要對郵件功能進行操作,還是要對短信功能進行操作,通過調用相應的函數(后面會介紹),MsgStore會指向我們需要操作的短信或郵件的倉庫上。第三個概念是信箱,或者叫文件夾(Folder),當獲得了指向一個具體倉庫的MsgStore以后,下一步就需要獲取具體的信箱(文件夾)了,比如當程序確定了希望對收件箱還是發件箱進行操作以后,Folder將會指向我們想要操作的具體的信箱。

OK,澄清了這三個概念,就可以進一步討論,如何建立會話,獲取具體信箱了。

1.?????? 會話接口IMAPISession

mapidefs.h中我們可以看到,通過DECLARE_MAPI_INTERFACE_這個宏使IMAPISession派生自IUnKnow接口,IUnKnow接口中定義引用技術等與COM有關的基本操作,關于IUnKnow的詳細內容大家可以參見COM技術的相關資料。IMAPISession接口中值得注意的一個函數是GetMsgStoresTable,后面我們將通過調用該函數獲取短信(郵件)倉庫的列表。

2.?????? 如何創建與MAPI的會話

Cemapi中,我們將使用MAPILogonEx函數建立與短信(郵件)系統的會話,MAPILogonExMapix.h中的定義如下:

typedef HRESULT (STDMETHODCALLTYPE MAPILOGONEX)(

??? ULONG ulUIParam,

??? LPTSTR lpszProfileName,

??? LPTSTR lpszPassword,

??? ULONG ulFlags,??

??? LPMAPISESSION FAR * lppSession

);

MAPILOGONEX MAPILogonEx;

從定義中可以看出MAPILogonEx函數返回一個HRESULT類型,采用宏FAILEDSUCCESSED可以判斷函數是否成功返回。同時,該函數有五個參數,這五個參數分別表示,短信(郵件)系統登陸UI的現實方式以及Session的共享方式,配置文件的文件名,郵箱密碼,編碼方式(默認)和指向IMAPISession接口指針的指針,對于短信應用程序的開發,前四個參數均無意義,可以直接設置為NULL。如果函數調用成功,我們將會從最后一個參數那里得到短信(郵件)系統的Session指針。調用方法如下:

IMAPISession *m_pSession=NULL;

???????? hr=MAPILogonEx(NULL,NULL,NULL,NULL,&m_pSession);

???????? if(FAILED(hr) || NULL==m_pSession)

???????? {

????????????? //異常處理

???????? }

3.?????? 如何終止與短信(郵件)系統的會話,并釋放Session對象

使用IMAPISession接口中Logoff方法可以終止與短信(郵件)系統的會話,Logoff方法定義為:

HRESULT IMAPISession::Logoff(ULONG ulUIParam,ULONG ulFlags,ULONG ulReserved);

方法返回一個HRESULT對象,通過它可以判斷調用是否成功。前兩個參數的意義與MAPILogonEx中的同名參數相同,最后一個參數保留不用。對于短信操作來說,三個參數均可設置為NULL

當成功Logoff以后,如果確信不再需要Session對象以后,可以通過Release方法釋放對象。源代碼如下:

if(NULL!=m_pSession)??????? //釋放Session

???????? {

????????????? HRESULT hr=m_pSession->Logoff(NULL,NULL,NULL);

????????????? if(FAILED(hr))

{

???? //異常處理

}

????????????? m_pSession->Release();

????????????? m_pSession=NULL;

}

4.?????? 短信(郵件)倉庫接口IMsgStore

IMsgStore繼承自IMAPIProp接口,而IMAPIProp接口又繼承自IUnknow接口,這個接口中值得我們重點關注的函數有GetProps,OpenEntry兩個函數,后面我們將會通過這兩個函數獲取具體信箱(Folder)對象。

5.?????? 建立與短信倉庫的連接

在實現連接以前,先來看一個很有意思的宏

#define SizedSPropTagArray(_ctag, _name) /

struct _SPropTagArray_ ## _name /

{ /

??? ????????? ULONG?? cValues; /

??? ????????? ULONG?? aulPropTag[_ctag]; /

} _name

為什么說這個結構體有意思,仔細看一下就知道了,利用了一個帶參數的宏,實現了動態聲明結構體的功能,更奇妙的是,連結構體的名稱都可以動態創建。大家別怪我顧洛寡聞,這種聲明方式還真是不太常見。這個數據結構在Cemapi中扮演一個很重要的角色,通過定制的實現它,可以告訴函數,我希望獲取或設置那些屬性。看下面一段程序:

SizedSPropTagArray(2 , Columns) = ???????? {

????????????? 2,

????????????? PR_ENTRYID, //Entry ID

????????????? PR_DISPLAY_NAME //Display Name

};

這段程序動態的聲明了一個名為_SPropTagArray_Columns的結構體,并且聲明了一個名為Columns的結構體變量。這個結構體中有一個ULONG類型的成員變量,和一個長度為2ULONG類型的數組成員組成。結構體中cValues的值被初始化為2aulPropTag[0]=PR_ENTRYIDaulProTag[1]=PR_DISPLAY_NAME

這里面涉及到了兩個常量符號,PR_ENTRYIDPR_DISPLAY_NAME,這兩個符號分別表示對象ID和顯示名稱,這里所說的對象可以是短信(郵件)存儲倉庫,也可是具體信箱Folder,還可以是短消息本身,調用不同的函數,這些符號會被解釋為具體對象的某些屬性。

另外還有一個重要的接口需要說明,那就是IMAPITable,這個接口也從IUnKnow中繼承。在WM系統中的短信(郵件)倉庫、具體信箱Folder以及Folder中的短信都不是唯一的,在使用Cemapi中的接口方法獲取這些對象的時候,將會采用表的形式返回結果,IMAPITable接口的作用就是用于描述這個表的結構。

有了這兩個類型作為基礎,我們就可以通過嘗試獲取WM系統中的短信(郵件)倉庫列表了,前面提到了IMAPISession接口一個方法GetMsgStoresTable,從名字上應該就很直觀的知道了這個方法的功能,即獲取MsgStore(短信郵件倉庫)列表。該方法定義為:

HRESULT IMAPISession::GetMsgStoresTable(ULONG ulFlags,LPMAPITABLE FAR * lppTable)

???????? 返回值依舊標志方法是否運行成功,不再贅述。參數中

ulFlags:表示字符編碼類型,這里好像只有MAPI_UNICODE標志供選擇。

lppTable:實際是一個IMAPITable **類型,該方法通過它返回MsgStore(短信郵件倉庫)列表。

GetMsgStoresTable方法成功獲取了IMAPITable接口的對象以后,這時該對象里面的數據還是以原始的方式組織的,我們無法獲取表中的記錄,這時候就需要調用IMAPITable接口中的SetColumns方法來告訴IMAPTABLE對象,內部數據將以什么形式進行組織。該方法定義為:

HRESULT IMAPITable::SetColumns(LPSPropTagArray , ULONG);

返回值用于判斷方法調用是否成功。參數說明:

LPSPropTagArray:用于說明IMAPITable中記錄的組織形式,把前面提到過的Columns對象作為參數傳入,則表示告訴IMAPITable對象,表格中每條記錄有兩列,第一列是對象ID(PR_ENTRYID),第二列是對象現實名稱(PR_DISPLAY_NAME)

ULONG:某種標志,一般設置為0,這里我沒有找到相關資料,希望高手們補充。

有了表格,有了記錄的結構,下一步要做什么應該很容易就能想到。Yes ,取表格中的所有記錄,并且遍歷這些記錄,查找顯示名稱(PR_DISPLAY_NAME)SMS的記錄。這里再介紹一種數據結構SRowSet,其定義如下:

typedef struct _SRowSet

{

??? ULONG?????????? cRows;????????? /* 行數 */

??? SRow??????????? aRow[MAPI_DIM]; /* 行記錄具體信息 */

} SRowSet, FAR * LPSRowSet;

???? 很有意思,MAPI_DIM的值為1,但是絕不是說所有從IMAPITable中取出的行記錄都只有一列,恰恰相反,列的數量是由我們前面提到的動態結構體變量Columns中的cValues的值來決定的,這里請讀者朋友們注意。SRow也為一個結構體,其定義如下:

typedef struct _SRow

{

??? ULONG?????????? ulAdrEntryPad;?

??? ULONG?????????? cValues;??????? /* 用于標志lpProps成員的數量 */

??? LPSPropValue??? lpProps;??????? /* 屬性結構體*/

} SRow, FAR * LPSRow;

lpProps成員所對應的結構體SPropValue才是行記錄中真正的數據。其定義如下

typedef struct _SPropValue

{

??? ULONG?????? ulPropTag;??????????????? /*屬性標志,常用于輔助判斷屬性值是否成功獲取*/

??? ULONG?????? dwAlignPad;

??? union _PV?? Value;

} SPropValue, FAR * LPSPropValue;

這個結構中Value成員非常有用,它由很多成員組成,每個成員對應著對象的一個屬性,該聯合體定義如下:

typedef union _PV

{

??? short int?????????? i;????? ????/* case PT_I2 */

??? LONG??????????????? l;????????? /* case PT_LONG */

??? ULONG?????????????? ul;???????? /* alias for PT_LONG */

??? float?????????????? flt;??????? /* case PT_R4 */

??? double????????????? dbl;??????? /* case PT_DOUBLE */

??? unsigned short int? b;????????? /* case PT_BOOLEAN */

??? CURRENCY??????????? cur;??????? /* case PT_CURRENCY */

??? double????????????? at;???????? /* case PT_APPTIME */

??? FILETIME??????????? ft;???????? /* case PT_SYSTIME */

??? LPSTR?????????????? lpszA;????? /* case PT_STRING8 */

??? SBinary???????????? bin;??????? /* case PT_BINARY */

??? LPWSTR????????????? lpszW;????? /* case PT_UNICODE */

??? LPGUID????????????? lpguid;???? /* case PT_CLSID */

??? LARGE_INTEGER?????? li;???????? /* case PT_I8 */

??? SShortArray???????? MVi;??????? /* case PT_MV_I2 */

??? SLongArray????????? MVl;??????? /* case PT_MV_LONG */

??? SRealArray????????? MVflt;????? /* case PT_MV_R4 */

??? SDoubleArray??????? MVdbl;????? /* case PT_MV_DOUBLE */

??? SCurrencyArray????? MVcur;????? /* case PT_MV_CURRENCY */

??? SAppTimeArray?????? MVat;?????? /* case PT_MV_APPTIME */

??? SDateTimeArray????? MVft;?????? /* case PT_MV_SYSTIME */

??? SBinaryArray??????? MVbin;????? /* case PT_MV_BINARY */

??? SLPSTRArray???????? MVszA;????? /* case PT_MV_STRING8 */

??? SWStringArray?????? MVszW;????? /* case PT_MV_UNICODE */

??? SGuidArray????????? MVguid;???? /* case PT_MV_CLSID */

??? SLargeIntegerArray? MVli;?????? /* case PT_MV_I8 */

??? SCODE?????????????? err;?? ?????/* case PT_ERROR */

??? LONG??????????????? x;????????? /* case PT_NULL, PT_OBJECT (no usable value) */

} __UPV;

看到這么成員是不是眼有些花呀?我認為這些成員不必全部了解,因為我們不必像想孔乙己那樣,知道茴香豆的茴字怎么寫,還要知道有幾種寫法(當然您也可以不這么認為)。其實我們只需要知道ftlpszAlpszW以及bin這四個成員就可以了,他們分別代表發送(接收)時間,顯示名稱或消息標題或正文或發送號碼或接受號碼等字符串(ASCII),顯示名稱或消息標題或正文或發送號碼或接受號碼等字符串(UNICODE)以及對象的EntryID(對象可以是短信郵件倉庫,可以是具體信箱Folder也可以是某條短信)。在這一小節中,我們只用到了lpszWbinSBinary也為一個結構體對象,它用來唯一標示某一對象的ID,其定義如下:

typedef struct _SBinary

{

??? ULONG?????? cb;

??? LPBYTE????? lpb;

} SBinary, FAR *LPSBinary;

這里面的兩個成員含義不必深究,我們只需要知道,這兩個成員所組成的結構體對象SBinary可以作為唯一標示對象的ID(對象依舊可以是短信郵件倉庫,可以是具體信箱Folder也可以是某條短信,在這一小節中它表示短信郵箱倉庫對象的ID

???? IMAPITable中提供了QueryRows方法來獲取行記錄,其定義如下:

???????? HRESULT IMAPITable::QueryRows(LONG,ULONG,SRowSet **);

???? 返回值用于判斷方法調用是否成功,這里要注意,如果取不到任何行記錄的時候也會返回失敗,因此可以用于判斷行記錄是否已經遍歷完畢。參數說明:

???? LONG:希望獲取多少行記錄。

ULONG:標志可以是如下定義的符號之一,很抱歉,具體每種標志代表什么含義,并沒有資料特別的說明,有興趣的朋友可以研究一下。再短信應用中,這個值一般會設置為0

#define TBL_LEAF_ROW??????????? ((ULONG) 1)

#define TBL_EMPTY_CATEGORY????? ((ULONG) 2)

#define TBL_EXPANDED_CATEGORY?? ((ULONG) 3)

#define TBL_COLLAPSED_CATEGORY? ((ULONG) 4)

SRowSet **:這個參數用于返回查找到的行記錄。

每次QueryRows成功執行以后,IMAPITable中的游標會自動移動第一個參數LONG行記錄,直到遍歷完畢為止。

現在我們已經獲取短信郵件系統中的所有短信郵件倉庫了,下面要做的就是找到顯示名稱為SMS的那個MsgStore倉庫,并獲去指向該倉庫的對象指針。還記得Columns這個動態結構體變量嗎?我們通過SetColumns方法給行記錄定義了兩列,第一列為對象IDPR_ENTRYID),第二列為顯示名稱(PR_DISPLAY_NAME),那么每一個SRowSet對象中就會有兩個SPropValue結構體對象,第一個就代表PR_ENTRYID,第二個則代表PR_DISPLAY_NAME,第一個SPropValue中的Value聯合體中的bin成員有效,而第二個SPropValue中的Value聯合體中的lpszW成員有效。如果我們使用QueryRows方法獲取到的SRowSet *對象為m_pRows,則下面代碼則表示上述說明內容。

m_pRows->aRow[0].lpProps[0].Value.binPR_ENTRYID

m_pRows->aRow[0].lpProps[1].Value.lpszWPR_DISPLAY_NAME

有了對象ID,我們就可以通過IMAPISession中的OpenEntry方法獲取短信倉庫對象IMsgStore了。OpenEntry方法定義為:

HRESULT IMAPISession::OpenEntry(ULONG,LPENTRYID,LPCIID,ULONG,ULONG*,LPUNKNOW*);

返回值說明了方法調用是否成功,參數說明如下:

ULONG:短信郵件倉庫的EntryId,也即對應的SBinary結構中的cb成員

LPENTRYID:短信郵件倉庫的EntryId指針,也即對應的SBinary結構中的lpb成員

LPCIID:本質是一個指向GUID結構體變量的指針,若想更深入的了解GUID結構體請參考COM相關資料,這里只給出定義:

typedef struct _GUID {????????? // size is 16

??? DWORD Data1;

??? WORD?? Data2;

??? WORD?? Data3;

??? BYTE? Data4[8];

} GUID;

ULONG:訪問標志,cemapi中只支持最優訪問方式,MAPI_BEST_ACCESS

ULONG*:用于返回Message類型

LPUNKNOW *:一個指向IUnKnow或其派生類指針的指針,用于返回派生自IUnknow接口的對象,這里是IMsgStore對象。

OK,相關的內容基本上已經介紹完了,說了很多,估計您已經看的云里霧里了,還是用一段完整程序來給上面的內容做一個總結吧。

IMAPITable *m_pTable? = NULL;???????

HRESULT hr? = 0;

???????? SRowSet *m_pRows? = NULL; ??????

???????? SizedSPropTagArray(2 , Columns) =

???????? {

????????????? 2 ,

????????????? PR_ENTRYID, //

????????????? PR_DISPLAY_NAME //Display Name

???????? };

?

???????? if(NULL==m_pSession)

???????? {

????????????? //異常處理

???????? }

?

???????? hr=m_pSession->GetMsgStoresTable(MAPI_UNICODE , &m_pTable);??? //獲取IMAPITable對象

?

???????? if(FAILED(hr) || NULL==m_pTable)

???????? {

?????????????????? //沒有取到表結構或取表結構時出錯

???????? }

?

???????? hr=m_pTable->SetColumns((LPSPropTagArray)&Columns, 0);? //設置行記錄結構

???????? if(FAILED(hr))

???????? {

????????????? //異常處理

???????? }

?

???????? while(SUCCEEDED(m_pTable->QueryRows(1, 0, &m_pRows)))? //循環遍歷所有行記錄

???????? {

????????????? if (NULL == m_pRows || m_pRows->cRows != 1)

????????????? {

?????????????????? break;

????????????? }

???????? ???? //查找顯示名字為SMS的行記錄

????????????? if (_tcsicmp(m_pRows->aRow[0].lpProps[1].Value.lpszW, _T("SMS")) == 0)

???????? ???? {

?????????????????? ULONG ulMsgType;

?????????????????? //則獲取指向短信倉庫的對象

?????????????????? hr=m_pSession->OpenEntry(m_pRows->aRow[0].lpProps[0].Value.bin.cb,

?????????????????? ? (LPENTRYID)m_pRows->aRow[0].lpProps[0].Value.bin.lpb,

?????????????????? ? NULL,

?????????????????? ? MAPI_BEST_ACCESS,

?????????????????? ? &ulMsgType,

?????????????????? ? (LPUNKNOWN*)&m_pMsgStore);

?????????????????? if(FAILED(hr) || NULL==m_pMsgStore)

?????????????????? {

?????????????????????? //異常處理

?????????????????? }

?????????????????? break;

????????????? }

?

????????????? FreeProws(m_pRows);??? //釋放

???????? ???? m_pRows = NULL;

???????? }

???????? if(m_pRows)??????? //釋放資源

???????? {

????????????? FreeProws(m_pRows);

????????????? m_pRows = NULL;

???? }

?

6.?????? 釋放IMsgStore對象

IMsgStore接口提供了Release方法釋放對象資源,調用方式如下:

if(NULL!=m_pMsgStore)

{

?? m_pMsgStore->Release();

}

7.?????? 與某一具體信箱建立連接,獲取具體信箱接口IMAPIFolder對象

獲取具體信箱IMAPIFolder對象要比獲取IMsgStore對象容易很多,因為在短信倉庫MsgStore下,只有收件箱,發件箱,草稿箱,廢件箱,已發送郵件箱5種具體信箱(Folder),我們可以通過指定要獲取的信箱(Folder)類型來直接獲取指向該具體信箱的IMAPIFolder對象。

首先,依舊需要建立一個動態的SPropTagArray結構體變量,用于告訴短信倉庫IMsgStore對象,我們需要獲取哪一個具體信箱的IMAPIFolder對象,代碼如下:

SizedSPropTagArray(1, Columns) =

???????? {

????????????? 1,

????????????? PR_CE_IPM_INBOX_ENTRYID???? /*表示要獲取指向系統收件箱的IMAPIFolder對象*/

???????? };

???????? 用于表示具體信箱(Folder)的標志:

???????? PR_CE_IPM_INBOX_ENTRYID:系統收件箱

???????? PR_CE_IPM_OUTBOX_ENTRYID:系統發件箱

???????? PR_CE_IPM_DRAFTS_ENTRYID:草稿箱

PR_IPM_SENTMAIL_ENTRYID:已發郵件箱

PR_IPM_WASTEBASKET_ENTRYID):廢件箱

然后我們需要用一個新的方法GetProps來獲取具體信箱(Folder)的屬性信息,其實我們的主要目的是獲取屬性中該具體信箱的EntryID。該方法被定義為:

HRESULT IMsgStore::GetProps(SPropTagArray *,ULONG,ULONG *,SPropTagArray**)

方法返回值標志方法是否執行成功。參數說明:

SPropTagArray * :利用前面動態結構體對象Columns,告訴IMsgStore對象,我需要取哪個具體信箱的屬性。

ULONG:指明當前的編碼方式,MAPI_UNICODE

SPropTagArray**:用于返回從具體信箱中獲取的屬性

???????? ???????? 最后用IMsgStore對象的OpenEntry方法建立獲取指向具體信箱的IMAPIFolder接口對象。該方法的定義與IMAPISession中的同名對象相同,這里不再贅述。

?????? 獲取指向具體信箱的IMAPIFolder接口對象的源程序如下:

???????? HRESULT hr=0;

???????? LPSPropValue stProps? = NULL;

???????? ULONG ulValues?? = 0;

SizedSPropTagArray(1, Columns) =

???????? {

????????????? 1,

????????????? PR_CE_IPM_INBOX_ENTRYID???? /*表示要獲取指向系統收件箱的IMAPIFolder對象*/

???????? };

// 獲取FolderEntry ID,然后通過OpenEntry獲得對象

???????? m_pMsgStore->GetProps((LPSPropTagArray) &Columns, MAPI_UNICODE, &ulValues, &stProps);

????????

???????? hr=m_pMsgStore->OpenEntry(stProps[0].Value.bin.cb, (LPENTRYID)stProps[0].Value.bin.lpb, NULL, MAPI_MODIFY, NULL, (LPUNKNOWN*)&m_pFolder );

?

???????? if(FAILED(hr) || NULL==m_pFolder)

???????? {

????????????? //異常處理

???????? }

???????? MAPIFreeBuffer(stProps);???????? //釋放掉對象

8.?????? 釋放掉Folder對象

If(NULL!=m_pFoder)

{

???? m_pFolder->Release();

}

9.?????? 本節所涉及到的源程序

//獲取IMAPISession會話對象

void Session()

{

IMAPISession *m_pSession=NULL;

???????? hr=MAPILogonEx(NULL,NULL,NULL,NULL,&m_pSession);

???????? if(FAILED(hr) || NULL==m_pSession)

???????? {

????????????? //異常處理

???????? }

?

}

//獲取指向短信倉庫的IMsgStroe接口對象

void MsgStore()

{

IMAPITable *m_pTable? = NULL;???????

HRESULT hr? = 0;

???????? SRowSet *m_pRows? = NULL; ??????

???????? SizedSPropTagArray(2 , Columns) =

???????? {

????????????? 2 ,

????????????? PR_ENTRYID, //

????????????? PR_DISPLAY_NAME //Display Name

???????? };

?

???????? if(NULL==m_pSession)

???????? {

????????????? //異常處理

???????? }

?

???????? hr=m_pSession->GetMsgStoresTable(MAPI_UNICODE , &m_pTable);??? //獲取IMAPITable對象

?

???????? if(FAILED(hr) || NULL==m_pTable)

???????? {

?????????????????? //沒有取到表結構或取表結構時出錯

???????? }

?

???????? hr=m_pTable->SetColumns((LPSPropTagArray)&Columns, 0);? //設置行記錄結構

???????? if(FAILED(hr))

???????? {

????????????? //異常處理

???????? }

?

???????? while(SUCCEEDED(m_pTable->QueryRows(1, 0, &m_pRows)))? //循環遍歷所有行記錄

???????? {

????????????? if (NULL == m_pRows || m_pRows->cRows != 1)

????????????? {

?????????????????? break;

????????????? }

???????? ???? //查找顯示名字為SMS的行記錄

????????????? if (_tcsicmp(m_pRows->aRow[0].lpProps[1].Value.lpszW, _T("SMS")) == 0)

???????? ???? {

?????????????????? ULONG ulMsgType;

?????????????????? //則獲取指向短信倉庫的對象

?????????????????? hr=m_pSession->OpenEntry(m_pRows->aRow[0].lpProps[0].Value.bin.cb,

?????????????????? ? (LPENTRYID)m_pRows->aRow[0].lpProps[0].Value.bin.lpb,

?????????????????? ? NULL,

?????????????????? ? MAPI_BEST_ACCESS,

?????????????????? ? &ulMsgType,

?????????????????? ? (LPUNKNOWN*)&m_pMsgStore);

?????????????????? if(FAILED(hr) || NULL==m_pMsgStore)

?????????????????? {

?????????????????????? //異常處理

?????????????????? }

?????????????????? break;

????????????? }

?

????????????? FreeProws(m_pRows);??? //釋放

???????? ???? m_pRows = NULL;

???????? }

???????? if(m_pRows)??????? //釋放資源

???????? {

????????????? FreeProws(m_pRows);

????????????? m_pRows = NULL;

???? }

?

}

??? //獲取指向具體信箱的IMAPIFolder接口對象

void Folder(ULONG ulType)

???? {

???????? HRESULT hr=0;

???????? LPSPropValue stProps? = NULL;

???????? ULONG ulValues?? = 0;

???????? ULONG ulTags[]?? = { 1, ulType};

?

???? ?// 獲取FolderEntry ID,然后通過OpenEntry獲得對象

???????? m_pMsgStore->GetProps((LPSPropTagArray) ulTags, MAPI_UNICODE, &ulValues, &stProps);

????????

???????? hr=m_pMsgStore->OpenEntry(stProps[0].Value.bin.cb, (LPENTRYID)stProps[0].Value.bin.lpb, NULL, MAPI_MODIFY, NULL, (LPUNKNOWN*)&m_pFolder );

?

???????? if(FAILED(hr) || NULL==m_pFolder)

???????? {

????????????? throw(CMsgException(_T("獲取FOLDER失敗!"),_T("CMsgControl->Folder"),ERR_GET_FOLDER));

???????? }

???????? MAPIFreeBuffer(stProps);???????? //釋放掉對象

}

//釋放掉IMAPISessionIMsgStoreIMAPIFolder對象

void UnInit()

???? {

???????? if(NULL!=m_pSession)??????? //釋放Session

???????? {

????????????? m_pSession->Logoff(NULL,NULL,NULL);

????????????? m_pSession->Release();

????????????? m_pSession=NULL;

???????? }

?

???????? if(NULL!=m_pMsgStore)? //釋放MsgStore

???????? {

????????????? m_pMsgStore->Release();

????????????? m_pMsgStore=NULL;

???????? }

?

???????? if(NULL!=m_pFolder)???????? //釋放Folder

???????? {

????????????? m_pFolder->Release();

????????????? m_pMsgStore=NULL;

???????? }

?}

總結

以上是生活随笔為你收集整理的CEMAPI实战攻略(二)——建立与短信信箱的连接的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。