如何以编程方式在Outlook搜索文件夹上设置自定义图标? (即Outlook文件夹SetCustomIcon)

我正在尝试使用Folder.SetCustomIcon()方法在我以编程方式创建的已保存搜索文件夹上放置自定义图标。 SetCustomIcon()文档非常稀疏,但可以在此处找到以供参考 。

此外, 它期望的对象是一遍又一遍的例子是非常稀疏的。

有人知道如何设置文件夹的自定义图标吗? 以下是我到目前为止的代码:

 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; } } 

您只需使用PictureDispConverter从图像/图标转到IPictureDisp 。 以下是MSDN的示例 。 这仅适用于Outlook 2010+ 。 若要在Outlook 2013中查看自定义文件夹图标您需要查看“ 文件夹列表” – 而不是“ 邮件”视图

来自MAPIFolder的SetCustomIcon

 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(); } } 

PictureDispConverter( Icon-> IPictureDisp,Image-> IPictureDisp

 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(); } } } } 

如果你想在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