vbAccelerator - Contents of code file: acclExplorerBar_ExplorerBarHelper.cs

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace vbAccelerator.Components.Controls.ExplorerBarUtility
{
   /// <summary>
   /// Contains static helper methods used throughout the Explorer Bar.
   /// </summary>
   internal class ExplorerBarHelper
   {      
      private static bool checkedXp = false;
      private static bool isXp = false;

      #region Unmanaged Code
      [DllImport("user32")]
      private static extern int GetAsyncKeyState(int vKey);
      #endregion

      /// <summary>
      /// Prevent direct instantiation; all methods are static.
      /// </summary>
      private ExplorerBarHelper()
      {
      }

      /// <summary>
      /// Determines whether the specified key is held down or not
      /// </summary>
      /// <param name="key">Key to check</param>
      /// <returns><c>true</c> if the key is pressed, <c>false</c>
       otherwise</returns>
      public static bool KeyIsPressed(Keys key)
      {
         bool isPressed = (GetAsyncKeyState((int) key) != 0);
         return isPressed;
      }

      /// <summary>
      /// Returns <c>true</c> if the System is XP, <c>false</c> otherwise.
      /// </summary>
      public static bool IsXp
      {
         get
         {
            if (!checkedXp)
            {
               Version ver = System.Environment.OSVersion.Version;
               if (ver.Major > 5)
               {
                  isXp = true;
               }
               else
               {
                  if ((ver.Major == 5) && (ver.Minor >= 1))
                  {
                     isXp = true;
                  }
               }
               checkedXp = true;
            }
            return isXp;
         }
      }

      /// <summary>
      /// Gets the horizontal margin used when drawing bars and items
      /// in the control.
      /// </summary>
      public static int HorizontalMargin
      {
         get
         {
            return 12;
         }
      }

      /// <summary>
      /// Draw the title for a bar.
      /// </summary>
      /// <param name="graphics">Graphics to render to</param>
      /// <param name="mode">Explorer Bar Drawing mode</param>
      /// <param name="style">Explorer Bar Drawing Style</param>
      /// <param name="barBitmaps">Class containing bitmaps for various title
       parts</param>
      /// <param name="xpTheme">Class managing the current system XP
       Theme</param>
      /// <param name="rectangle">Rectangle to draw into</param>
      /// <param name="isSpecial">Whether this is a special bar or not</param>
      /// <param name="isHot">Whether the bar is hot not</param>
      /// <param name="isMouseDown">Whether the mouse is down on the bar or
       not</param>
      /// <param name="state">The state of the bar, expanded or
       collapsed</param>
      /// <param name="canExpand">Whether the bar is expandable</param>
      /// <param name="rightToLeft">If the control should be draw Right -
       Left</param>
      /// <returns>Actual height of title image</returns>
      public static int DrawBarTitle(
         Graphics graphics,
         ExplorerBarMode mode,
         ExplorerBarDrawingStyle style,
         BarBitmaps barBitmaps,
         XpThemeAPI xpTheme,
         Rectangle rectangle,
         bool isSpecial,
         bool isHot,
         bool isMouseDown,
         ExplorerBarState state,
         bool canExpand,
         bool rightToLeft
         )
      {
         if ((rectangle.Height <= 0) || (rectangle.Width <= 0))
         {
            return 0;
         }

         bool useXpStyle = false;

         if ((style == ExplorerBarDrawingStyle.XP) || (style ==
          ExplorerBarDrawingStyle.System))
         {
            useXpStyle = (xpTheme.hTheme != IntPtr.Zero);
         }

         // Evaluate the bitmap type (not used for classic style):            
         BarBitmapType bitmapType = getBarBitmapType(state, isSpecial, isHot);
         int size = 0;

         if (useXpStyle)
         {
            size = DrawTitleUsingXpTheme(bitmapType, barBitmaps, graphics,
             rectangle, isSpecial, canExpand, rightToLeft, mode);
         }
         else // Don't use XP style
         {
            if ((style == ExplorerBarDrawingStyle.Classic) || (style ==
             ExplorerBarDrawingStyle.System))
            {
               size = DrawTitleUsingClassicStyle(graphics, rectangle,
                isSpecial, canExpand, rightToLeft, state, isHot, isMouseDown,
                mode);
            }
            else
            {
               size = DrawTitleUsingEmulatedXpStyle(bitmapType, barBitmaps,
                graphics, rectangle, isSpecial, canExpand, rightToLeft, mode);
            }
         }
         return size;
      }

      /// <summary>
      /// Gets the bar bitmap type for the specified parameters.
      /// </summary>
      /// <param name="state">State of the bar, expanded or collapsed</param>
      /// <param name="isSpecial">Whether the bar is special or not</param>
      /// <param name="isHot">Whether the bar is hot or not</param>
      /// <returns>Bitmap type</returns>
      private static BarBitmapType getBarBitmapType(
         ExplorerBarState state,
         bool isSpecial,
         bool isHot
         )
      {
         BarBitmapType bitmapType;
         if (isSpecial)
         {
            if (isHot)
            {
               if (state == ExplorerBarState.Collapsed)
               {
                  bitmapType = BarBitmapType.EBP_SPECIALGROUPCOLLAPSE_MOUSEOVER;
               }
               else
               {
                  bitmapType = BarBitmapType.EBP_SPECIALGROUPEXPAND_MOUSEOVER;
               }
            }
            else
            {
               if (state == ExplorerBarState.Collapsed)
               {
                  bitmapType = BarBitmapType.EBP_SPECIALGROUPCOLLAPSE;
               }
               else
               {
                  bitmapType = BarBitmapType.EBP_SPECIALGROUPEXPAND;
               }
            }
         }
         else
         {
            if (isHot)
            {
               if (state == ExplorerBarState.Collapsed)
               {
                  bitmapType = BarBitmapType.EBP_NORMALGROUPCOLLAPSE_MOUSEOVER;
               }
               else
               {
                  bitmapType = BarBitmapType.EBP_NORMALGROUPEXPAND_MOUSEOVER;
               }
            }
            else
            {
               if (state == ExplorerBarState.Collapsed)
               {
                  bitmapType = BarBitmapType.EBP_NORMALGROUPCOLLAPSE;
               }
               else
               {
                  bitmapType = BarBitmapType.EBP_NORMALGROUPEXPAND;
               }
            }
         }
         return bitmapType;
      }

      /// <summary>
      /// Draws a bar title in the classic style.
      /// </summary>
      /// <param name="graphics">Graphics to render to</param>
      /// <param name="rectangle">Bounding rectangle for the title</param>
      /// <param name="isSpecial">Whether the bar is special</param>
      /// <param name="canExpand">Whether the bar can be
       expanded/collapsed</param>
      /// <param name="rightToLeft">Whether to draw right to left</param>
      /// <param name="state">Bar state, expanded or collapsed</param>
      /// <param name="isHot">Whether bar is hot or not</param>
      /// <param name="isMouseDown">Whether mouse is down on the title</param>
      /// <param name="mode">Drawing mode of the control</param>
      /// <returns>Actual height of title image</returns>
      private static int DrawTitleUsingClassicStyle(
         Graphics graphics,
         Rectangle rectangle,
         bool isSpecial,
         bool canExpand,
         bool rightToLeft,
         ExplorerBarState state,
         bool isHot,
         bool isMouseDown,
         ExplorerBarMode mode
         )
      {
         // Draw the title
         if (mode == ExplorerBarMode.Default)
         {
            if (isSpecial)
            {
               graphics.FillRectangle(SystemBrushes.ActiveCaption, rectangle);
            }
            else
            {
               graphics.FillRectangle(SystemBrushes.InactiveCaption, rectangle);
            }
         }
         
         // Draw the button
         if (canExpand)
         {
            Rectangle buttonPosition = new Rectangle(rectangle.Location,
             rectangle.Size);
            buttonPosition.Y = buttonPosition.Top + (buttonPosition.Height -
             16) / 2;
            buttonPosition.Height = 16;                     
            if (rightToLeft)
            {
               buttonPosition.X += 2;
               buttonPosition.Width = 16;
            }
            else
            {
               buttonPosition.X = buttonPosition.Right - 16 - 4;
               buttonPosition.Width = 16;
            }

            Pen pen = null;
            if (isSpecial)
            {
               pen = SystemPens.ActiveCaptionText;
            }
            else
            {
               pen = SystemPens.InactiveCaptionText;
            }
            // Draw the glyph
            if (state == ExplorerBarState.Expanded)
            {
               // collapse glyph
               graphics.DrawLine(pen, buttonPosition.Left + 5,
                buttonPosition.Top + 7, buttonPosition.Left + 8,
                buttonPosition.Top + 4);
               graphics.DrawLine(pen, buttonPosition.Left + 8,
                buttonPosition.Top + 4, buttonPosition.Left + 11,
                buttonPosition.Top + 7);
               graphics.DrawLine(pen, buttonPosition.Left + 6,
                buttonPosition.Top + 7, buttonPosition.Left + 8,
                buttonPosition.Top + 5);
               graphics.DrawLine(pen, buttonPosition.Left + 8,
                buttonPosition.Top + 5, buttonPosition.Left + 10,
                buttonPosition.Top + 7);
                        
               graphics.DrawLine(pen, buttonPosition.Left + 5,
                buttonPosition.Top + 11, buttonPosition.Left + 8,
                buttonPosition.Top + 8);
               graphics.DrawLine(pen, buttonPosition.Left + 8,
                buttonPosition.Top + 8, buttonPosition.Left + 11,
                buttonPosition.Top + 11);
               graphics.DrawLine(pen, buttonPosition.Left + 6,
                buttonPosition.Top  + 11, buttonPosition.Left + 8,
                buttonPosition.Top + 9);
               graphics.DrawLine(pen, buttonPosition.Left + 8,
                buttonPosition.Top + 9, buttonPosition.Left + 10,
                buttonPosition.Top + 11);
            }
            else
            {
               // expand glyph
               graphics.DrawLine(pen, buttonPosition.Left + 5,
                buttonPosition.Top + 4, buttonPosition.Left + 8,
                buttonPosition.Top + 7);
               graphics.DrawLine(pen, buttonPosition.Left + 8,
                buttonPosition.Top + 7, buttonPosition.Left + 11,
                buttonPosition.Top + 4);
               graphics.DrawLine(pen, buttonPosition.Left + 6,
                buttonPosition.Top + 4, buttonPosition.Left + 8,
                buttonPosition.Top + 6);
               graphics.DrawLine(pen, buttonPosition.Left + 8,
                buttonPosition.Top + 6, buttonPosition.Left + 10,
                buttonPosition.Top + 4);
                        
               graphics.DrawLine(pen, buttonPosition.Left + 5,
                buttonPosition.Top + 8, buttonPosition.Left + 8,
                buttonPosition.Top + 11);
               graphics.DrawLine(pen, buttonPosition.Left + 8,
                buttonPosition.Top + 11, buttonPosition.Left + 11,
                buttonPosition.Top + 8);
               graphics.DrawLine(pen, buttonPosition.Left + 6,
                buttonPosition.Top + 8, buttonPosition.Left + 8,
                buttonPosition.Top + 10);
               graphics.DrawLine(pen, buttonPosition.Left + 8,
                buttonPosition.Top + 10, buttonPosition.Left + 10,
                buttonPosition.Top + 8);
            }
                     
            // Draw button border if required
            if (isHot)
            {
               if (isMouseDown)
               {
                  ControlPaint.DrawBorder3D(graphics, buttonPosition, 
                     Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Top
                      | Border3DSide.Right | Border3DSide.Bottom);
               }
               else
               {
                  ControlPaint.DrawBorder3D(graphics, buttonPosition, 
                     Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top
                      | Border3DSide.Right | Border3DSide.Bottom);
               }
            }
         }
   
         return rectangle.Height;

      }

      /// <summary>
      /// Draws a bar title using an emulation of the XP theme style
      /// </summary>
      /// <param name="bitmapType">Bar Bitmap type to use to draw the
       bar</param>
      /// <param name="barBitmaps">Class containing bitmaps to draw</param>
      /// <param name="graphics">Graphics object to render to</param>
      /// <param name="rectangle">Bounding rectangle of title</param>
      /// <param name="isSpecial">Whether the bar is special or not</param>
      /// <param name="canExpand">Whether the bar can be
       expanded/collapsed</param>
      /// <param name="rightToLeft">Whether the control should render right -
       left</param>
      /// <param name="mode">Drawing mode of the control</param>
      /// <returns>Actual height of title image</returns>
      private static int DrawTitleUsingEmulatedXpStyle(
         BarBitmapType bitmapType,
         BarBitmaps barBitmaps,
         Graphics graphics,
         Rectangle rectangle,
         bool isSpecial,
         bool canExpand,
         bool rightToLeft,
         ExplorerBarMode mode
         )
      {
         // emulated XP style:
         Color startColor;
         Color endColor;
         Bitmap button = barBitmaps[bitmapType];      
         Point buttonPosition = new Point(rectangle.X + 2, rectangle.Top +
          (rectangle.Height - button.Height) / 2 );
         if (!rightToLeft)
         {
            buttonPosition.X = rectangle.Left + rectangle.Width - 2 -
             button.Width;
         }
         Rectangle titleRect = new Rectangle(rectangle.Location,
          rectangle.Size);         

         if (mode == ExplorerBarMode.Default)
         {
            if (titleRect.Height > button.Height + 4)
            {
               titleRect.Y += (titleRect.Height - (button.Height + 4));
               titleRect.Height = button.Height + 4;
               buttonPosition.Y = titleRect.Top + 2;
            }
            if (isSpecial)
            {
               startColor = barBitmaps.SpecialTitleColorLight;
               if (startColor == Color.Empty)
               {
                  startColor = barBitmaps.DefaultSpecialTitleColorLight;
               }
               endColor = barBitmaps.SpecialTitleColorDark;
               if (endColor == Color.Empty)
               {
                  endColor = barBitmaps.DefaultSpecialTitleColorDark;
               }
            }
            else
            {
               startColor = barBitmaps.NormalTitleColorLight;
               if (startColor == Color.Empty)
               {
                  startColor = barBitmaps.DefaultNormalTitleColorLight;
               }
               endColor = barBitmaps.NormalTitleColorDark;
               if (endColor == Color.Empty)
               {
                  endColor = barBitmaps.DefaultNormalTitleColorDark;
               }
            }
            if (rightToLeft)
            {
               Color swapColor = startColor;
               startColor = endColor;
               endColor = swapColor;
            }                  

            Rectangle clippedRect;
            GraphicsPath path = new GraphicsPath();
            if (rightToLeft)
            {
               path.AddLine(buttonPosition.X + button.Width, titleRect.Bottom,
                buttonPosition.X + button.Width, titleRect.Top);
               path.AddLine(buttonPosition.X + button.Width, titleRect.Top,
                titleRect.Right - 2, titleRect.Top);
               path.AddLine(titleRect.Right - 2, titleRect.Top,
                titleRect.Right, titleRect.Top + 2);
               path.AddLine(titleRect.Right, titleRect.Top + 2,
                titleRect.Right, titleRect.Bottom);
               clippedRect = new Rectangle(buttonPosition.X + button.Width - 1,
                titleRect.Top, 
                  titleRect.Width - buttonPosition.X - button.Width + 2,
                   titleRect.Height);
            }
            else
            {
               path.AddLine(titleRect.Left, titleRect.Bottom, titleRect.Left,
                titleRect.Top + 2);
               path.AddLine(titleRect.Left, titleRect.Top + 2, titleRect.Left +
                2, titleRect.Top);
               path.AddLine(titleRect.Left + 2, titleRect.Top,
                buttonPosition.X, titleRect.Top);
               path.AddLine(buttonPosition.X, titleRect.Top, buttonPosition.X,
                titleRect.Bottom);
               clippedRect = new Rectangle(titleRect.Left - 1, titleRect.Top, 
                  titleRect.Width - button.Width - 2 + 2, titleRect.Height);
            }
            path.CloseFigure();
            Region region = new Region(path);                  
            LinearGradientBrush titleBrush = new LinearGradientBrush(
               clippedRect, startColor, endColor, 0.0F);
            graphics.FillRegion(titleBrush, region);
            titleBrush.Dispose();
            region.Dispose();
            path.Dispose();

            path = new GraphicsPath();
            if (rightToLeft)
            {
               path.AddLine(titleRect.Left, titleRect.Bottom, titleRect.Left,
                titleRect.Top + 2);
               path.AddLine(titleRect.Left, titleRect.Top + 2, titleRect.Left +
                2, titleRect.Top);
               path.AddLine(titleRect.Left + 2, titleRect.Top, buttonPosition.X
                + button.Width, titleRect.Top);
               path.AddLine(buttonPosition.X + button.Width, titleRect.Top,
                buttonPosition.X + button.Width, titleRect.Bottom);
            }
            else
            {
               path.AddLine(clippedRect.Right - 1, titleRect.Bottom,
                clippedRect.Right - 1, titleRect.Top);
               path.AddLine(clippedRect.Right - 1, titleRect.Top,
                titleRect.Right - 2, titleRect.Top);
               path.AddLine(titleRect.Right -  2, titleRect.Top,
                titleRect.Right, titleRect.Top + 2);
               path.AddLine(titleRect.Right, titleRect.Top + 2,
                titleRect.Right, titleRect.Bottom);
            }
            path.CloseFigure();
            region = new Region(path);
            Brush behindButton = new SolidBrush(endColor);
            graphics.FillRegion(behindButton, region);
            behindButton.Dispose();
            region.Dispose();
            path.Dispose();
         }

         // Draw the button:
         if (canExpand)
         {                                                            
            graphics.DrawImageUnscaled(button, buttonPosition.X,
             buttonPosition.Y);
         }

         return titleRect.Height;
      }

      /// <summary>
      /// Draw a bar title using the current XP theme
      /// </summary>
      /// <param name="bitmapType">Bitmap type to draw</param>
      /// <param name="barBitmaps">Class containing bitmaps for title
       bars</param>
      /// <param name="graphics">Graphics object to render to</param>
      /// <param name="rectangle">Bounding rectangle for title bar</param>
      /// <param name="isSpecial">Whether the bar is special or not</param>
      /// <param name="canExpand">Whether the bar can be
       expanded/collapsed</param>
      /// <param name="rightToLeft">Whether the title should be rendered right
       - left</param>
      /// <param name="mode">Drawing mode of the control</param>
      /// <returns>Actual height of title image</returns>
      private static int DrawTitleUsingXpTheme(
            BarBitmapType bitmapType,
            BarBitmaps barBitmaps,
            Graphics graphics,
            Rectangle rectangle,
            bool isSpecial,
            bool canExpand,
            bool rightToLeft,
            ExplorerBarMode mode
         )
      {
         Rectangle titleRectangle = new Rectangle(rectangle.Location,
          rectangle.Size);
         if (mode == ExplorerBarMode.Default)
         {
            // Draw the title bar:
            BarBitmapType titleBitmapType = BarBitmapType.EBP_NORMALGROUPHEAD;
            if (isSpecial)
            {
               titleBitmapType = BarBitmapType.EBP_SPECIALGROUPHEAD;
            }
            Bitmap titleBar = barBitmaps[titleBitmapType];
            titleBar.MakeTransparent(titleBar.GetPixel(0, 0));
            if (rectangle.Height > titleBar.Height + 2)
            {
               titleRectangle.Height = titleBar.Height + 2;
               titleRectangle.Y += (rectangle.Height - titleBar.Height - 2);
            }
            graphics.DrawImage(titleBar, titleRectangle, 0, 0, titleBar.Width,
             titleBar.Height, GraphicsUnit.Pixel);            
         }

         // Draw the relevant button:
         if (canExpand)
         {
            Bitmap button = barBitmaps[bitmapType];
            Point buttonPosition = new Point(titleRectangle.X + 2, 
               titleRectangle.Top + (titleRectangle.Height - button.Height) / 2
                + 2);
            if (!rightToLeft)
            {
               buttonPosition.X = titleRectangle.Left + titleRectangle.Width -
                2 - button.Width;
            }
            graphics.DrawImageUnscaled(button, buttonPosition.X,
             buttonPosition.Y);
         }

         return titleRectangle.Height;
      }

      public static void DrawSearchContainer(
         Graphics graphics,
         Rectangle boundingRectangle,
         int top,
         int height,
         int internalBorder,
         Color panelColor
         )
      {
         int drawHeight = height;
         if (drawHeight > boundingRectangle.Height)
         {
            drawHeight = boundingRectangle.Height;
         }

         Rectangle rectangle = new Rectangle(internalBorder, top, 
            boundingRectangle.Width - internalBorder * 2, height);
         Brush brush = new SolidBrush(panelColor);
         graphics.FillRectangle(brush, rectangle);
         brush.Dispose();

         int pathLeft = internalBorder - 1;
         int pathTop = top - 1;
         int pathRight = pathLeft + boundingRectangle.Width - internalBorder *
          2 + 1;
         int pathBottom = pathTop + height + 1;
         GraphicsPath path = new GraphicsPath();
         path.AddLine(pathLeft, pathTop + 2, pathLeft + 2, pathTop);
         path.AddLine(pathLeft + 2, pathTop, pathRight - 2, pathTop);
         path.AddLine(pathRight - 2, pathTop, pathRight, pathTop + 2);
         path.AddLine(pathRight, pathTop + 2, pathRight, pathBottom - 2);
         path.AddLine(pathRight, pathBottom - 2, pathRight - 2, pathBottom);
         path.AddLine(pathRight - 2, pathBottom, pathLeft + 2, pathBottom);
         path.AddLine(pathLeft + 2, pathBottom, pathLeft, pathBottom - 2);
         path.CloseFigure();

         graphics.DrawPath(Pens.White, path);

      }

      /// <summary>
      /// Draws the background to a bar
      /// </summary>
      /// <param name="graphics">Graphics object to render to</param>
      /// <param name="style">Drawing style for Explorer Bar</param>
      /// <param name="mode">Drawing mode for Explorer Bar</param>
      /// <param name="xpTheme">Class managing XP Theme</param>
      /// <param name="bitmaps">Class managing bitmaps to draw</param>
      /// <param name="rectangle">Bounding rectangle of bar</param>
      /// <param name="isSpecial">Whether the item is special or not</param>
      /// <param name="customNormalPanelColor">Customised color of normal panel
       back color</param>
      /// <param name="customSpecialPanelColor">Customised color of special
       panel back color</param>
      public static void DrawBarBackground(
         Graphics graphics,
         ExplorerBarDrawingStyle style,
         ExplorerBarMode mode,
         XpThemeAPI xpTheme,
         BarBitmaps bitmaps,
         Rectangle rectangle,
         bool isSpecial,
         Color customNormalPanelColor,
         Color customSpecialPanelColor
         )
      {
         bool classic = (style == ExplorerBarDrawingStyle.Classic);
         if (style == ExplorerBarDrawingStyle.System)
         {
            if (xpTheme.hTheme.Equals(IntPtr.Zero))
            {
               classic = true;
            }
         }

         if (classic)
         {
            graphics.FillRectangle(SystemBrushes.Window, rectangle);
            if (mode == ExplorerBarMode.Default)
            {
               Rectangle borderRectangle = new Rectangle(
                  rectangle.Location, rectangle.Size);
               borderRectangle.Width -=1;
               borderRectangle.Height -=1;
               if (isSpecial)
               {                  
                  Pen pen = new Pen(SystemBrushes.ActiveCaption, 1.0f);
                  graphics.DrawRectangle(pen, borderRectangle);
                  pen.Dispose();
               }
               else
               {
                  Pen pen = new Pen(SystemBrushes.InactiveCaption, 1.0f);
                  graphics.DrawRectangle(pen, borderRectangle);
                  pen.Dispose();
               }
            }
         }
         else
         {
            if (mode == ExplorerBarMode.Default)
            {               
               Color backColor = BarBackColor(
                  (isSpecial ? customSpecialPanelColor :
                   customNormalPanelColor), style, bitmaps, xpTheme, isSpecial);
               Brush brush = new SolidBrush(backColor);
               graphics.FillRectangle(brush, rectangle);
               brush.Dispose();
               graphics.DrawLine(Pens.White, rectangle.Left, rectangle.Top,
                rectangle.Left, rectangle.Bottom );
               graphics.DrawLine(Pens.White, rectangle.Left, rectangle.Bottom ,
                rectangle.Right - 1, rectangle.Bottom );
               graphics.DrawLine(Pens.White, rectangle.Right - 1,
                rectangle.Bottom, rectangle.Right - 1, rectangle.Top);

            }
            else // search mode
            {
               // nothing to do, the background is pre-rendered
            }
            
         }

      }


      /// <summary>
      /// Gets the default item text color for an item
      /// </summary>
      /// <param name="style"></param>
      /// <param name="xpTheme"></param>
      /// <param name="isLink"></param>
      /// <param name="isHot"></param>
      /// <returns></returns>
      public static Color ItemTextColor(
         ExplorerBarDrawingStyle style,
         XpThemeAPI xpTheme,
         bool isLink,
         bool isHot
         )
      {
         Color returnColor = Color.Empty;
         if (isLink)
         {
            bool classic = (style == ExplorerBarDrawingStyle.Classic);
            if (style == ExplorerBarDrawingStyle.System)
            {
               classic = (xpTheme.hTheme.Equals(IntPtr.Zero));
            }
            if (classic)
            {
               if (isHot)
               {
                  returnColor = Color.FromKnownColor(KnownColor.Highlight);
               }
               else
               {
                  returnColor = Color.FromKnownColor(KnownColor.WindowText);
               }
            }
            else
            {
               if (isHot)
               {
                  returnColor =
                   BlendColor(Color.FromKnownColor(KnownColor.Highlight),
                   Color.Black, 240);
               }
               else
               {
                  returnColor =
                   BlendColor(Color.FromKnownColor(KnownColor.Highlight),
                   Color.Black, 192);
               }
            }
         }
         else
         {
            returnColor  = Color.FromKnownColor(KnownColor.WindowText);
         }
         Debug.Assert(returnColor != Color.Empty, "ItemTextColor failed to
          identify a colour");
         return returnColor;
      }

      /// <summary>
      /// Gets the default title color for a bar
      /// </summary>
      /// <param name="isHot"></param>
      /// <param name="isSpecial"></param>
      /// <param name="style"></param>
      /// <param name="state"></param>
      /// <param name="xpTheme"></param>
      /// <returns></returns>
      public static Color BarTitleColor(
         bool isHot, 
         bool isSpecial, 
         ExplorerBarDrawingStyle style, 
         ExplorerBarState state,
         XpThemeAPI xpTheme
         )
      {
         Color useColor = Color.Empty;


         bool classic = (style == ExplorerBarDrawingStyle.Classic);
         if (style == ExplorerBarDrawingStyle.System)
         {
            if (xpTheme.hTheme.Equals(IntPtr.Zero))
            {
               classic = true;
            }
         }

         if (classic)
         {
            if (isSpecial)
            {
               useColor = Color.FromKnownColor(KnownColor.ActiveCaptionText);
            }
            else
            {
               useColor = Color.FromKnownColor(KnownColor.InactiveCaptionText);
            }
         }
         else // not classic
         {
            if (isSpecial)
            {
               if (isHot)
               {
                  useColor = ExplorerBarHelper.BlendColor(Color.White,
                   Color.FromKnownColor(KnownColor.Highlight), 128);
               }
               else
               {
                  useColor = Color.White;
               }
            }
            else // not special
            {
               if (isHot)
               {
                  useColor =
                   ExplorerBarHelper.BlendColor(Color.FromKnownColor(KnownColor.
                  Highlight), Color.Black, 240);
               }
               else
               {
                  useColor =
                   ExplorerBarHelper.BlendColor(Color.FromKnownColor(KnownColor.
                  Highlight), Color.Black, 192);
               }
            }
         }

         Debug.Assert(useColor != Color.Empty, "BarTitleColor failed to locate
          a colour");
         return useColor;
      }

      /// <summary>
      /// Gets the background colour for a bar
      /// </summary>
      /// <param name="backColor"></param>
      /// <param name="style"></param>
      /// <param name="barBitmaps"></param>
      /// <param name="xpTheme"></param>
      /// <param name="isSpecial"></param>
      /// <returns></returns>
      public static Color BarBackColor(
         Color backColor,
         ExplorerBarDrawingStyle style,
         BarBitmaps barBitmaps,
         XpThemeAPI xpTheme,
         bool isSpecial
         )
      {
         Color useColor = Color.Empty;
         if (style == ExplorerBarDrawingStyle.Classic)
         {
            useColor = Color.FromKnownColor(KnownColor.Window);
         }
         else if (style == ExplorerBarDrawingStyle.System)
         {
            if (xpTheme.hTheme.Equals(IntPtr.Zero))
            {
               // classic
               useColor = Color.FromKnownColor(KnownColor.Window);
            }
            else
            {
               // XP
               if (isSpecial)
               {
                  useColor = barBitmaps.SpecialPanelColor;
               }
               else
               {
                  useColor = barBitmaps.NormalPanelColor;
               }
            }
         }
         else if (style == ExplorerBarDrawingStyle.XP)
         {
            if (isSpecial)
            {
               useColor = barBitmaps.SpecialPanelColor;
            }
            else
            {
               useColor = barBitmaps.NormalPanelColor;
            }
         }
         else
         {
            if (backColor == Color.Empty)
            {
               if (isSpecial)
               {
                  useColor = barBitmaps.SpecialPanelColor;
               }
               else
               {
                  useColor = barBitmaps.NormalPanelColor;
               }
            }
            else
            {
               useColor = backColor;
            }
         }
         return useColor;
      }
      

      /// <summary>
      /// Blends two colours together using the specified alpha amount.
      /// </summary>
      /// <param name="colorFrom">Base colour</param>
      /// <param name="colorTo">Colour to blend with the base colour.</param>
      /// <param name="alpha">Alpha amount to use when blending the
       colours.</param>
      /// <returns>The blended colour.</returns>
      public static Color BlendColor(
         Color colorFrom,
         Color colorTo,
         int alpha
         )
      {
         Color retColor =  Color.FromArgb(
            ((colorFrom.R * alpha) / 255) + ((colorTo.R * (255 - alpha)) /
             255), 
            ((colorFrom.G * alpha) / 255) + ((colorTo.G * (255 - alpha)) /
             255), 
            ((colorFrom.B * alpha) / 255) + ((colorTo.B * (255 - alpha)) / 255)
            );
         return retColor;
      }
   }
}