In the previous sample, I showed how to get the PR_ATTACH_SIZE Extended MAPI property that returns the size of an Attachment object. To be more precise, it returns the size of the attached file plus the size of some internal info.
In most cases that makeweight does not matter at all since it is very small (about 100-200 bytes), but sometimes it may be excess. In order to get the exact size of the attached file, you need to use the PR_ATTACH_DATA_BIN binary property:
Private Function GetAttachSizeMAPI(ByVal oMAPIObject As Object) As Long
If (oMAPIObject Is Nothing) Then Return 0
Dim result As String = 0
Dim pPropValue As IntPtr = IntPtr.Zero
Dim IUnk As IntPtr = IntPtr.Zero
Dim IProperty As IntPtr = IntPtr.Zero
Try
MAPI.MAPIInitialize(IntPtr.Zero)
IUnk = Marshal.GetIUnknownForObject(oMAPIObject)
' Outlook 2003 and 2007 ( IMAPIProp )
Dim res = Marshal.QueryInterface(IUnk, MAPI.guidMAPIProp, IProperty)
If res = MAPI.S_OK Then
Dim oMapiProp As Object = Marshal.GetObjectForIUnknown(IProperty)
Dim iMapiProp As IMAPIProp = TryCast(oMapiProp, IMAPIProp)
If iMapiProp IsNot Nothing Then
Try
Dim stream As ComTypes.IStream
Dim IStream As IntPtr = IntPtr.Zero
iMapiProp.OpenProperty( _
MAPI.PR_ATTACH_DATA_BIN, _
MAPI.guidIStream, 0, 0, _
IStream)
If IStream <> IntPtr.Zero Then
Try
stream = TryCast( _
Marshal.GetObjectForIUnknown(IStream), _
ComTypes.IStream)
If stream IsNot Nothing Then
Try
Dim stat As ComTypes.STATSTG = Nothing
stream.Stat(stat, STATFLAG.STATFLAG_NONAME)
result = stat.cbSize
Return result
Finally
Marshal.ReleaseComObject(stream)
End Try
End If
Finally
Marshal.Release(IStream)
End Try
End If
Finally
Marshal.ReleaseComObject(oMapiProp)
End Try
End If
End If
' Outlook 2000 and XP ( IAttach )
res = Marshal.QueryInterface(IUnk, MAPI.guidMAPIAttach, IProperty)
If res = MAPI.S_OK Then
Dim oMapiProp As Object = Marshal.GetObjectForIUnknown(IProperty)
Dim iMapiProp As IAttach = TryCast(oMapiProp, IAttach)
If iMapiProp IsNot Nothing Then
Try
Dim stream As ComTypes.IStream
Dim IStream As IntPtr = IntPtr.Zero
iMapiProp.OpenProperty( _
MAPI.PR_ATTACH_DATA_BIN, _
MAPI.guidIStream, 0, 0, _
IStream)
If IStream <> IntPtr.Zero Then
Try
stream = TryCast( _
Marshal.GetObjectForIUnknown(IStream), _
ComTypes.IStream)
If stream IsNot Nothing Then
Try
Dim stat As ComTypes.STATSTG = Nothing
stream.Stat(stat, STATFLAG.STATFLAG_NONAME)
result = stat.cbSize
Return result
Finally
Marshal.ReleaseComObject(stream)
End Try
End If
Finally
Marshal.Release(IStream)
End Try
End If
Finally
Marshal.ReleaseComObject(oMapiProp)
End Try
End If
End If
Finally
If (pPropValue <> IntPtr.Zero) Then
MAPI.MAPIFreeBuffer(pPropValue)
End If
If (IProperty <> IntPtr.Zero) Then
Marshal.Release(IProperty)
End If
If (IUnk <> IntPtr.Zero) Then
Marshal.Release(IUnk)
End If
End Try
Return result
End Function
Personal thanks to François-Denis for his contribution to the PR_ATTACH_SIZE vs. PR_ATTACH_DATA_BIN properties discussion on our forum.
You may also be interested in:
How to program an Outlook COM add-in: ribbon tabs, command bars, task panes
Advanced features for Outlook plug-in development
How to develop custom Outlook forms
Available downloads:
This sample add-in was developed using Add-in Express 2009 for Microsoft Office and .net
C# sample Outlook add-in for VS 2005
VB.NET sample Outlook add-in for VS 2005




