vbAccelerator - Contents of code file: acclExplorerBar_BarBitmaps.cs

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Resources;
using System.Runtime.InteropServices;

namespace vbAccelerator.Components.Controls.ExplorerBarUtility
{

   /// <summary>
   /// The types of bar bitmaps available.
   /// </summary>
   internal enum BarBitmapType : int
   {
      EBP_NORMALGROUPCOLLAPSE = 0,
      EBP_NORMALGROUPCOLLAPSE_MOUSEOVER = 1,
      EBP_NORMALGROUPEXPAND = 2,
      EBP_NORMALGROUPEXPAND_MOUSEOVER = 3,
      EBP_SPECIALGROUPCOLLAPSE = 4,
      EBP_SPECIALGROUPCOLLAPSE_MOUSEOVER = 5,
      EBP_SPECIALGROUPEXPAND = 6,
      EBP_SPECIALGROUPEXPAND_MOUSEOVER = 7,
      EBP_SPECIALGROUPHEAD = 8,
      EBP_NORMALGROUPHEAD = 9
   }

   /// <summary>
   /// Maintains a collection of bitmaps to use when drawing 
   /// explorer bars.
   /// </summary>
   internal class BarBitmaps : IDisposable
   {
      #region Unmanaged Code
      [DllImport("gdi32")]
      private static extern int DeleteObject(IntPtr hObject);

      [DllImport("user32")]
      private static extern int GetSysColor(int nIndex);

      private const int COLOR_GRADIENTACTIVECAPTION = 27;
      private const int COLOR_GRADIENTINACTIVECAPTION = 28;
      #endregion

      private Color specialTitleColorDark;
      private Color specialTitleColorLight;
      private Color normalTitleColorDark;
      private Color normalTitleColorLight;
      private Color specialPanelColor;
      private Color normalPanelColor;
      private Bitmap[] bitmaps;
      private bool usingXpBitmaps = false;

      /// <summary>
      /// Constructs a new instance of this class
      /// </summary>
      public BarBitmaps()
      {
         bitmaps = new Bitmap[10];
      }

      public Color SpecialTitleColorDark
      {
         get
         {
            return specialTitleColorDark;
         }
         set
         {
            if (specialTitleColorDark != value)
            {
               specialTitleColorDark = value;
               if (!usingXpBitmaps)
               {
                  ClearUp();
                  LoadLocalThemeBitmaps();
               }
            }
         }
      }
      public Color SpecialTitleColorLight
      {
         get
         {
            return specialTitleColorLight;
         }
         set
         {
            specialTitleColorLight = value;
         }
      }
      public Color NormalTitleColorDark
      {
         get
         {
            return normalTitleColorDark;
         }
         set
         {
            if (normalTitleColorDark != value)
            {
               normalTitleColorDark = value;
               if (!usingXpBitmaps)
               {
                  ClearUp();
                  LoadLocalThemeBitmaps();
               }
            }
         }
      }
      public Color NormalTitleColorLight
      {
         get
         {
            return normalTitleColorLight;
         }
         set
         {
            normalTitleColorLight = value;
         }
      }
      public Color SpecialPanelColor
      {
         get
         {
            return specialPanelColor;
         }
      }
      public Color NormalPanelColor
      {
         get
         {
            return normalPanelColor;
         }
      }

      public Color DefaultNormalTitleColorDark
      {
         get
         {
            int rgb = GetSysColor(COLOR_GRADIENTINACTIVECAPTION);
            return Color.FromArgb(rgb & 0xFF, ((rgb >> 8) & 0xFF), ((rgb >> 16)
             & 0xFF));
         }
      }
      
      public Color DefaultNormalTitleColorLight
      {
         get
         {
            return Color.White;
         }
      }

      public Color DefaultSpecialTitleColorLight
      {
         get
         {
            return Color.FromKnownColor(KnownColor.ActiveCaption);
         }
      }

      public Color DefaultSpecialTitleColorDark
      {
         get
         {
            int rgb = GetSysColor(COLOR_GRADIENTACTIVECAPTION);
            return Color.FromArgb(rgb & 0xFF, ((rgb >> 8) & 0xFF), ((rgb >> 16)
             & 0xFF));
         }
      }


      /// <summary>
      /// Gets the Bitmap with the specified type.
      /// </summary>
      public Bitmap this[BarBitmapType bitmapType]
      {
         get
         {
            return bitmaps[(int) bitmapType];
         }
      }
      
      /// <summary>
      /// Loads the bitmaps.
      /// </summary>
      /// <param name="handle">Windows handle.</param>
      /// <param name="style">Style to draw with.</param>
      public void Load(
         IntPtr handle,
         ExplorerBarDrawingStyle style
         )
      {
         ClearUp();
         
         bool success = false;
         bool tryXp = false;

         usingXpBitmaps = false;

         if (ExplorerBarHelper.IsXp)
         {
            tryXp = ((style == ExplorerBarDrawingStyle.XP) || 
               (style == ExplorerBarDrawingStyle.System));
         }

         if ((style == ExplorerBarDrawingStyle.Classic) ||
            (style == ExplorerBarDrawingStyle.System && !tryXp))
         {
         }
         else
         {
            if (tryXp)
            {
               success = LoadXpThemeBitmaps(handle);
            }
            if (success)
            {
               usingXpBitmaps = true;
            }
            else
            {
               LoadLocalThemeBitmaps();
               normalPanelColor =
                Color.FromKnownColor(KnownColor.InactiveCaptionText);
               specialPanelColor = ExplorerBarHelper.BlendColor(
                  Color.FromKnownColor(KnownColor.InactiveCaptionText),
                  Color.White, 128);
            }
         }
      }            

      private bool LoadXpThemeBitmaps(IntPtr handle)
      {
         bool success = false;

         using (XpThemeAPI xpTheme = new XpThemeAPI())
         {
            xpTheme.Handle = handle;
            xpTheme.ClassList = "ExplorerBar";

            if (!xpTheme.hTheme.Equals(IntPtr.Zero))
            {
               string shellStyleDLLFile = xpTheme.ThemeFile;
               shellStyleDLLFile = Path.GetDirectoryName(shellStyleDLLFile);
               shellStyleDLLFile = Path.Combine(shellStyleDLLFile, "Shell");
               shellStyleDLLFile = Path.Combine(shellStyleDLLFile,
                xpTheme.ThemeColorName);
               shellStyleDLLFile = Path.Combine(shellStyleDLLFile,
                "shellstyle.dll");

               if (File.Exists(shellStyleDLLFile))
               {
                  using (ResourceLibrary lib = new ResourceLibrary())
                  {
                     lib.Filename = shellStyleDLLFile;
                     if (!lib.Handle.Equals(IntPtr.Zero))
                     {
                        // normal collapse
                        bitmaps[0] = BarBitmaps.GetXpThemeBitmap(lib, 102);
                        bitmaps[1] = BarBitmaps.GetXpThemeBitmap(lib, 103);

                        // normal expand
                        bitmaps[2] = BarBitmaps.GetXpThemeBitmap(lib, 100);
                        bitmaps[3] = BarBitmaps.GetXpThemeBitmap(lib, 101);

                        // special collapse
                        bitmaps[4] = BarBitmaps.GetXpThemeBitmap(lib, 106);
                        bitmaps[5] = BarBitmaps.GetXpThemeBitmap(lib, 107);

                        // special expand
                        bitmaps[6] = BarBitmaps.GetXpThemeBitmap(lib, 104);
                        bitmaps[7] = BarBitmaps.GetXpThemeBitmap(lib, 105);

                        // special title bar
                        bitmaps[8] = BarBitmaps.GetXpThemeBitmap(lib, 110);

                        // normal title bar
                        bitmaps[9] = BarBitmaps.GetXpThemeBitmap(lib, 112);

                        // temporary bitmap to get the panel colour:
                        Bitmap panelColour = BarBitmaps.GetXpThemeBitmap(lib,
                         14);

                        success = true;
                        
                        for (int i = 0; i < 10; i++)
                        {
                           if (bitmaps[i] == null)
                           {
                              success = false;
                              break;
                           }
                        }

                        if (success)
                        {
                           if (panelColour != null)
                           {
                              specialPanelColor = panelColour.GetPixel(0, 0);
                              normalPanelColor =
                               ExplorerBarHelper.BlendColor(specialPanelColor,
                               Color.FromKnownColor(KnownColor.ActiveCaption),
                               230);
                              panelColour.Dispose();
                           }
                           else
                           {
                              success = false;
                           }
                        }
                     }
                  }
               }
            }
         }
         
         return success;
      }

      private static Bitmap GetXpThemeBitmap(ResourceLibrary lib, int id)
      {
         Bitmap bm = null; 

         IntPtr hDib = lib.GetResource(
            id, 
            ResourceLibrary.ImageType.IMAGE_BITMAP, 
            ResourceLibrary.ImageLoadOptions.LR_CREATEDIBSECTION);
         if (!hDib.Equals(IntPtr.Zero))
         {
            bm = ImageUtility.DibToBitmap(hDib);
            DeleteObject(hDib);
         }

         return bm;
      }

      private void LoadLocalThemeBitmaps()
      {
         ResourceManager resources = new
          ResourceManager(typeof(acclExplorerBar));
         Color color;

         // Normal collapse
         bitmaps[0] = (Bitmap) (resources.GetObject("collapse"));
         if (bitmaps[0] != null)
         {   
            color = normalTitleColorDark;
            if (color == Color.Empty)
            {
               color = DefaultNormalTitleColorDark;
            }
            ImageUtility.ColouriseGlyph(bitmaps[0], color);
            bitmaps[1] = (Bitmap) bitmaps[0].Clone();
         }
         
         // Normal expand
         bitmaps[2] = (Bitmap) (resources.GetObject("expand"));
         if (bitmaps[2] != null)
         {
            color = normalTitleColorDark;
            if (color == Color.Empty)
            {
               color = DefaultNormalTitleColorDark;
            }
            ImageUtility.ColouriseGlyph(bitmaps[2], color);
            bitmaps[3] = (Bitmap) bitmaps[2].Clone();
         }

         // Special collapse
         bitmaps[4] = (Bitmap) (resources.GetObject("collapseSpecial"));
         if (bitmaps[4] != null)
         {
            color = specialTitleColorDark;
            if (color == Color.Empty)
            {
               color = DefaultSpecialTitleColorDark;
            }
            ImageUtility.ColouriseGlyph(bitmaps[4], color);
            bitmaps[5] = (Bitmap) bitmaps[4].Clone();
         }
         
         // Special expand
         bitmaps[6] = (Bitmap) (resources.GetObject("expandSpecial"));
         if (bitmaps[6] != null)
         {
            color = specialTitleColorDark;
            if (color == Color.Empty)
            {
               color = DefaultSpecialTitleColorDark;
            }
            ImageUtility.ColouriseGlyph(bitmaps[6], color);
            bitmaps[7] = (Bitmap) bitmaps[6].Clone();
         }

         // Set default panel colours:
         specialPanelColor =
          ExplorerBarHelper.BlendColor(Color.FromKnownColor(KnownColor.Control),
          Color.White, 24);
         normalPanelColor = ExplorerBarHelper.BlendColor(specialPanelColor,
          Color.FromKnownColor(KnownColor.ActiveCaption), 230);
      }

      
      private void ClearUp()
      {
         for (int i = 0; i < 10; i++)
         {
            if (bitmaps[i] != null)
            {
               bitmaps[i].Dispose();
               bitmaps[i] = null;
            }
         }
      }

      /// <summary>
      /// Disposes with any resources
      /// </summary>
      public void Dispose()
      {
         ClearUp();
      }

   }
}