无聊客的专栏

寻找逝去的岁月

原创 (原创)CE MAPI实例讲解 --- 如何获取Inbox里的所有消息(二)收藏

新一篇: 如何使用PPC Notification (By 无聊客)

 第三步:获取Folder。我们以Drafts为例。
 LPSPropValue rgprops  = NULL;
 ULONG ulValues   = 0;
 //设置我们想拿哪个Folder,详细可以查阅MSDN关于ImsgStore的介绍,在这里我将常用的几个Folder的属性值列一下:
 //PR_CE_IPM_DRAFTS_ENTRYID     drafts,草稿箱
 //PR_CE_IPM_INBOX_ENTRYID  Inbox,收件箱
 //PR_IPM_OUTBOX_ENTRYID  Outbox,发件箱
 //PR_IPM_SENTMAIL_ENTRYID  Sentbox,这个不知道叫什么好,寄件箱?就是已经发送的消息放的box.
 //PR_IPM_WASTEBASKET_ENTRYID  垃圾箱
 ULONG rgTags[]   = { 1, PR_CE_IPM_DRAFTS_ENTRYID}; 

 // 获取Folder的Entry ID,然后通过OpenEntry获得对象
 pMsgStore->GetProps((LPSPropTagArray) rgTags, MAPI_UNICODE, &ulValues, &rgprops);
 pMsgStore->OpenEntry(rgprops[0].Value.bin.cb, (LPENTRYID)rgprops[0].Value.bin.lpb, NULL, MAPI_MODIFY, NULL, (LPUNKNOWN*)pFolder );
 MAPIFreeBuffer(rgprops);
 这样,我就拿到了需要的Folder,接下来还剩下最后一件事情,就是遍历message,其实它的过程和拿Store的过程十分相似。

第四步:获取message。
 LPMAPITABLE  pTable = NULL;
 LPSRowSet pRows = NULL;
 ULONG   ulNumCols = 1;
 //指定我们需要获取Entry ID属性
 SizedSPropTagArray(ulNumCols, Columns) =
 { 
  ulNumCols,
  PR_ENTRYID  
 };

 pFolder->GetContentsTable(0, &pTable);
 hr = pTable->SetColumns((LPSPropTagArray)&Columns, 0);
 //从这些代码可以看出,和获取Message Store的方法很相似,只不过一个是从Session对象里拿,而另一个是从Folder里面拿而已。

 while(SUCCEEDED(pTable->QueryRows(1, 0, &pRows)))
 {
  LPMESSAGE pMsg = NULL;
  ULONG ulMesageType;
  //通过OpenEntry获取IMessage对象
  pFolder->OpenEntry( pRows->aRow[0].lpProps[0].Value.bin.cb,
     (LPENTRYID)pRows->aRow[0].lpProps[0].Value.bin.lpb,
     NULL,
     MAPI_BEST_ACCESS,
     &ulMesageType,
     (LPUNKNOWN*)&pMsg);
  //这里拿到每个IMessage对象就代表了Folder里面的每一条Message,可以通过对它的操作来获取想要的信息。
  ......
  //不需要时记的释放
  pMsg->Release();
  FreeProws(pRows);
  pRows = NULL;
 }
 if(pRows)
 { 
  FreeProws(pRows);
 }
 if(pTable)
 {
  pTable->Release();
 }

终于完工了,第一次写,不知道讲的清楚不,如有不对的地方,欢迎大家指正。

     无聊客
   2005.8.11
yzx0023@gmail.com

发表于 @ 2005年08月11日 21:58:00|评论(loading...)|编辑

旧一篇: (原创)CE MAPI实例讲解 --- 如何获取Inbox里的所有消息(一)

评论

#flypeng 发表于2006-03-30 09:45:00  IP: 221.232.155.*
你好,请问:在第三步中是不是遗漏了些变量,比如IMAPIFolder类型的变量,用于第三步中的pMsgStore->OpenEntry(...)函数,返回指向所需的文件夹,而且好象作者在这个函数中遗漏些参数吧?请作者赐教!
#flypeng 发表于2006-03-30 10:02:00  IP: 221.232.155.*
你好,我实在是水平有限,能否请你解释一下第四步中ePR_ENTRYID这个变量的含义?非常感谢,期待你的尽快回复?谢谢..
#flypeng 发表于2006-03-29 22:30:00  IP: 61.183.207.*
这么好的两篇实例让我明白了以前不明白的东西,好象MSDN上讲的都没有这么清楚,谢谢作者的辛勤工作,期待这方面更多的作品.
#yzx0023 发表于2006-04-04 17:07:00  IP: 218.108.41.*
谢谢,好象是粘贴的时候漏掉了,现在补上:
pMsgStore->OpenEntry(rgprops[0].Value.bin.cb, (LPENTRYID)rgprops[0].Value.bin.lpb, NULL, MAPI_MODIFY, NULL, (LPUNKNOWN*)pFolder );
#yzx0023 发表于2006-04-04 17:11:00  IP: 218.108.41.*
关于ePR_ENTRYID是搬代码的时候的笔误,在这里应该就是0,因为获取的是一个属性列表,第1个(也就是序号0)的才是我们需要的
#hzqq 发表于2006-07-02 00:11:00  IP: 221.137.24.*
为什么我在 pMsgStore->OpenEntry(rgprops[0].Value.bin.cb, (LPENTRYID)rgprops[0].Value.bin.lpb, NULL, MAPI_MODIFY, NULL, (LPUNKNOWN*)pFolder );
的时候,得到HRESULT是E_INVALIDARG?
#yzx0023 发表于2006-07-02 00:57:00  IP: 60.176.52.*
rgprops[0].Value.bin值看一下看,确认是否已经获取了正确的Folder Entry ID
#hzqq 发表于2006-07-02 23:35:00  IP: 221.137.24.*
bin.cb=20
bin.lpb = 0x00296200
这个算不算得到了正确的Folder EntryID?
我觉得看上去好像是对的
#yzx0023 发表于2006-07-03 08:52:00  IP: 218.108.41.*
E_INVALIDARG是参数不对,你传的参数肯定有不对的地方,pFolder你的声明是什么?IMAPIFolder* pFolder = NULL?如果是这样的话,请注意这里的类型是LPUNKNOWN*,调用应该改为pMsgStore->OpenEntry(rgprops[0].Value.bin.cb, (LPENTRYID)rgprops[0].Value.bin.lpb, NULL, MAPI_MODIFY, NULL, (LPUNKNOWN*)&pFolder );
#ALLEN 发表于2006-08-09 13:40:00  IP: 211.160.176.*
LPCTSTR CVOMAPIMessage::GetBody()
{
IStream* pStream;
char szBuf[255];
ULONG ulNumChars;
CString strBody="";
HRESULT hr;

hr = m_pMessage->OpenProperty( PR_BODY, &IID_IStream, STGM_READ, NULL,
(LPUNKNOWN*) &pStream);
EXIT_ON_FAILED(hr);

do
{
pStream->Read(szBuf, 255, &ulNumChars);
if (ulNumChars >0)
{
static CString strBodyPart="";

memmove(strBodyPart.GetBuffer(ulNumChars), szBuf, ulNumChars);
strBodyPart.ReleaseBuffer(ulNumChars);

strBody += strBodyPart;
}
} while (ulNumChars >= 255);

MAPIAllocateBuffer(sizeof(SBinary) + (sizeof(TCHAR) * (strBody.GetLength() + 1)), (LPVOID*)&m_propBody );
m_propBody->dwAlignPad = 0;
m_propBody->ulPropTag = PR_BODY;

m_propBody->Value.lpszW = (LPTSTR)(m_propBody + 1); // Set to byte immediately after structure header

_tcscpy(m_propBody->Value.lpszW, strBody);

return m_propBody->Value.lpszW;

FuncExit:
return TEXT("");
}

无聊客兄弟,请帮我看看这段程序,为什么我跟踪他读取的字符串会在本来正确的内容后面多出一些多余的内容啊?
#yzx0023 发表于2006-08-10 12:53:00  IP: 218.108.41.*
To ALLEN:我已经回你EMAIL了,请检查。
#ALLEN 发表于2006-08-13 10:38:00  IP: 211.160.176.*
谢谢,我已经解决问题了。加了一句
memset(),将字符串在被使用之前置为'\0'
#ALLEN 发表于2006-08-15 14:03:00  IP: 211.160.176.*
问题已经解决了
增加一条语句
memset((char*)strBodyPart.GetBuffe(ulNumChars+2),'\0',ulNumChars+2);
#yzx0023 发表于2006-08-30 22:07:00  IP: 60.176.242.*
To mellonyou:关于如何获取收件人,请参考第六篇内容:CE MAPI实例讲解 --- 如何获取收件人信息(六)
#mellonyou 发表于2006-08-30 21:20:00  IP: 124.91.20.*
请问无聊客,我要取得SMS的接受者,
res = pmessage->GetProps((LPSPropTagArray)receivernameprop,MAPI_UNICODE,&val,&receivernamepropval);这行代码可以吗?receivernameprop该怎么定义?
#mellonyou 发表于2006-08-31 20:35:00  IP: 124.91.20.*
谢谢你给我回答,我看了CE MAPI实例讲解 --- 如何获取收件人信息(六),但是我要获取的是某一封特定邮件的收件人,现在我已经可以取到某一封邮件的发件人,标题等信息,但就是不知怎么取得收件人信息,望回答,谢谢。
#yzx0023 发表于2006-09-01 18:23:00  IP: 218.108.41.*
To mellonyou:不是很明白你的意思,邮件的收件人可以按照第六篇里面的介绍取的,你是指不能取的特定的邮件?
#mellonyou 发表于2006-09-06 14:45:00  IP: 124.91.16.*
无聊客,你好。前两天的问题,看了你的帖已经解决了。现在又遇到了新的问题,希望得到你的指导。就是我在查找到一封邮件之后,希望通过点击一个按钮来打开这封邮件。望恢复,谢谢。
#yzx0023 发表于2006-09-06 22:18:00  IP: 60.176.252.*
to mellonyou:希望通过点击一个按钮来打开这封邮件
====================================
如果是WM5,想编辑调用MailComposeMessage,想播放调用MailDisplayMessage

在EVC4.0种正常运行,但是到了VS2005中,就出错了
============================
这个很难说,错误类型是什么?是取什么类型message的body?
#mellonyou 发表于2006-09-06 22:29:00  IP: 124.91.16.*
MailDisplayMessage
只能在WM5中用,那2003种有打开的方法吗?
#mellonyou 发表于2006-09-06 22:42:00  IP: 124.91.16.*
是要取得邮件的Body,通过res = psession->OpenEntry( msgset->aRow[0].lpProps[0].Value.bin.cb,
(ENTRYID*)msgset->aRow[0].lpProps[0].Value.bin.lpb,
NULL, MAPI_BEST_ACCESS, &ulObjType,
(LPUNKNOWN*) &pmessage);取得pmessage,
res = pmailmessage->GetProps((LPSPropTagArray) &subjectprop, MAPI_UNICODE,&val, &subjectpropval);
这行可以正确取得Subject,res 返回S_OK,但是res = pmailmessage->OpenProperty( PR_BODY, &IID_IStream, STGM_READ, NULL, (LPUNKNOWN*) &pStream);执行后就有问题,res 返回-2147221233,
编译没有问题,在执行这行后,
错误信息:CXX0004:Error:syntax error
#mellonyou 发表于2006-09-06 20:33:00  IP: 124.91.16.*
res = pmessage->OpenProperty( PR_BODY, &IID_IStream, STGM_READ, NULL, (LPUNKNOWN*) &pStream);

无聊客,又来请教。我用上面的代码,在EVC4.0种正常运行,但是到了VS2005中,就出错了,res取不到值。急用,望回复,再次谢过。
#actionman 发表于2006-09-07 15:36:00  IP: 61.151.255.*
hi, 无聊客,
如何用自己的代码(就像用上述代码读取sms)写sms, 并存到sms/inbox?,
#actionman 发表于2006-09-07 16:59:00  IP: 61.151.255.*
我知道了, 用sendmail这个例子就好了, 是吧!
#yzx0023 发表于2006-09-08 11:52:00  IP: 218.108.41.*
To actionman:Sendmail会把消息放到Outbox,并且等待发送,你想放到Inbox的话,你可以借鉴它的前一部分,创建Message再移到Inbox,或者直接在Inbox创建新的message
#yzx0023 发表于2006-09-08 11:53:00  IP: 218.108.41.*
to mellonyou:03上还不知道用什么方法display,新建界面倒可以用命令行方式调用。
#actionman 发表于2006-09-08 16:39:00  IP: 61.151.255.*
我在研究Transportdemo, 能够创建自己的账号, 也能存储, 在把邮件存到Outbox时, 系统如何发送,

我知道用IMAPIAdviseSink可以实现邮件的发送通知。也阅读了你的几篇文章。通过注册, 在移动/删除, 邮件时都能得到通知, 是不是只要在notify函数根据不同的event, 来做不同的动作就可以了。里边的event有些不大明白
#yzx0023 发表于2006-09-08 19:22:00  IP: 60.176.54.*
to actionman: 是的
#money 发表于2006-09-10 21:34:00  IP: 61.151.255.*
Hi ,无聊客:
我在研究CustomForm, 想仿照SMS做一个MMS的Composer,修改 CMsgView::CreateMainWindow(),想在编辑画面加入tool buttons, 但却调用SHCreateMenuBar()不成功,总是显示defalut menu ,好像无法create一个带有Command Bar 的window,不知道怎么回事,能否指点一下?
Thanks!
#yzx0023 发表于2006-09-10 23:28:00  IP: 220.191.113.*
To money:SHCreateMenuBar返回错误值是什么?据我所知,应该是可以的。
#money 发表于2006-09-11 09:37:00  IP: 61.151.255.*
To yzx0023:

SHCreateMenuBar 返回FALSE , 通过GetLastError()获得的信息是“This function is only valid in Win32 mode”, 在别的地方这个函数调用都是可以的,device 是 WM5.0 PPC. code 如下:
SHMENUBARINFO mbi;

memset(&mbi, 0, sizeof(SHMENUBARINFO));
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = hWnd;
mbi.nToolBarId = IDR_MENU;
mbi.hInstRes = g_hInstance;


if (!SHCreateMenuBar(&mbi))
{
g_hWndMenuBar = NULL;
}
else
{
g_hWndMenuBar = mbi.hwndMB;
}
执行的时候走到了g_hWndMenuBar = NULL;然后调用GetLastError得到如上错误信息.
编辑窗口带有自己的Command Bar应该是可以的,因为我见Dopod 的机器上虹軟科技的 (arcsoft)mms composer
编辑画面是可以在Commmand Bar上面加Tool buttons的,并且Menu也不是inbox里面的default menu. 我这里编辑画面却和SMS 和Outlook里一样,虽然可以改Menu,但却没办法加Tool Buttons.我的做法是选择New,直接进入MMS编辑画面,他们的做法是进入一个模板选择画面,然后进入编辑画面,而我只是省去了进入模板选择,直接进入了编辑。
Thanks a lot!
#yzx0023 发表于2006-09-11 21:30:00  IP: 60.176.250.*
To money:
试试看:
SHMENUBARINFO mbi;
memset(&mbi, 0, sizeof(SHMENUBARINFO));
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = hParent;
mbi.nToolBarId = nYourMenuId;
mbi.hInstRes = hResInst;
mbi.dwFlags = SHCMBF_HMENU;
SHCreateMenuBar(&mbi);
#yzx0023 发表于2006-09-12 11:27:00  IP: 218.108.41.*
To money:呵呵,兄弟,我就是这么做的,可以的啊,不过我不是按照CustomFom做的,我是自己新建窗口干活的
#money 发表于2006-09-12 10:48:00  IP: 61.151.255.*
这个我已经试过了,没有什么区别的,我怀疑人家可能不是采用的这个做法。如果有谁做过这样的尝试,解决了这个问题,烦请告知!本人QQ: 707285797.
Thanks for your help!

#money 发表于2006-09-12 15:56:00  IP: 61.151.255.*
呀,不会吧! 那你整个架构应该是和CustomForm一样的吧,编辑的时候调用到CreateComposeForm(), 最后调用CreateMainWindow(),再自己新建窗口干活,我现在是这样做的,就出现了这个问题。能否大致介绍一下您的实现方式?
Thanks!
#money 发表于2006-09-13 09:32:00  IP: 61.151.255.*
我发现SHCreateMenuBar(&mbi)调用失败的原因了,怀疑是由于mbi.hInstRes = g_hInstance; 引起的。由于g_hInstance是在LibMain()中赋值的,而LibMain()在调用时没有走到,g_hInstance一直是NULL,所以调用SHCreateMenuBar()会失败。但我却没有办法得到g_hInstance的值,不知如何才能得到这个值?
Thanks!
#yzx0023 发表于2006-09-13 22:38:00  IP: 60.176.240.*
To money:mbi.hInstRes 应该是你的Menu所在库的Instance,应该可以在DllMain里面取的
#money 发表于2006-09-14 18:58:00  IP: 61.151.255.*
我换到TV_Inbox中, DllMain可以走到,SHCreateMenuBar()可以用了。但还有一个问题没有找到办法:就是在
CFormProvider::CreateComposeForm(
IMessageFormHostEx* pHost,
LPMESSAGE pMsg, // Object to compose
FORMTYPE eFormType, // Reply, Reply All, Forward
LPMESSAGE pMsgBase, // Message to prefill the form if necessary
MESSAGEFIELDS* pMsgFields, // message fields for the new message
HWND hwndForm, // HWND of the form frame
HWND* phwndBody, // HWND of the form-created body
IMessageFormEx** ppForm // Form object
)

中, hwndForm就是编辑窗口的句柄,调用这个函数前,编辑窗口已经生成了,只需要再生成窗体即phwndBody就OK了。但是如果自己生成编辑窗口的话,会有两个编辑窗口,我现在把新生成的编辑窗口句柄赋给phwndBody,编辑完成按OK时,关掉hwndForm。但这却是在子窗口中关掉了父窗口。并且这样做虽然可以工作,却不是正确的做法。不知能否请您给点建议?还有一个问题,当按窗口右上角OK时,会给窗口发一个WM_COMMAND消息,如何区分这个消息,是哪个event事件,我从MSDN上没有查到。Thanks!
#yzx0023 发表于2006-09-18 09:13:00  IP: 218.108.41.*
To money:不存在子窗口关父窗口的问题,因为那个OK BUTTON本来就是系统hwndForm的,所以一点hwndForm就关了,如果这个BUTTON是子窗口的,没做特殊响应的话,即使子窗口关闭了,也不会导致hwndForm被关掉。至于如何区分这个消息,我不是很明白你的意思,一般hwndForm被关掉,会调用IMessageFormEx::CloseForm,通知Form释放
#almond 发表于2006-09-21 14:17:00  IP: 219.133.76.*


无聊客, 你可以把它写成 .lib or .dll 让兄弟们分享一下可以吗?

#actionman 发表于2006-09-26 11:26:00  IP: 61.151.255.*
to 无聊客
如何得到 某一条消息/邮件的UID, 我用PR_CE_IMAP_UID属性, 但还是不行, 为何?
#actionman 发表于2006-09-26 13:09:00  IP: 61.151.255.*
to 无聊客

如何得到消息/邮件的 UID, 我用PR_CE_IMAP_UID属性, 但是不能得到, 很奇怪!
#yzx0023 发表于2006-09-27 16:28:00  IP: 218.108.41.*
To actionman: UID是个什么概念?不是很明白,但是你可以试试用AdviseSink去监控一下属性的改变,凡是系统修改的属性你都可以看到。
#actionman 发表于2006-09-28 08:22:00  IP: 61.151.255.*
to yzx0023

UID 是邮件/消息的唯一标识符。 用PR_CE_IMAP_UID但是得不到
#simon 发表于2006-10-28 17:01:00  IP: 124.91.8.*
我把代码扩展到了读短信的任何文件夹(写了一个类,用FindFirstSMS()和FindNextSMS()来读所有的短信,当读取短信(发件人为空时会出错))
如:
SizedSPropTagArray(1, sptaEmail) = { 1, PR_SENDER_EMAIL_ADDRESS};
ULONG cValues = 0;
SPropValue *pspvEmail = NULL;
hr = m_pMsg->GetProps((SPropTagArray *) &sptaEmail, MAPI_UNICODE, &cValues, &pspvEmail);
if (FAILED(hr))
{
goto EndFindNextSMS;
}
lstrcpy(lpPhone, pspvEmail->Value.lpszW);

当短信没有发件人时,pspvEmail->Value.lpszW这个字符串(乱码)好像很长。所以一直停在lstrcpy(lpPhone, pspvEmail->Value.lpszW);,执行不下去了。

我想问一下,有没有方法判断一个短信的发件人是否为空。
#yzx0023 发表于2006-10-30 21:09:00  IP: 60.176.212.*
To simon:请注意判断pspvEmail->ulPropTag的值,即使GetProps返回调用成功,可能拿到属性也为无效,这是因为GetProps支持获取多个属性,不会因为单个属性获取是否成功而导致整个调用失败。你可以加上以下判断:
if(FAILED(hr)) || PT_ERROR == pspvEmail->ulPropTag)

{
goto EndFindNextSMS;
}
或者更好的办法是每个获取属性的ulPropTag都和传入的SPropTagArray的tag值做比较
#siomon 发表于2006-10-30 21:31:00  IP: 124.91.8.*
To yzx0023: 非常感谢.
我最近在做短信方面的开发,你的文章给了我很大的帮助。
后来我换了种方法,就是看短信是收到的还是自己写的。
SizedSPropTagArray(1, sptaFlag) = { 1, PR_MESSAGE_FLAGS };
SPropValue *pspvFlag = NULL;
hr = m_pMsg->GetProps((SPropTagArray *) &sptaFlag, MAPI_UNICODE, &cValues, &pspvFlag);
判断这个值pspvFlag->Value.l(0或1表示收到的),其他的表示自己编辑的短信。
我用这个值来判断(如果pspvFlag->Value.l > 1,就不读了).
绕弯了。

你开发Windows Mobile有多久了?我刚开发了半年的时间,
希望有时间多交流。
#xyz666 发表于2007-03-15 14:24:29  IP: 218.4.63.*
无聊客大哥,你好啊,看过你写的文章,很是感谢.现在我的问题是能否得到收到短信的时间,是否有像以下的一个属性得到短信的内容来得到每条短信的接收到的时间?
SPropValue *pspvSubject = NULL;
SizedSPropTagArray(1, sptaSubject) = { 1, PR_SUBJECT};
pMsg->GetProps((SPropTagArray *) &sptaSubject,
MAPI_UNICODE,&cValues,&pspvSubject);
我找了好几个属性都没找到,希望能得到你的帮忙.谢谢!
2007-03-16 18:58:37作者回复
你可以在mapitags.h里面找一下和TIME相关的属性,所有属性都已经列在了这个头文件里面
#matrixcl 发表于2007-05-23 11:00:06  IP: 124.42.2.*
请教一下无聊客:
我需要读收件箱中短信的联系人号码,标志位使用PR_SENDER_EMAIL_ADDRESS。
发件人号码没有存在手机上是,可以取到。 否则会取到类似这样的串 "h55e i9# <+8613400000000>
内容大概是姓名+号码

请问怎么才能取到正确的号码? 谢谢
#wm 发表于2007-06-11 19:37:26  IP: 222.128.58.*
为什么我读草稿箱的时侯,提示错误

异常代码:0xc0000005
异常地址:0x30000028
读取:0x01000028
#yzx0023 发表于2007-06-11 21:42:43  IP: 60.186.2.*
To wm:你的代码哪里写的不对,一般来说内存问题,请帖上主要代码,或者将代码发至我的EMAIL,有空帮你看看。
#yzx0023 发表于2007-06-11 21:44:17  IP: 60.186.2.*
To matrixcl:抱歉,忘记给你回复了,我最近也遇到类似的问题,似乎系统MAPI对于收到的MESSAGE就会做如此的处理,其他字段我也没找到,目前看来只有parse它了。
#qinye2829 发表于2007-06-12 11:41:01  IP: 222.128.58.*
代码都是我直接粘过去的,我就是想知道,下面。。。。。。。。。。。。省略的部分应该怎么写,也就是怎么来读取草稿箱的subject。我自己加上了
LPSPropValue pProp = NULL;
ULONG ulPropCount = NULL;
ULONG p[2]={1,PR_SUBJECT};
m_pMessage->GetProps((LPSPropTagArray)&p, MAPI_UNICODE, &ulPropCount, &pProp);

但是执行这句话的时候就报
异常代码:0xc0000005
异常地址:0x30000028
读取:0x01000028



下面是部分代码:

pFolder->OpenEntry( pRows2->aRow[0].lpProps[0].Value.bin.cb,
(LPENTRYID)pRows2->aRow[0].lpProps[0].Value.bin.lpb,
NULL,
MAPI_BEST_ACCESS,
&ulMesageType,
(LPUNKNOWN*)&pMsg);
//这里拿到每个IMessage对象就代表了Folder里面的每一条Message,可以通过对它的操作来获取想要的信息。


。。。。。。。。。。。。。。。。。。。。。。。


//不需要时记的释放

RELEASE(pMsg);
FreeProws(pRows2);
pRows2 = NULL;
#yzx0023 发表于2007-06-12 17:17:17  IP: 218.108.41.*
To qinye2829:问题应该出在m_pMessage上面,是不是该变量是无效的?
#yzx0023 发表于2007-06-12 17:18:12  IP: 218.108.41.*
或者在用之前已经被release掉了
#qinye2829 发表于2007-06-12 18:28:03  IP: 222.128.58.*
我刚才找了一下,找到了下面这句话
if(pFolder->GetProps((SPropTagArray *)&subject, MAPI_UNICODE, &ulPropCount, &pProp)==S_OK){
LPCTSTR m_strSubject = (LPCTSTR) pProp->Value.LPSZ;
MAPIFreeBuffer(pProp);
}

当我给 m_strSubject赋值的时候,又出现了:
异常代码:0x80000002
异常地址:0x03fa7070

是类型转换的问题吗?
#qinye2829 发表于2007-06-12 18:42:06  IP: 222.128.58.*
怎么才能取得到呢?老出现一些奇奇怪怪的问题。
#qinye2829 发表于2007-06-12 18:47:37  IP: 222.128.58.*
而且这个 pProp->Value.LPSZ 我试过另外其他类型,还是报同样的错误。
比如:
pProp->Value.lpszW

这个是什么原因?不能付给LPCTSTR类型的变量吗?请执教。
#qinye2829 发表于2007-06-13 14:55:46  IP: 222.128.58.*
无聊客大哥,我的问题什么时候帮我解决?困扰我好久了。加我msn吧,帮我看看程序。谢谢啦!
qinye2829@hotmail.com
#yzx0023 发表于2007-06-13 15:54:42  IP: 218.108.41.*
To qinye2829:从代码上看有严重问题:
LPCTSTR m_strSubject = (LPCTSTR) pProp->Value.LPSZ;
MAPIFreeBuffer(pProp);
你只是把pProp->Value.LPSZ的内存地址传给了临时变量m_strSubject,当MAPIFreeBuffer(pProp);调用以后,这块内存已经被释放,再去用时肯定会出问题。况且m_strSubject在这里是局部的临时变量,出了括号已经生命期结束,其他地方再用肯定也有问题,所以建议你先找身边的人详细check代码,感觉不是MAPI使用上的问题
#qinye2829 发表于2007-06-13 20:23:49  IP: 222.128.58.*
谢谢大哥。搞定了。哈哈
#dao21hao 发表于2007-09-06 20:54:05  IP: 124.91.20.*
请问一下,按照片上面的步骤,获得了短信对象IMessage后,想要删除这条短信应怎么设置DeleteMessages()的参数呢?
#yzx0023 发表于2007-09-07 09:01:56  IP: 218.108.85.*
To dao21hao:通过拿IMessage::GetProps拿PR_ENTRYID属性的值,获取EntryID,然后传给 IMAPIFolder::DeleteMessages进行删除
#zhangyq73 发表于2007-09-12 10:50:51  IP: 221.221.13.*
在读取短信的时候,出现异常,提示说访问内存违规.出现在读完短信以后,读完以后,while中的循环条件依然满足,是不是必须加异常处理呢?
#zhangyq73 发表于2007-09-12 15:30:48  IP: 221.221.13.*
在同事的帮助下,已解决,问题是是while的循环条件有问题,导致无限循环.
#dang800919 发表于2007-09-25 15:23:54  IP: 219.143.46.*
如何 建立一个 能和 收件箱 还有垃圾箱等 系统内制的 文件夹 的文件夹啊~~~
是不是应该有个宏 或者在哪一步需要做更改啊?
谢谢
#dang800919 发表于2007-09-25 15:50:26  IP: 219.143.46.*
如何 建立一个 能和 收件箱 还有垃圾箱等 系统内制的 文件夹 平级 的文件夹啊~~~
是不是应该有个宏 或者在哪一步需要做更改啊?
谢谢
#yzx0023 发表于2007-10-10 23:09:42  IP: 125.119.98.*
to dang800919: 用PR_IPM_SUBTREE_ENTRYID获取folder,再创建就行了
#zzq_gates 发表于2007-10-16 17:21:37  IP: 219.143.95.*
你好,我现在可以建新的文件夹,比如我和收件箱平级的建一个叫“临时”的文件夹,可是我现在第一:删除不了这个文件夹,第二,不知道怎么给这个文件夹下面写短信?无聊兄,帮兄弟一把了
#zzq_gates 发表于2007-10-17 14:12:51  IP: 219.143.81.*
我是用PR_IPM_SUBTREE_ENTRYID建地文件夹,现在我在收件箱中也可以建了,可是我就是无法列举到这些文件夹?你能告诉我怎么列举到自己建的文件夹吗?msdn我看了,没有找到,无聊兄,这个问题急,谢谢你的帮组了
#小破孩 发表于2007-11-21 14:29:32  IP: 218.241.130.*
我的SDK里没有PR_CE_IPM_INBOX_ENTRYID的定义,无法打开收件箱,那位兄弟指点一下,烦请给我email
#wolf 发表于2007-11-25 19:08:02  IP: 58.48.63.*
你好,请问:在第三步中是不是遗漏了些变量,比如IMAPIFolder类型的变量,另外,请问你的pFolder定义的是什么类型的变量呢,我的程序在第四步的
//通过OpenEntry获取IMessage对象
pFolder->OpenEntry( pRows->aRow[0].lpProps[0].Value.bin.cb,
(LPENTRYID)pRows->aRow[0].lpProps[0].Value.bin.lpb,
NULL,
MAPI_BEST_ACCESS,
&ulMesageType,
(LPUNKNOWN*)&pMsg);
这里总是莫名其妙的结束了,请问是什么原因,谢谢!
#lbjfeng 发表于2007-12-04 16:26:15  IP: 202.118.2.*
无聊兄,在第三步获取文件夹的时候
// 获取Folder的Entry ID,然后通过OpenEntry获得对象
pMsgStore->GetProps((LPSPropTagArray) rgTags, MAPI_UNICODE, &ulValues, &rgprops);
pMsgStore->OpenEntry(rgprops[0].Value.bin.cb, (LPENTRYID)rgprops[0].Value.bin.lpb, NULL, MAPI_MODIFY, NULL, (LPUNKNOWN*)pFolder );
MAPIFreeBuffer(rgprops);
这里OpenEntry以后,pFolder老是为空,为什么啊~着急啊。看了好久还不明白~
谢谢无聊兄了。如果看了以后,可以发送到我邮箱一下么~我的是liubf@neusoft.com
#lbjfeng 发表于2007-12-04 19:07:50  IP: 202.118.2.*
明白了。
无聊兄,第三步OpenEnity最后的一个参数少了一个&
看了好久才明白~
#Ada_wangxuan 发表于2007-12-24 15:08:26  IP: 58.240.78.*
请问一下,在执行pFolder->GetContentsTable(NULL, &pTable);这一句时会弹出对话框说"没有可用于当前位置的源代码",是什么原因?
#King 发表于2007-12-26 14:15:05  IP: 218.108.52.*
纯粹学习~~刚刚开始~~
#yzx0023 发表于2008-01-14 16:30:48  IP: 218.108.85.*
To Ada_wangxuan:你是在调试吧?应该是你的本地代码和目标设备上的文件不符合造成的,重新上传一下就可以了,和代码本身没什么关系。
#Ada_wangxuan 发表于2008-01-15 11:26:41  IP: 58.240.78.*
谢谢你。后来发现是收件箱中没有短信且程序中也没加上错误检查造成的。我在
hr=Folder->OpenEntry(pRows->aRow[0].lpProps[0].Value.bin.cb, (LPENTRYID)pRows->aRow[0].lpProps[0].Value.bin.lpb,
NULL,
MAPI_BEST_ACCESS,
&ulMessageType,
(LPUNKNOWN*)&pMsg);
这句之前加上了这样的出错处理:
if (NULL == pRows->aRow[0].lpProps)
{
return 0;
}
就不出错了。
#Ada_wangxuan 发表于2008-01-15 13:06:45  IP: 58.240.78.*
大侠,我现在又有个问题,就是用IMAPIFolder::DeleteMessages 删除某一条短信时如何知道我要删除的是哪条短信?我看了这个函数的第一个参数是一个ENTRYLIST的指针,这个就是用来标识消息的ID的吧?但是ENTRYLIST里没有一个地方放ENTRYID这个结构的啊?我该怎么构造这个参数呢?

我的程序是这样写的:
SBinary sbinary = {currentSMS.cb,currentSMS.lpb};
ULONG cValues =1;
SBinary FAR* lpbin = &sbinary;
SBinaryArray sBinaryArray = {cValues,lpbin};
hr = pFolder->DeleteMessages(&sBinaryArray, NULL, NULL, 0);
if (FAILED(hr))
{
return;
}

currentSMS是我构造的一个放当前要删除的消息的数组,里面有这两个数据:
ULONG cb;
LPBYTE lpb;
是在读取时赋值的。

这样做没能把消息删除,请问是什么原因啊?

我是个mobile的初学者,希望大侠多多指点!先谢谢啦!
#Ada_wangxuan 发表于2008-01-15 14:56:37  IP: 58.240.78.*
错误代码是0x8004010f
#Ada_wangxuan 发表于2008-01-22 11:18:49  IP: 58.240.78.*
今天终于改成功了,原因是上面程序的
SBinary sbinary = {currentSMS.cb,currentSMS.lpb};
这一句的值有问题,当时给currentSMS.cb,currentSMS.lpb这两个变量赋值时赋错了。下面是我改过的读取短信属性的程序段:
......

while (SUCCEEDED(pTable->QueryRows(1,0,&pRows)))
{
IMessage *pMsg = NULL;
ULONG ulMessageType = 0L;
//通过OpenEntry获取IMessage对象
if (NULL == pRows->aRow[0].lpProps)
{
return 0;
}
hr = pFolder->OpenEntry(pRows->aRow[0].lpProps[0].Value.bin.cb,
(LPENTRYID)pRows->aRow[0].lpProps[0].Value.bin.lpb,
NULL,
MAPI_BEST_ACCESS,
&ulMessageType,
(LPUNKNOWN*)&pMsg);
if(hr != S_OK)
{
MessageBox(_T("d0 error"));
return 0;
}

//Begin Read Message
ULONG tagMsg[] = {1, PR_ENTRYID};
ULONG cMsgPropCount = 0;

// Get the message's properties.
hr = pMsg->GetProps((LPSPropTagArray)tagMsg, MAPI_UNICODE, &cMsgPropCount, &pPropMsg);

// Access the properties.
if (SUCCEEDED(hr))
{
if (pPropMsg[0].ulPropTag == PR_ENTRYID)
{
smsMessages[i].cb = pPropMsg[0].Value.bin.cb;
smsMessages[i].lpb = pPropMsg[0].Value.bin.lpb;
}
i++;
}

//End Read Message
//释放
pMsg->Release();
FreeProws(pRows);
pRows = NULL;
}
......

这样是可以正确删除了,但不知我的程序写的有没有问题,请大侠指点!谢谢!
#新手 发表于2008-03-10 19:40:59  IP: 220.128.63.*
請問 取出的SMS要如何分辨是存在手機上,還是SIM card 上呢
#新手 发表于2008-03-11 16:25:31  IP: 220.128.63.*
請問無聊客:
我目前遇到一個問題,就是透過這方式把SMS抓取出來,

我發現,儲存在SIM Card上的SMS也會被抓取出,

但是我希望不要抓到SIM Card上的資訊,只想要讀取Phone上的SMS

不知道,有沒有什麼tag 或是屬性 可以判別呢

謝謝你
#z 发表于2008-05-12 21:07:18  IP: 218.81.122.*
请问Ada_wangxuan ,我在使用DeleteMessages删除短信时,总是说“试图访问不存在的令牌(token)”。请问,你在使用该函数前,是怎样设置参数的?谢谢!
#kernet 发表于2008-06-27 11:30:35  IP: 220.178.1.*
看了老兄读SMS的文章,感觉很有收获,那么读MMS和SMS有什么不同,应该怎么去做呢?
发表评论  


登录
Csdn Blog version 3.1a
Copyright © 无聊客