Reputation: 1595
I am attempting to use the Folder.SetCustomIcon()
method to place a custom icon on a saved search folder I programmatically created. The SetCustomIcon()
documentation is very sparse but can be found here for reference.
Also, the object it expects is here and again the examples are very sparse.
Would anybody know how to set the custom icon for a folder? The following is the code I have thus far:
searchFolders = inboxFolder.Store.GetSearchFolders();
foreach (Outlook.Folder folder in searchFolders)
{
if (folder.Name == "Expiring Retention Policy Mail")
{
folder.ShowItemCount = Microsoft.Office.Interop.Outlook.OlShowItemCount.olShowTotalItemCount;
folder.SetCustomIcon(new Bitmap(32, 32)); // <=-- this isn't working because it's expecting stdPicture which has very sparse information on how to convert to this type.
Globals.ThisAddIn.Application.ActiveExplorer().CurrentFolder = folder;
}
}
Upvotes: 3
Views: 3277
Reputation: 382
here is simple version if you want to realize it in VBA
Sub Change_mapiRootFolder_Icon()
Dim mapiRootFolder As Outlook.MAPIFolder, mapiCurrFolder As Outlook.MAPIFolder
Dim stFullFolderPath As String, stCurrItemType As String, stIconPath As String, stCurrFolder As String
Dim i As Integer
Dim ipdMyPic As IPictureDisp
Set mapiCurrFolder = Application.ActiveExplorer.CurrentFolder
stCurrItemType = Application.ActiveExplorer.CurrentFolder.DefaultMessageClass
If stCurrItemType = "IPM.Note" Then 'mail Item types https://msdn.microsoft.com/en-us/library/office/ff861573.aspx
Set mapiRootFolder = mapiCurrFolder
stFullFolderPath = mapiRootFolder.Name
Do Until mapiRootFolder.Parent = "Mapi"
Set mapiRootFolder = mapiRootFolder.Parent
stFullFolderPath = mapiRootFolder.Name & "\" & stFullFolderPath
Loop
Debug.Print stFullFolderPath
stIconPath = "U:\OUTLOOK\Icons\Sent\iconarchive_sent1.ico"
stIconPath = "C:\Temp\iconarchive_sent1.bmp"
Set ipdMyPic = LoadPicture(stIconPath)
If Not (mapiCurrFolder Is Nothing) Then
mapiCurrFolder.SetCustomIcon ipdMyPic
End If
End If
End Sub
Upvotes: 0
Reputation: 31651
You just need to use a PictureDispConverter
to go from an image/icon to IPictureDisp
. Below is an example from MSDN. This only works in Outlook 2010+. To view custom Folder Icons in Outlook 2013, you need to view the Folder List - not the Mail view.
private static void SetCustomIcon(Outlook.MAPIFolder folder)
{
Icon icon = null;
try
{
icon = Properties.Resources.myCustomIcon_16x16;
stdole.StdPicture iconPictureDisp = PictureDispConverter.ToIPictureDisp(icon) as stdole.StdPicture;
folder.SetCustomIcon(iconPictureDisp);
}
finally
{
icon.Dispose();
}
}
public static class PictureDispConverter
{
//IPictureDisp GUID.
public static Guid iPictureDispGuid = typeof(stdole.IPictureDisp).GUID;
// Converts an Icon into an IPictureDisp.
public static stdole.IPictureDisp ToIPictureDisp(Icon icon)
{
PICTDESC.Icon pictIcon = new PICTDESC.Icon(icon);
return PictureDispConverter.OleCreatePictureIndirect(pictIcon, ref iPictureDispGuid, true);
}
// Converts an image into an IPictureDisp.
public static stdole.IPictureDisp ToIPictureDisp(Image image)
{
Bitmap bitmap = (image is Bitmap) ? (Bitmap)image : new Bitmap(image);
PICTDESC.Bitmap pictBit = new PICTDESC.Bitmap(bitmap);
return PictureDispConverter.OleCreatePictureIndirect(pictBit, ref iPictureDispGuid, true);
}
[DllImport("OleAut32.dll", EntryPoint = "OleCreatePictureIndirect", ExactSpelling = true,
PreserveSig = false)]
private static extern stdole.IPictureDisp OleCreatePictureIndirect(
[MarshalAs(UnmanagedType.AsAny)] object picdesc, ref Guid iid, bool fOwn);
private readonly static HandleCollector handleCollector =
new HandleCollector("Icon handles", 1000);
// WINFORMS COMMENT:
// PICTDESC is a union in native, so we'll just
// define different ones for the different types
// the "unused" fields are there to make it the right
// size, since the struct in native is as big as the biggest
// union.
private static class PICTDESC
{
//Picture Types
public const short PICTYPE_UNINITIALIZED = -1;
public const short PICTYPE_NONE = 0;
public const short PICTYPE_BITMAP = 1;
public const short PICTYPE_METAFILE = 2;
public const short PICTYPE_ICON = 3;
public const short PICTYPE_ENHMETAFILE = 4;
[StructLayout(LayoutKind.Sequential)]
public class Icon
{
internal int cbSizeOfStruct = Marshal.SizeOf(typeof(PICTDESC.Icon));
internal int picType = PICTDESC.PICTYPE_ICON;
internal IntPtr hicon = IntPtr.Zero;
internal int unused1 = 0;
internal int unused2 = 0;
internal Icon(System.Drawing.Icon icon)
{
this.hicon = icon.ToBitmap().GetHicon();
}
}
[StructLayout(LayoutKind.Sequential)]
public class Bitmap
{
internal int cbSizeOfStruct = Marshal.SizeOf(typeof(PICTDESC.Bitmap));
internal int picType = PICTDESC.PICTYPE_BITMAP;
internal IntPtr hbitmap = IntPtr.Zero;
internal IntPtr hpal = IntPtr.Zero;
internal int unused = 0;
internal Bitmap(System.Drawing.Bitmap bitmap)
{
this.hbitmap = bitmap.GetHbitmap();
}
}
}
}
Upvotes: 2