internal static Color Lookup(string name)
        {
            var colorSet  = Uxtheme.GetImmersiveUserColorSetPreference(false, false);
            var colorType = Uxtheme.GetImmersiveColorTypeFromName(name);
            var rawColor  = Uxtheme.GetImmersiveColorFromColorSetEx(colorSet, colorType, false, 0);

            return(rawColor.ToABGRColor());
        }
Example #2
0
        /// <summary>Draw column in header control.</summary>
        /// <param name="graphicsColumn">The graphics column.</param>
        /// <param name="rectColumn">The rectangle column.</param>
        /// <param name="column">The column.</param>
        /// <param name="theme">The _theme.</param>
        /// <param name="listView">The list View.</param>
        public static void DrawColumnHeader(Graphics graphicsColumn, Rectangle rectColumn, VisualListViewColumn column, IntPtr theme, VisualListViewAdvanced listView)
        {
            DebugTraceManager.WriteDebug("ListViewRenderer::DrawColumnHeader - Name: " + column.Name, DebugTraceManager.DebugOutput.TraceListener);

            if (listView.ControlStyle == LVControlStyles.SuperFlat)
            {
                SolidBrush brush = new SolidBrush(listView.SuperFlatHeaderColor);
                graphicsColumn.FillRectangle(brush, rectColumn);
                brush.Dispose();
            }
            else if ((listView.ControlStyle == LVControlStyles.XP) && listView.ThemesAvailable)
            {
                // this is really the only thing we care about for themeing right now inside the control
                IntPtr hDC = graphicsColumn.GetHdc();

                RECT colrect  = new RECT(rectColumn.X, rectColumn.Y, rectColumn.Right, rectColumn.Bottom);
                RECT cliprect = new RECT(rectColumn.X, rectColumn.Y, rectColumn.Right, rectColumn.Bottom);

                if (column.State == ColumnStates.None)
                {
                    // Debug.WriteLine( "Normal" );
                    Uxtheme.DrawThemeBackground(theme, hDC, 1, 1, ref colrect, ref cliprect);
                }
                else if (column.State == ColumnStates.Pressed)
                {
                    // Debug.WriteLine( "Pressed" );
                    Uxtheme.DrawThemeBackground(theme, hDC, 1, 3, ref colrect, ref cliprect);
                }
                else if (column.State == ColumnStates.Hot)
                {
                    // Debug.WriteLine( "Hot" );
                    Uxtheme.DrawThemeBackground(theme, hDC, 1, 2, ref colrect, ref cliprect);
                }

                graphicsColumn.ReleaseHdc(hDC);
            }
            else
            {
                // normal state
                if (column.State != ColumnStates.Pressed)
                {
                    ControlPaint.DrawButton(graphicsColumn, rectColumn, ButtonState.Normal);
                }
                else
                {
                    ControlPaint.DrawButton(graphicsColumn, rectColumn, ButtonState.Pushed);
                }
            }

            // if there is an image, this routine will RETURN with exactly the space left for everything else after the image is drawn (or not drawn due to lack of space)
            if ((column.ImageIndex > -1) && (listView.ImageListColumns != null) && (column.ImageIndex < listView.ImageListColumns.Images.Count))
            {
                rectColumn = DrawCellGraphic(graphicsColumn, rectColumn, listView.ImageListColumns.Images[column.ImageIndex], HorizontalAlignment.Left, listView.CellPaddingSize, listView);
            }

            DrawCellText(graphicsColumn, rectColumn, column.Text, listView.Font, column.TextAlignment, listView.ForeColor, false, listView);
        }
Example #3
0
        /// <summary>
        /// Get the theme names.
        /// </summary>
        /// <param name="theme">Name of the theme.</param>
        /// <param name="color">Name of the colors.</param>
        /// <param name="size">Name of the size.</param>
        /// <returns>true if theme information was recovered; otherwise false.</returns>
        public static bool GetCurrentThemeName(ref string theme,
                                               ref string color,
                                               ref string size)
        {
            try
            {
                // Create arrays to receive information from call
                char[] themeChars = new char[256];
                char[] colorChars = new char[256];
                char[] sizeChars  = new char[256];

                // Get names back from Uxtheme dll
                Uxtheme.GetCurrentThemeName(themeChars, 255, colorChars, 255, sizeChars, 255);

                int themeLength = 0;
                int colorLength = 0;
                int sizeLength  = 0;

                // Find the number of characters in each returned string
                for (themeLength = 0; themeLength < 256; themeLength++)
                {
                    if (themeChars[themeLength] == 0)
                    {
                        break;
                    }
                }
                for (colorLength = 0; colorLength < 256; colorLength++)
                {
                    if (colorChars[colorLength] == 0)
                    {
                        break;
                    }
                }
                for (sizeLength = 0; sizeLength < 256; sizeLength++)
                {
                    if (sizeChars[sizeLength] == 0)
                    {
                        break;
                    }
                }

                // Return names to caller
                theme = new string(themeChars, 0, themeLength);
                color = new string(colorChars, 0, colorLength);
                size  = new string(sizeChars, 0, sizeLength);

                return(true);
            }
            catch
            {
                // Any exception is because the Uxtheme.dll does not
                // exist, in which case the application is not themed
                return(false);
            }
        }
Example #4
0
        /// <summary>Calls <see cref="Uxtheme.SetWindowThemeAttribute" /> to set various attributes on the window.</summary>
        /// <param name="attributes">Attributes to set on the window.</param>
        private void SetWindowThemeAttributes(WTNCA attributes)
        {
            WTA_OPTIONS options = new WTA_OPTIONS
            {
                dwFlags = attributes,
                dwMask  = WTNCA.VALIDBITS
            };

            // The SetWindowThemeAttribute API call takes care of everything
            Uxtheme.SetWindowThemeAttribute(Handle, WINDOWTHEMEATTRIBUTETYPE.WTA_NONCLIENT, ref options, (uint)Marshal.SizeOf(typeof(WTA_OPTIONS)));
        }
Example #5
0
        public static bool TryLookup(string name, out Color color)
        {
            color = default(Color);

            var colorSet  = Uxtheme.GetImmersiveUserColorSetPreference(false, false);
            var colorType = Uxtheme.GetImmersiveColorTypeFromName(name);
            var rawColor  = Uxtheme.GetImmersiveColorFromColorSetEx(colorSet, colorType, false, 0);

            color = rawColor.ToABGRColor();
            return(rawColor != 4294902015);
        }
Example #6
0
        private void OpenTheme()
        {
            // Can onyl create theme information if themes are active
            if (IsAppThemed && IsThemeActive)
            {
                // Attempt to create theme data for control, of provided class type
                _hTheme = Uxtheme.OpenThemeData(_control.Handle, _classList);

                // Raises event
                OnThemeOpened();
            }
        }
Example #7
0
        private void CloseTheme()
        {
            // Must close down theme handle
            if (IsControlThemed)
            {
                // Close down the Win32 handle
                Uxtheme.CloseThemeData(_hTheme);

                // No longer have a valid theme handle
                _hTheme = IntPtr.Zero;

                // Raises event
                OnThemeClosed();
            }
        }
Example #8
0
        /// <summary>
        /// Draw a themed background element.
        /// </summary>
        /// <param name="g">Graphics object reference.</param>
        /// <param name="draw">Rectangle for drawing.</param>
        /// <param name="exclude">Rectangle to exclude from drawing.</param>
        /// <param name="part">Theme part.</param>
        /// <param name="state">Theme state of part.</param>
        public void DrawThemeBackground(Graphics g, Rectangle draw, Rectangle exclude, int part, int state)
        {
            if (IsControlThemed)
            {
                // Create a Win32 version of the drawing Rectangle
                Win32.RECT drawWin32 = new Win32.RECT();
                drawWin32.left   = draw.X;
                drawWin32.top    = draw.Y;
                drawWin32.right  = draw.Right;
                drawWin32.bottom = draw.Bottom;

                // Create a Win32 version of the clipping Rectangle
                Win32.RECT excludeWin32 = new Win32.RECT();
                excludeWin32.left   = exclude.X;
                excludeWin32.top    = exclude.Y;
                excludeWin32.right  = exclude.Right;
                excludeWin32.bottom = exclude.Bottom;

                // Get access to the underlying HDC
                IntPtr hDC = g.GetHdc();

                // Make a note of the original clipping region
                IntPtr hOldClipRgn = IntPtr.Zero;
                Gdi32.GetClipRgn(hDC, ref hOldClipRgn);

                // Create region that excludes area from drawing rectangle
                IntPtr hDrawRgn    = Gdi32.CreateRectRgnIndirect(ref drawWin32);
                IntPtr hExcludeRgn = Gdi32.CreateRectRgnIndirect(ref excludeWin32);
                Gdi32.CombineRgn(hExcludeRgn, hDrawRgn, hExcludeRgn, (int)CombineFlags.RGN_DIFF);

                // Define required clipping rectangle
                Gdi32.SelectClipRgn(hDC, hExcludeRgn);

                // Perform actual drawing work
                Uxtheme.DrawThemeBackground(_hTheme, hDC, part, state, ref drawWin32, IntPtr.Zero);

                // Put clipping region back again
                Gdi32.SelectClipRgn(hDC, hOldClipRgn);

                // Delete objects no longer needed
                Gdi32.DeleteObject(hDrawRgn);
                Gdi32.DeleteObject(hExcludeRgn);

                // Must release the resource to prevent leaks!
                g.ReleaseHdc(hDC);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public static Color GetThemeBorderColor(Color substituteColor)
        {
            Int32 color = 0;

            // UxTheme is only supported on Windows XP and Later
            if (Environment.OSVersion.Version.Major >= 5 &&
                Environment.OSVersion.Version.Minor >= 1)
            {
                IntPtr hTheme = Uxtheme.OpenThemeData(IntPtr.Zero, "Edit");
                if (hTheme != IntPtr.Zero)
                {
                    Uxtheme.GetThemeColor(hTheme, Uxtheme.EP.EDITTEXT, Uxtheme.ETS.NORMAL, Uxtheme.TMT.BORDERCOLOR, out color);
                    Uxtheme.CloseThemeData(hTheme);
                }
            }
            return(color == 0 ? substituteColor : ColorTranslator.FromWin32(color));
        }
        internal static IDictionary <string, Color> GetList()
        {
            var colors   = new Dictionary <string, Color>();
            var colorSet = Uxtheme.GetImmersiveUserColorSetPreference(false, false);

            for (uint i = 0; ; i++)
            {
                var ptr = Uxtheme.GetImmersiveColorNamedTypeByIndex(i);
                if (ptr == IntPtr.Zero)
                {
                    break;
                }

                var name = Marshal.PtrToStringUni(Marshal.ReadIntPtr(ptr));
                colors.Add(name, Lookup($"Immersive{name}"));
            }

            return(colors);
        }
Example #11
0
        /// <summary>
        /// Get the size of a themed part in a givenstate.
        /// </summary>
        /// <param name="g">Graphics object reference.</param>
        /// <param name="part">Theme part.</param>
        /// <param name="state">Theme state of part.</param>
        /// <param name="themeSize">How to calculate the size.</param>
        /// <returns>new Size if themed; otherwise Size.Empty</returns>
        public Size GetThemePartSize(Graphics g, int part, int state, THEMESIZE themeSize)
        {
            Size retSize = Size.Empty;

            if (IsControlThemed)
            {
                Win32.SIZE size = new Win32.SIZE();

                IntPtr hDC = g.GetHdc();
                Uxtheme.GetThemePartSize(_hTheme, hDC, part, state, IntPtr.Zero, themeSize, ref size);
                g.ReleaseHdc(hDC);

                // Copy back results
                retSize.Width  = size.cx;
                retSize.Height = size.cy;
            }

            return(retSize);
        }
Example #12
0
        /// <summary>
        /// Converts a buffer to PARGB32.
        /// </summary>
        /// <param name="hPaintBuffer">The paint buffer handle.</param>
        /// <param name="hdc">The device context handle.</param>
        /// <param name="iconHandle">The icon handle.</param>
        /// <param name="iconSize">The icon size.</param>
        private static void ConvertBufferToPARGB32(IntPtr hPaintBuffer, IntPtr hdc, IntPtr iconHandle, Size iconSize)
        {
            //  Get the actual paint bits of the buffer. If this fails, we return.
            IntPtr prgbQuad;
            int    cxRow;
            var    hr = Uxtheme.GetBufferedPaintBits(hPaintBuffer, out prgbQuad, out cxRow);

            if (hr != WinError.S_OK)
            {
                return;
            }

            unsafe
            {
                //  Get the pointer to the bits.
                var pargb = (UInt32 *)prgbQuad.ToPointer();

                //  If out pixels have any alpha values, we're done.
                if (HasAlpha(pargb, iconSize, cxRow))
                {
                    return;
                }

                //  As we don't have alpha values, we need to get the icon info for
                //  a mask image.
                ICONINFO info;
                if (!User32.GetIconInfo(iconHandle, out info))
                {
                    return;
                }

                //  If there's a mask, we can apply it.
                if (info.MaskBitmap != IntPtr.Zero)
                {
                    ConvertToPARGB32(hdc, pargb, info.MaskBitmap, iconSize, cxRow);
                }

                //  Free the icon info and we're done.
                Gdi32.DeleteObject(info.ColorBitmap);
                Gdi32.DeleteObject(info.MaskBitmap);
            }
        }
Example #13
0
        /// <summary>
        /// Draw a themed background element.
        /// </summary>
        /// <param name="g">Graphics object reference.</param>
        /// <param name="draw">Rectangle for drawing.</param>
        /// <param name="part">Theme part.</param>
        /// <param name="state">Theme state of part.</param>
        public void DrawThemeBackground(Graphics g, Rectangle draw, int part, int state)
        {
            if (IsControlThemed)
            {
                // Create a Win32 version of the drawing Rectangle
                Win32.RECT drawWin32 = new Win32.RECT();
                drawWin32.left   = draw.X;
                drawWin32.top    = draw.Y;
                drawWin32.right  = draw.Right;
                drawWin32.bottom = draw.Bottom;

                // Get access to the underlying HDC
                IntPtr hDC = g.GetHdc();

                // Perform actual drawing work
                Uxtheme.DrawThemeBackground(_hTheme, hDC, part, state, ref drawWin32, IntPtr.Zero);

                // Must release the resource to prevent leaks!
                g.ReleaseHdc(hDC);
            }
        }
Example #14
0
        /// <summary>Draw the column header.</summary>
        /// <param name="graphicsColumn">The graphics column.</param>
        /// <param name="columnRectangle">The rectangle column.</param>
        /// <param name="column">The column.</param>
        /// <param name="theme">The theme.</param>
        /// <param name="listView">The list View.</param>
        public static void DrawColumnHeader(Graphics graphicsColumn, Rectangle columnRectangle, VisualListViewColumn column, IntPtr theme, VisualListView listView)
        {
            ConsoleEx.WriteDebug("ListViewRenderer::DrawColumnHeader - Text: " + column.Text);

            if (listView.ControlStyle == LVControlStyles.SuperFlat)
            {
                SolidBrush columnRectangleBrush;

                if (column.State == ColumnStates.None)
                {
                    columnRectangleBrush = new SolidBrush(listView.ColumnColorState.Enabled);
                    graphicsColumn.FillRectangle(columnRectangleBrush, columnRectangle);
                }
                else if (column.State == ColumnStates.Pressed)
                {
                    columnRectangleBrush = new SolidBrush(listView.ColumnColorState.Pressed);
                    graphicsColumn.FillRectangle(columnRectangleBrush, columnRectangle);
                }
                else if (column.State == ColumnStates.Hover)
                {
                    columnRectangleBrush = new SolidBrush(listView.ColumnColorState.Hover);
                    graphicsColumn.FillRectangle(columnRectangleBrush, columnRectangle);
                }
            }
            else if ((listView.ControlStyle == LVControlStyles.XP) && listView.ThemesAvailable)
            {
                // This is really the only thing we care about for theme right now inside the control.
                IntPtr hDC = graphicsColumn.GetHdc();

                RECT _columnRect = new RECT(columnRectangle.X, columnRectangle.Y, columnRectangle.Right, columnRectangle.Bottom);
                RECT _clipRect   = new RECT(columnRectangle.X, columnRectangle.Y, columnRectangle.Right, columnRectangle.Bottom);

                if (column.State == ColumnStates.None)
                {
                    // Normal.
                    Uxtheme.DrawThemeBackground(theme, hDC, 1, 1, ref _columnRect, ref _clipRect);
                }
                else if (column.State == ColumnStates.Pressed)
                {
                    // Pressed
                    Uxtheme.DrawThemeBackground(theme, hDC, 1, 3, ref _columnRect, ref _clipRect);
                }
                else if (column.State == ColumnStates.Hover)
                {
                    // Hover
                    Uxtheme.DrawThemeBackground(theme, hDC, 1, 2, ref _columnRect, ref _clipRect);
                }

                graphicsColumn.ReleaseHdc(hDC);
            }
            else
            {
                // Normal state.
                if (column.State != ColumnStates.Pressed)
                {
                    ControlPaint.DrawButton(graphicsColumn, columnRectangle, ButtonState.Normal);
                }
                else
                {
                    ControlPaint.DrawButton(graphicsColumn, columnRectangle, ButtonState.Pushed);
                }
            }

            // Check if we need checkboxes in this column.
            if (column.CheckBox)
            {
                columnRectangle = DrawCheckBox(graphicsColumn, columnRectangle, column.Checked, ListViewConstants.CHECKBOX_SIZE, listView);
            }

            // If there is an image, this routine will RETURN with exactly the space left for everything else after the image is drawn (or not drawn due to lack of space).
            if ((column.ImageIndex > -1) && (listView.ImageListColumns != null) && (column.ImageIndex < listView.ImageListColumns.Images.Count))
            {
                columnRectangle = DrawCellGraphic(graphicsColumn, columnRectangle, listView.ImageListColumns.Images[column.ImageIndex], HorizontalAlignment.Left, listView.CellPaddingSize, listView);
            }

            DrawCellText(graphicsColumn, columnRectangle, column.Text, listView.Font, column.TextAlignment, listView.ForeColor, false, listView);
        }
Example #15
0
        /// <summary>
        /// Creates a handle to a PARGB32 bitmap from an Icon.
        /// </summary>
        /// <param name="iconHandle">The handle to the icon.</param>
        /// <param name="iconSize">The iconSize of the icon.</param>
        /// <returns>A PARGB32 bitmap with the contents of the icon, including transparency.</returns>
        public static IntPtr CreatePARGB32HBitmap(IntPtr iconHandle, Size iconSize)
        {
            //  Make sure we're ready for buffered painting.
            //  TODO: Really we only need to do this once per thread, so an improvement
            //  might be to have a manager create this as required per thread.
            Uxtheme.BufferedPaintInit();

            //  Create a compatible device context to work with.
            var deviceContextHandle = Gdi32.CreateCompatibleDC(IntPtr.Zero);

            if (deviceContextHandle == IntPtr.Zero)
            {
                return(IntPtr.Zero);
            }

            //  Now create a 32 bit bitmap of the appropriate size, getting it's bits and handle.
            IntPtr bits;
            IntPtr hBitmap;

            if (!Create32BitHBITMAP(deviceContextHandle, iconSize, out bits, out hBitmap))
            {
                Gdi32.DeleteDC(deviceContextHandle);
                return(IntPtr.Zero);
            }

            //  Select the bitmap, keeping track of the old one. If this fails,
            //  delete the device context and return a null handle.
            var oldBitmapHandle = Gdi32.SelectObject(deviceContextHandle, hBitmap);

            if (oldBitmapHandle == IntPtr.Zero)
            {
                Gdi32.DeleteDC(deviceContextHandle);
                return(IntPtr.Zero);
            }

            //  Create paint params that represent our alpha blending.
            var bfAlpha = new BLENDFUNCTION
            {
                BlendOp             = AC_SRC_OVER,
                BlendFlags          = 0,
                SourceConstantAlpha = 255,
                AlphaFormat         = AC_SRC_ALPHA
            };
            var paintParams = new BP_PAINTPARAMS();

            paintParams.cbSize         = (uint)Marshal.SizeOf(paintParams);
            paintParams.dwFlags        = BPPF_ERASE;
            paintParams.pBlendFunction = Marshal.AllocHGlobal(Marshal.SizeOf(bfAlpha));
            Marshal.StructureToPtr(bfAlpha, paintParams.pBlendFunction, false);

            //  Create the pointer that'll hold the device context to the buffer, set the icon rectangle.
            IntPtr bufferDeviceContextHandle;
            var    iconRect = new RECT(0, 0, iconSize.Width, iconSize.Height);

            //  Create a paint buffer handle.
            var paintBufferHandle = Uxtheme.BeginBufferedPaint(deviceContextHandle, ref iconRect,
                                                               BP_BUFFERFORMAT.BPBF_DIB, ref paintParams, out bufferDeviceContextHandle);

            //  Free the memory we allocated for the blend function.
            Marshal.FreeHGlobal(paintParams.pBlendFunction);

            //  If we created a paint buffer successfully, we can draw the icon into it.
            if (paintBufferHandle != IntPtr.Zero)
            {
                //  Try and draw the icon.
                if (Gdi32.DrawIconEx(bufferDeviceContextHandle, 0, 0, iconHandle, iconSize.Width, iconSize.Height, 0, IntPtr.Zero,
                                     (int)DI_NORMAL))
                {
                    //  Now convert the buffer we've painted into PARGB32, meaning we'll end up
                    //  with a PARGB32 bitmap.
                    ConvertBufferToPARGB32(paintBufferHandle, deviceContextHandle, iconHandle, iconSize);
                }

                // This will write the buffer contents to the destination bitmap.
                Uxtheme.EndBufferedPaint(paintBufferHandle, true);
            }

            //  Select the old bitmpa and delete the device context.
            Gdi32.SelectObject(deviceContextHandle, oldBitmapHandle);
            Gdi32.DeleteDC(deviceContextHandle);

            //  We're done with buffered painting.
            Uxtheme.BufferedPaintUnInit();

            //  Baddabing-baddabom, PARGB32.
            return(hBitmap);
        }