本文的目的是向开发者展示如何通过扩展MAPI(Extended MAPI)增强他们的应用程序。为了使应用程序能够运行,需要下载并安装一个免费的组件,即.NET的MAPI存储访问器(MAPI Store Accessor for .NET)。
MAPI存储访问器是一个.NET组件,它允许订阅诸如OnNewMail
、OnObjectChanged
、OnObjectCopied
等事件。它还允许访问MAPI存储、文件夹、项目和附件。将看到,使用MAPI存储访问器有效地隐藏了MAPI的复杂性。
目前,.NET的MAPI存储访问器支持:
在AddinExpress.MAPI库中,基本类包括:
Store
- 表示配置文件中的一个存储Folder
- 表示存储中的一个文件夹MapiItem
- 表示文件夹中的一个项目HiddenItem
- 表示文件夹中的一个隐藏项目Attachment
- 表示一个附件还有相应的集合,如Stores
、Folders
等。要开始使用这些类,应该在组件连接到MAPI子系统时,从组件获取存储的集合。
要开始使用MAPI存储访问器,请在工具箱窗口中找到它,并将其拖放到Windows表单上,或者在代码中手动声明该组件。
应该做的两件事:
Initialize
LogOff
它们类似于开始和停止命令。当调用带有布尔参数的Initialize
时,组件连接到默认配置文件。应用程序根据传递给方法的值创建或连接到现有的MAPI会话。如果想创建一个新的会话,请传递True
。如果需要连接到现有的会话,请传递False
。当传递False
时,请确保会话存在。Initialize
方法的另一个重载接受配置文件名称和密码。
在适当的地方添加Initialize
和LogOff
。在表单的Load
和FormClosing
事件处理程序中分别这样做。
在VB.NET中,可以这样编写代码:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' 初始化组件
AdxmapiStoreAccessor1.Initialize(True)
' 其他任务
Dim folders As Folders = AdxmapiStoreAccessor1.MsgStores(0).RootFolder.Folders(1).Folders
Dim folder As Folder
For Each folder In folders
Dim folderName As Object = folder.GetProperty(ADXMAPIPropertyTag._PR_DISPLAY_NAME)
If folderName IsNot Nothing Then
ipmTreeView.Nodes.Add(folderName.ToString())
End If
Next
End Sub
Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
AdxmapiStoreAccessor1.LogOff()
End Sub
在C#中,可以这样编写代码:
private void Form1_Load(object sender, EventArgs e)
{
// 初始化组件
adxmapiStoreAccessor1.Initialize(true);
// 其他任务
foreach (Folder folder in adxmapiStoreAccessor1.MsgStores[0].RootFolder.Folders[1].Folders)
{
object folderName = folder.GetProperty(ADXMAPIPropertyTag._PR_DISPLAY_NAME);
if (folderName != null)
{
ipmTreeView.Nodes.Add(folderName.ToString());
}
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
adxmapiStoreAccessor1.LogOff();
}
现在,准备向应用程序添加业务逻辑。需要一个TreeView
和一个ListBox
。将它们拖放到表单上。添加选择的适当设置。最后,添加以下事件处理程序:
在VB.NET中,可以这样编写代码:
Private Sub ipmTreeView_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles ipmTreeView.AfterSelect
listBoxItems.Items.Clear()
' 检索登录的配置文件中的第一个消息存储
current = AdxmapiStoreAccessor1.MsgStores(0).RootFolder.Folders(1).Folders(e.Node.Index)
Dim item As MapiItem
For Each item In current.MapiItems
' 检索mapi项目的PR_BODY属性
Dim subject As Object = item.GetProperty(ADXMAPIPropertyTag._PR_SUBJECT)
If subject IsNot Nothing Then
listBoxItems.Items.Add(subject.ToString())
End If
Next
End Sub
在C#中,可以这样编写代码:
private void ipmTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
listBoxItems.Items.Clear();
// 检索登录的配置文件中的第一个消息存储
current = ((Folders)adxmapiStoreAccessor1.MsgStores[0].RootFolder.Folders[1].Folders).Add(e.Node.Text);
foreach (MapiItem item in current.MapiItems)
{
// 检索mapi项目的PR_BODY属性
object subject = item.GetProperty(ADXMAPIPropertyTag._PR_SUBJECT);
if (subject != null)
{
listBoxItems.Items.Add(subject.ToString());
}
}
}
在VB.NET中,可以这样编写代码:
Private Sub listBoxItems_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles listBoxItems.DoubleClick
If listBoxItems.SelectedIndex >= 0 Then
Dim item As MapiItem = current.MapiItems(listBoxItems.SelectedIndex)
Dim body As Object = item.GetProperty(ADXMAPIPropertyTag._PR_BODY)
If body IsNot Nothing Then
MsgBox(body.ToString(), "邮件项目的正文", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End If
End Sub
private void listBoxItems_DoubleClick(object sender, EventArgs e)
{
if (listBoxItems.SelectedIndex >= 0)
{
MapiItem item = current.MapiItems[listBoxItems.SelectedIndex];
object body = item.GetProperty(ADXMAPIPropertyTag._PR_BODY);
if (body != null)
{
System.Windows.Forms.MessageBox.Show(body.ToString(), "邮件项目的正文", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}