using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Vanara.Extensions;
using Vanara.PInvoke;
using static Vanara.PInvoke.Gdi32;
using static Vanara.PInvoke.Kernel32;
using static Vanara.PInvoke.User32;
using static Vanara.PInvoke.UxTheme;
namespace Vanara.Windows.Forms
{
/// A wrapper around the UxTheme methods.
///
public class VisualTheme : IDisposable
{
/// Initializes a new instance of the class.
/// A semicolon-separated list of class names to match.
/// Optional flags that control how to return the theme data.
public VisualTheme(string classList, OpenThemeDataOptions opt = OpenThemeDataOptions.None) : this(null, classList, opt) { }
/// Initializes a new instance of the class.
/// A handle to a theme (HTHEME). This handle will not be freed on disposal.
public VisualTheme(IntPtr handle)
{
Handle = new SafeHTHEME(handle, false);
}
/// Initializes a new instance of the class.
/// A window or control that the theme is to be retrieved from. This value can be null.
/// A semicolon-separated list of class names to match.
/// Optional flags that control how to return the theme data.
///
public VisualTheme(IWin32Window window, string classList, OpenThemeDataOptions opt = OpenThemeDataOptions.None)
{
Handle = OpenThemeDataEx(window?.Handle ?? HWND.NULL, classList, opt);
if (Handle.IsInvalid)
throw new Win32Exception();
}
/// Properties accessible via .
public enum BitmapProperty
{
/// The background image
BackgroundImage = ThemeProperty.TMT_DIBDATA,
/// The glyph image drawn on top of the background, if present.
GlyphImage = ThemeProperty.TMT_GLYPHDIBDATA,
/// Not currently supported.
Handle = ThemeProperty.TMT_HBITMAP,
}
/// Properties accessible via .
public enum BoolProperty
{
/// TRUE if the sizing bar associated with the part and state should always be shown.
AlwaysShowSizingBar = ThemeProperty.TMT_ALWAYSSHOWSIZINGBAR,
/// TRUE if the nonclient caption area associated with the part and state vary with text width.
AutoSize = ThemeProperty.TMT_AUTOSIZE,
/// TRUE if true-sized images associated with the part and state are to be drawn on the background fill.
BackgroundFill = ThemeProperty.TMT_BGFILL,
/// TRUE if the image associated with the part and state should only have its border drawn.
BorderOnly = ThemeProperty.TMT_BORDERONLY,
/// TRUE if the control associated with the part and state will handle its own compositing of images.
Composited = ThemeProperty.TMT_COMPOSITED,
/// TMT_COMPOSITEDOPAQUE
CompositedOpaque = ThemeProperty.TMT_COMPOSITEDOPAQUE,
/// TMT_DRAWBORDERS
DrawBorders = ThemeProperty.TMT_DRAWBORDERS,
/// Describes how menus are drawn. If true, menus are drawn without shadows. If false, menus have shadows underneath them.
FlatMenus = ThemeProperty.TMT_FLATMENUS,
/// TRUE if the glyph associated with the part and state should be drawn without a background.
GlyphOnly = ThemeProperty.TMT_GLYPHONLY,
///
/// TRUE if the glyph associated with the part and state have transparent areas. See GetThemeColor for the definition of the TMT_GLYPHCOLOR value
/// that defines the transparent color.
///
GlyphTransparent = ThemeProperty.TMT_GLYPHTRANSPARENT,
/// TRUE if the truesize image or border associated with the part and state must be sized to a factor of 2.
IntegralSizing = ThemeProperty.TMT_INTEGRALSIZING,
/// TMT_LOCALIZEDMIRRORIMAGE
LocalizedMirrorImage = ThemeProperty.TMT_LOCALIZEDMIRRORIMAGE,
/// TRUE if the image associated with the part and state should be flipped if the window is being viewed in right-to-left reading mode.
MirrorImage = ThemeProperty.TMT_MIRRORIMAGE,
/// TMT_NOETCHEDEFFECT
NoEtchedEffect = ThemeProperty.TMT_NOETCHEDEFFECT,
/// TMT_SCALEDBACKGROUND
ScaledBackground = ThemeProperty.TMT_SCALEDBACKGROUND,
/// TRUE if the image associated with the part and state will scale larger in size if necessary.
SourceGrow = ThemeProperty.TMT_SOURCEGROW,
/// TRUE if the image associated with the part and state will scale smaller in size if necessary.
SourceShrink = ThemeProperty.TMT_SOURCESHRINK,
/// TMT_TEXTAPPLYOVERLAY
TextApplyOverlay = ThemeProperty.TMT_TEXTAPPLYOVERLAY,
///
TextGlow = ThemeProperty.TMT_TEXTGLOW,
///
TextItalic = ThemeProperty.TMT_TEXTITALIC,
///
Transparent = ThemeProperty.TMT_TRANSPARENT,
/// TRUE if the image associated with the part and state must have equal height and width.
UniformSizing = ThemeProperty.TMT_UNIFORMSIZING,
/// TRUE if the image associated with the part and state is based on the current user.
UserPicture = ThemeProperty.TMT_USERPICTURE,
}
/// Properties accessible via .
public enum ColorProperty
{
/// The color used as an accent color hint for custom controls.
AccentColorHint = ThemeProperty.TMT_ACCENTCOLORHINT,
/// TMT_ACTIVEBORDER
ActiveBorder = ThemeProperty.TMT_ACTIVEBORDER,
/// TMT_ACTIVECAPTION
ActiveCaption = ThemeProperty.TMT_ACTIVECAPTION,
/// TMT_APPWORKSPACE
AppWorkspace = ThemeProperty.TMT_APPWORKSPACE,
/// TMT_BACKGROUND
Background = ThemeProperty.TMT_BACKGROUND,
/// The color used as a blend color.
BlendColor = ThemeProperty.TMT_BLENDCOLOR,
/// TMT_BODYTEXTCOLOR
BodyTextColor = ThemeProperty.TMT_BODYTEXTCOLOR,
/// The color of the border associated with the part and state.
BorderColor = ThemeProperty.TMT_BORDERCOLOR,
/// The color used as a border color hint for custom controls.
BorderColorHint = ThemeProperty.TMT_BORDERCOLORHINT,
/// TMT_BTNFACE
ButtonFace = ThemeProperty.TMT_BTNFACE,
/// TMT_BTNHIGHLIGHT
ButtonHighlight = ThemeProperty.TMT_BTNHIGHLIGHT,
/// TMT_BTNSHADOW
ButtonShadow = ThemeProperty.TMT_BTNSHADOW,
/// TMT_BTNTEXT
ButtonText = ThemeProperty.TMT_BTNTEXT,
/// TMT_BUTTONALTERNATEFACE
ButtonAlternateFace = ThemeProperty.TMT_BUTTONALTERNATEFACE,
/// TMT_CAPTIONTEXT
CaptionText = ThemeProperty.TMT_CAPTIONTEXT,
/// TMT_DKSHADOW3D
DarkShadow3D = ThemeProperty.TMT_DKSHADOW3D,
/// The dark shadow color of the edge associated with this part and state.
EdgeDarkShadowColor = ThemeProperty.TMT_EDGEDKSHADOWCOLOR,
/// The fill color of the edge associated with this part and state.
EdgeFillColor = ThemeProperty.TMT_EDGEFILLCOLOR,
/// The highlight color of the edge associated with this part and state.
EdgeHighlightColor = ThemeProperty.TMT_EDGEHIGHLIGHTCOLOR,
/// The light color of the edge associated with this part and state.
EdgeLightColor = ThemeProperty.TMT_EDGELIGHTCOLOR,
/// The shadow color of the edge associated with this part and state.
EdgeShadowColor = ThemeProperty.TMT_EDGESHADOWCOLOR,
/// The color of the background fill associated with the part and state.
FillColor = ThemeProperty.TMT_FILLCOLOR,
/// The color used as a fill color hint for custom controls.
FillColorHint = ThemeProperty.TMT_FILLCOLORHINT,
/// TMT_FROMCOLOR1
FromColor1 = ThemeProperty.TMT_FROMCOLOR1,
/// TMT_FROMCOLOR2
FromColor2 = ThemeProperty.TMT_FROMCOLOR2,
/// TMT_FROMCOLOR3
FromColor3 = ThemeProperty.TMT_FROMCOLOR3,
/// TMT_FROMCOLOR4
FromColor4 = ThemeProperty.TMT_FROMCOLOR4,
/// TMT_FROMCOLOR5
FromColor5 = ThemeProperty.TMT_FROMCOLOR5,
/// The color of the glow produced by calling DrawThemeIcon using this part and state.
GlowColor = ThemeProperty.TMT_GLOWCOLOR,
/// The color that the font-based glyph associated with this part and state will use.
GlyphTextColor = ThemeProperty.TMT_GLYPHTEXTCOLOR,
///
/// The transparent glyph color associated with this part and state. If the TMT_GLYPHTRANSPARENT value for this part and state is TRUE, parts of the
/// glyph that use this color are not drawn.
///
GlyphTransparentColor = ThemeProperty.TMT_GLYPHTRANSPARENTCOLOR,
/// TMT_GRADIENTACTIVECAPTION
GradientActiveCaption = ThemeProperty.TMT_GRADIENTACTIVECAPTION,
/// The first color of the gradient associated with this part and state.
GradientColor1 = ThemeProperty.TMT_GRADIENTCOLOR1,
/// The second color of the gradient.
GradientColor2 = ThemeProperty.TMT_GRADIENTCOLOR2,
/// The third color of the gradient.
GradientColor3 = ThemeProperty.TMT_GRADIENTCOLOR3,
/// The fourth color of the gradient.
GradientColor4 = ThemeProperty.TMT_GRADIENTCOLOR4,
/// The fifth color of the gradient.
GradientColor5 = ThemeProperty.TMT_GRADIENTCOLOR5,
/// TMT_GRADIENTINACTIVECAPTION
GradientInactiveCaption = ThemeProperty.TMT_GRADIENTINACTIVECAPTION,
/// TMT_GRAYTEXT
GrayText = ThemeProperty.TMT_GRAYTEXT,
/// TMT_HEADING1TEXTCOLOR
Heading1TextColor = ThemeProperty.TMT_HEADING1TEXTCOLOR,
/// TMT_HEADING2TEXTCOLOR
Heading2TextColor = ThemeProperty.TMT_HEADING2TEXTCOLOR,
/// TMT_HIGHLIGHT
Highlight = ThemeProperty.TMT_HIGHLIGHT,
/// TMT_HIGHLIGHTTEXT
HighlightText = ThemeProperty.TMT_HIGHLIGHTTEXT,
/// TMT_HOTTRACKING
HotTracking = ThemeProperty.TMT_HOTTRACKING,
/// TMT_INACTIVEBORDER
InactiveBorder = ThemeProperty.TMT_INACTIVEBORDER,
/// TMT_INACTIVECAPTION
InactiveCaption = ThemeProperty.TMT_INACTIVECAPTION,
/// TMT_INACTIVECAPTIONTEXT
InactiveCaptionText = ThemeProperty.TMT_INACTIVECAPTIONTEXT,
/// TMT_INFOBK
InfoBackground = ThemeProperty.TMT_INFOBK,
/// TMT_INFOTEXT
InfoText = ThemeProperty.TMT_INFOTEXT,
/// TMT_LIGHT3D
Light3D = ThemeProperty.TMT_LIGHT3D,
/// TMT_MENU
Menu = ThemeProperty.TMT_MENU,
/// TMT_MENUBAR
MenuBar = ThemeProperty.TMT_MENUBAR,
/// TMT_MENUHILIGHT
MenuHilight = ThemeProperty.TMT_MENUHILIGHT,
/// TMT_MENUTEXT
MenuText = ThemeProperty.TMT_MENUTEXT,
/// TMT_SCROLLBAR
ScrollBar = ThemeProperty.TMT_SCROLLBAR,
/// The color of the shadow drawn underneath text associated with this part and state.
ShadowColor = ThemeProperty.TMT_SHADOWCOLOR,
/// The color of the text border associated with this part and state.
TextBorderColor = ThemeProperty.TMT_TEXTBORDERCOLOR,
/// The color of the text associated with this part and state.
TextColor = ThemeProperty.TMT_TEXTCOLOR,
/// TMT_TEXTCOLORHINT
TextColorHint = ThemeProperty.TMT_TEXTCOLORHINT,
/// The color of the text shadow associated with this part and state.
TextShadowColor = ThemeProperty.TMT_TEXTSHADOWCOLOR,
///
/// The transparent color associated with this part and state. If the TMT_TRANSPARENT value for this part and state is TRUE, parts of the graphic
/// that use this color are not drawn.
///
TransparentColor = ThemeProperty.TMT_TRANSPARENTCOLOR,
/// TMT_WINDOW
Window = ThemeProperty.TMT_WINDOW,
/// TMT_WINDOWFRAME
WindowFrame = ThemeProperty.TMT_WINDOWFRAME,
/// TMT_WINDOWTEXT
WindowText = ThemeProperty.TMT_WINDOWTEXT,
}
/// Properties accessible via GetEnumValue.
public enum EnumProperty
{
/// The basic drawing type for this part.
BackgroundType = ThemeProperty.TMT_BGTYPE,
/// The type of border drawn if this part is a border fill.
BorderType = ThemeProperty.TMT_BORDERTYPE,
/// The alignment of text in the caption associated with this part.
ContentAlignment = ThemeProperty.TMT_CONTENTALIGNMENT,
/// The type of fill shape drawn if this part is a border fill.
FillType = ThemeProperty.TMT_FILLTYPE,
/// The type of glyph drawn on this part.
GlyphType = ThemeProperty.TMT_GLYPHTYPE,
/// The type of method used to select between different-sized glyphs.
GlyphFontSizingType = ThemeProperty.TMT_GLYPHFONTSIZINGTYPE,
/// The horizontal alignment if this part uses a true-size image.
HAlign = ThemeProperty.TMT_HALIGN,
/// The type of effect to be displayed when this part is drawn using DrawThemeIcon.
IconEffect = ThemeProperty.TMT_ICONEFFECT,
/// The type of alignment used when multiple images are drawn.
ImageLayout = ThemeProperty.TMT_IMAGELAYOUT,
/// The type of method used to select between sized images for this part. See the TMT_IMAGEFILE1 value of GetThemeFilename.
ImageSelectType = ThemeProperty.TMT_IMAGESELECTTYPE,
/// The alignment of this part on the window.
OffsetType = ThemeProperty.TMT_OFFSETTYPE,
/// The method used to size an image if this part uses an image file.
SizingType = ThemeProperty.TMT_SIZINGTYPE,
/// The type of shadow effect to draw behind text associated with this part.
TextShadowType = ThemeProperty.TMT_TEXTSHADOWTYPE,
/// The type of scaling used if this part uses a true-sized image.
TrueSizeScalingType = ThemeProperty.TMT_TRUESIZESCALINGTYPE,
/// The vertical alignment if this part uses a true-size image.
VAlign = ThemeProperty.TMT_VALIGN,
}
/// Properties accessible via .
public enum FilenameProperty
{
/// The filename for the glyph image associated with this part and state.
GlyphImageFile = ThemeProperty.TMT_GLYPHIMAGEFILE,
///
/// The filename of the image associated with this part and state, or the base filename for multiple images associated with this part and state.
///
ImageFile = ThemeProperty.TMT_IMAGEFILE,
/// The filename of the first scaled image associated with this part and state, for support of different resolutions.
ImageFile1 = ThemeProperty.TMT_IMAGEFILE1,
/// The filename of the second scaled image.
ImageFile2 = ThemeProperty.TMT_IMAGEFILE2,
/// The filename of the third scaled image.
ImageFile3 = ThemeProperty.TMT_IMAGEFILE3,
/// The filename of the fourth scaled image.
ImageFile4 = ThemeProperty.TMT_IMAGEFILE4,
/// The filename of the fifth scaled image.
ImageFile5 = ThemeProperty.TMT_IMAGEFILE5,
}
/// Properties accessible via .
public enum FontProperty
{
/// TMT_BODYFONT
Body = ThemeProperty.TMT_BODYFONT,
/// The font that the glyph associated with this part will be drawn with, if font-based glyphs are used.
Glyph = ThemeProperty.TMT_GLYPHFONT,
/// TMT_HEADING1FONT
Heading1 = ThemeProperty.TMT_HEADING1FONT,
/// TMT_HEADING2FONT
Heading2 = ThemeProperty.TMT_HEADING2FONT,
///
Caption = ThemeProperty.TMT_CAPTIONFONT,
/// TMT_ICONTITLEFONT
IconTitle = ThemeProperty.TMT_ICONTITLEFONT,
/// TMT_MENUFONT
Menu = ThemeProperty.TMT_MENUFONT,
/// TMT_MSGBOXFONT
MessageBox = ThemeProperty.TMT_MSGBOXFONT,
/// TMT_SMALLCAPTIONFONT
SmallCaption = ThemeProperty.TMT_SMALLCAPTIONFONT,
/// TMT_STATUSFONT
Status = ThemeProperty.TMT_STATUSFONT,
}
/// Properties accessible via .
public enum IntProperty
{
/// TMT_ANIMATIONDELAY
AnimationDelay = ThemeProperty.TMT_ANIMATIONDELAY,
/// TMT_ANIMATIONDURATION
AnimationDuration = ThemeProperty.TMT_ANIMATIONDURATION,
/// TMT_CHARSET
CharSet = ThemeProperty.TMT_CHARSET,
/// TMT_COLORIZATIONCOLOR
ColorizationColor = ThemeProperty.TMT_COLORIZATIONCOLOR,
/// TMT_COLORIZATIONOPACITY
ColorizationOpacity = ThemeProperty.TMT_COLORIZATIONOPACITY,
/// TMT_FRAMESPERSECOND
FramesPerSecond = ThemeProperty.TMT_FRAMESPERSECOND,
/// TMT_FROMHUE1
FromHue1 = ThemeProperty.TMT_FROMHUE1,
/// TMT_FROMHUE2
FromHue2 = ThemeProperty.TMT_FROMHUE2,
/// TMT_FROMHUE3
FromHue3 = ThemeProperty.TMT_FROMHUE3,
/// TMT_FROMHUE4
FromHue4 = ThemeProperty.TMT_FROMHUE4,
/// TMT_FROMHUE5
FromHue5 = ThemeProperty.TMT_FROMHUE5,
/// TMT_GLOWINTENSITY
GlowIntensity = ThemeProperty.TMT_GLOWINTENSITY,
/// Gets the minimum color depth, in bits, required to properly view this style.
MinimumColorDepth = ThemeProperty.TMT_MINCOLORDEPTH,
/// TMT_OPACITY
Opacity = ThemeProperty.TMT_OPACITY,
/// TMT_PIXELSPERFRAME
PixelsPerFrame = ThemeProperty.TMT_PIXELSPERFRAME,
/// TMT_TEXTGLOWSIZE
TextGlowSize = ThemeProperty.TMT_TEXTGLOWSIZE,
/// TMT_TOCOLOR1
ToColor1 = ThemeProperty.TMT_TOCOLOR1,
/// TMT_TOCOLOR2
ToColor2 = ThemeProperty.TMT_TOCOLOR2,
/// TMT_TOCOLOR3
ToColor3 = ThemeProperty.TMT_TOCOLOR3,
/// TMT_TOCOLOR4
ToColor4 = ThemeProperty.TMT_TOCOLOR4,
/// TMT_TOCOLOR5
ToColor5 = ThemeProperty.TMT_TOCOLOR5,
/// TMT_TOHUE1
ToHue1 = ThemeProperty.TMT_TOHUE1,
/// TMT_TOHUE2
ToHue2 = ThemeProperty.TMT_TOHUE2,
/// TMT_TOHUE3
ToHue3 = ThemeProperty.TMT_TOHUE3,
/// TMT_TOHUE4
ToHue4 = ThemeProperty.TMT_TOHUE4,
/// TMT_TOHUE5
ToHue5 = ThemeProperty.TMT_TOHUE5,
}
/// Properties accessible via .
public enum MarginsProperty
{
/// The margins that define where caption text may be placed within a part.
Caption = ThemeProperty.TMT_CAPTIONMARGINS,
/// The margins that define where content may be placed within a part.
Content = ThemeProperty.TMT_CONTENTMARGINS,
/// The margins used for sizing a non-true-size image.
Sizing = ThemeProperty.TMT_SIZINGMARGINS,
}
/// Properties accessible via .
public enum MetricProperty
{
/// The alpha value (0-255) used for DrawThemeIcon.
AlphaLevel = ThemeProperty.TMT_ALPHALEVEL,
/// The minimum alpha value (0-255) that a pixel must have to be considered opaque.
AlphaThreshold = ThemeProperty.TMT_ALPHATHRESHOLD,
/// The thickness of the border drawn if this part uses a border fill.
BorderSize = ThemeProperty.TMT_BORDERSIZE,
/// The character index into the selected font that will be used for the glyph, if the part uses a font-based glyph.
GlyphIndex = ThemeProperty.TMT_GLYPHINDEX,
///
/// The amount of the first gradient color (TMT_GRADIENTCOLOR1) to use in drawing the part. This value can be from 0 to 255, but this value plus the
/// values of each of the GRADIENTRATIO values must add up to 255.
///
GradientRatio1 = ThemeProperty.TMT_GRADIENTRATIO1,
/// The amount of the second gradient color (TMT_GRADIENTCOLOR2) to use in drawing the part.
GradientRatio2 = ThemeProperty.TMT_GRADIENTRATIO2,
/// The amount of the third gradient color (TMT_GRADIENTCOLOR3) to use in drawing the part.
GradientRatio3 = ThemeProperty.TMT_GRADIENTRATIO3,
/// The amount of the fourth gradient color (TMT_GRADIENTCOLOR4) to use in drawing the part.
GradientRatio4 = ThemeProperty.TMT_GRADIENTRATIO4,
/// The amount of the fifth gradient color (TMT_GRADIENTCOLOR5) to use in drawing the part.
GradientRatio5 = ThemeProperty.TMT_GRADIENTRATIO5,
/// The height of the part.
Height = ThemeProperty.TMT_HEIGHT,
/// The number of state images present in an image file.
ImageCount = ThemeProperty.TMT_IMAGECOUNT,
/// The minimum dots per inch (dpi) that the first image file was designed for.
MinDpi1 = ThemeProperty.TMT_MINDPI1,
/// The minimum dpi that the second image file was designed for.
MinDpi2 = ThemeProperty.TMT_MINDPI2,
/// The minimum dpi that the third image file was designed for.
MinDpi3 = ThemeProperty.TMT_MINDPI3,
/// The minimum dpi that the fourth image file was designed for.
MinDpi4 = ThemeProperty.TMT_MINDPI4,
/// The minimum dpi that the fifth image file was designed for.
MinDpi5 = ThemeProperty.TMT_MINDPI5,
/// The size of the progress control "chunk" shapes that define how far an operation has progressed.
ProgressChunkSize = ThemeProperty.TMT_PROGRESSCHUNKSIZE,
/// The total size of all of the progress control "chunks".
ProgressSpaceSize = ThemeProperty.TMT_PROGRESSSPACESIZE,
/// The roundness (0 to 100 percent) of the part's corners.
RoundCornerHeight = ThemeProperty.TMT_ROUNDCORNERHEIGHT,
/// The roundness (0 to 100 percent) of the part's corners.
RoundCornerWidth = ThemeProperty.TMT_ROUNDCORNERWIDTH,
/// The amount of saturation (0-255) to apply to an icon drawn using DrawThemeIcon.
Saturation = ThemeProperty.TMT_SATURATION,
/// The thickness of the border drawn around text characters.
TextBorderSize = ThemeProperty.TMT_TEXTBORDERSIZE,
/// The percentage of a true-size image's original size at which the image will be stretched.
TrueSizeStretchMark = ThemeProperty.TMT_TRUESIZESTRETCHMARK,
/// The width of the part.
Width = ThemeProperty.TMT_WIDTH,
}
/// Identifies the type of size value to retrieve for a visual style part.
public enum PartSize
{
/// Receives the minimum size of a visual style part.
Minimum = THEMESIZE.TS_MIN,
/// Receives the size of the visual style part that will best fit the available space.
BestFit = THEMESIZE.TS_TRUE,
/// Receives the size that the theme manager uses to draw a part.
Default = THEMESIZE.TS_DRAW
}
/// Properties accessible via .
public enum PositionProperty
{
/// The minimum size that the normal image file can be used for before moving to the next smallest image file.
MinSize = ThemeProperty.TMT_MINSIZE,
/// The minimum size that the first small image file can be used for.
MinSize1 = ThemeProperty.TMT_MINSIZE1,
/// The minimum size that the second small image file can be used for.
MinSize2 = ThemeProperty.TMT_MINSIZE2,
/// The minimum size that the third small image file can be used for.
MinSize3 = ThemeProperty.TMT_MINSIZE3,
/// The minimum size that the fourth small image file can be used for.
MinSize4 = ThemeProperty.TMT_MINSIZE4,
/// The minimum size that the fifth small image file can be used for.
MinSize5 = ThemeProperty.TMT_MINSIZE5,
/// The size of the normal image associated with this part.
NormalSize = ThemeProperty.TMT_NORMALSIZE,
/// The position offset from the alignment for this part. The alignment is defined by the TMT_OFFSETTYPE value.
Offset = ThemeProperty.TMT_OFFSET,
/// The offset from the text at which text shadows are drawn.
TextShadowOffset = ThemeProperty.TMT_TEXTSHADOWOFFSET,
}
/// Returned by GetPropertyOrigin to specify where a property was found.
public enum PropertyOrigin
{
/// Property was found in the state section.
State = PROPERTYORIGIN.PO_STATE,
/// Property was found in the part section.
Part = PROPERTYORIGIN.PO_PART,
/// Property was found in the class section.
Class = PROPERTYORIGIN.PO_CLASS,
/// Property was found in the list of global variables.
Global = PROPERTYORIGIN.PO_GLOBAL,
/// Property was not found.
NotFound = PROPERTYORIGIN.PO_NOTFOUND
}
/// Properties accessible via .
public enum RectangleProperty
{
/// TMT_ANIMATIONBUTTONRECT
AnimationButton = ThemeProperty.TMT_ANIMATIONBUTTONRECT,
/// TMT_ATLASRECT
Atlas = ThemeProperty.TMT_ATLASRECT,
/// TMT_CUSTOMSPLITRECT
CustomSplit = ThemeProperty.TMT_CUSTOMSPLITRECT,
/// The default size of the part.
DefaultPane = ThemeProperty.TMT_DEFAULTPANESIZE,
}
/// Properties accessible via .
public enum StringProperty
{
/// TMT_ALIAS
Alias = ThemeProperty.TMT_ALIAS,
/// TMT_ATLASINPUTIMAGE
AtlasInputImage = ThemeProperty.TMT_ATLASINPUTIMAGE,
/// TMT_AUTHOR
Author = ThemeProperty.TMT_AUTHOR,
/// TMT_CLASSICVALUE
ClassicValue = ThemeProperty.TMT_CLASSICVALUE,
/// TMT_COLORSCHEMES
ColorSchemes = ThemeProperty.TMT_COLORSCHEMES,
/// TMT_COMPANY
Company = ThemeProperty.TMT_COMPANY,
/// TMT_COPYRIGHT
Copyright = ThemeProperty.TMT_COPYRIGHT,
/// See GetThemeSysString.
CssName = ThemeProperty.TMT_CSSNAME,
/// TMT_DESCRIPTION
Description = ThemeProperty.TMT_DESCRIPTION,
/// TMT_DISPLAYNAME
DisplayName = ThemeProperty.TMT_DISPLAYNAME,
/// TMT_LASTUPDATED
LastUpdated = ThemeProperty.TMT_LASTUPDATED,
/// TMT_SIZES
Sizes = ThemeProperty.TMT_SIZES,
/// The text displayed by the part.
Text = ThemeProperty.TMT_TEXT,
/// TMT_TOOLTIP
Tooltip = ThemeProperty.TMT_TOOLTIP,
/// TMT_URL
Url = ThemeProperty.TMT_URL,
/// TMT_VERSION
Version = ThemeProperty.TMT_VERSION,
/// See GetThemeSysString.
XmlName = ThemeProperty.TMT_XMLNAME,
/// TMT_NAME
Name = ThemeProperty.TMT_NAME,
}
private enum PropertyType
{
Unknown = 0,
Enum = 200,
String = 201,
Int = 202,
SysInt = 198,
Metric = 199,
Bool = 203,
Color = 204,
Margins = 205,
FileName = 206,
Size = 207,
Position = 208,
Rect = 209,
Font = 210,
IntList = 211,
HBitmap = 212,
DiskStream = 213,
Stream = 214
}
/// Gets the full path of the current visual style file.
public static string CurrentThemePath
{
get
{
var sb = new StringBuilder(MAX_PATH);
return GetCurrentThemeName(sb, MAX_PATH, null, 0, null, 0).Succeeded ? sb.ToString() : null;
}
}
/// Gets the name of the author of the theme.
public string Author => GetDocumentationProperty(CurrentThemePath, SZ_THDOCPROP_AUTHOR);
/// Gets the name of the theme.
public string CanonicalName => GetDocumentationProperty(CurrentThemePath, SZ_THDOCPROP_CANONICALNAME);
/// Gets the display name of the theme.
public string DisplayName => GetDocumentationProperty(CurrentThemePath, SZ_THDOCPROP_DISPLAYNAME);
/// Gets the native theme handle (HTHEME).
public SafeHTHEME Handle { get; private set; }
/// Gets the tooltip associated with this theme.
public string Tooltip => GetDocumentationProperty(CurrentThemePath, SZ_THDOCPROP_TOOLTIP);
/// Retrieves the value for a theme property from the documentation section of the specified theme file.
/// The name of the theme file that will be opened to query for the property.
/// The name of the theme property to query.
/// The property string value.
public static string GetDocumentationProperty(string themeFile, string prop)
{
var sb = new StringBuilder(MAX_PATH);
return GetThemeDocumentationProperty(themeFile, prop, sb, MAX_PATH).Succeeded ? sb.ToString() : null;
}
/// Uses the aero wizard background style for a window or control.
/// The window or control.
/// If set to apply the background style; to remove.
public static void UseAeroWizardTexture(IWin32Window window, bool enable) =>
EnableThemeDialogTexture(window.Handle, ThemeDialogTextureFlags.ETDT_USEAEROWIZARDTABTEXTURE | (enable ? ThemeDialogTextureFlags.ETDT_ENABLE : ThemeDialogTextureFlags.ETDT_DISABLE));
/// Uses the tab control background style for a window or control.
/// The window or control.
/// If set to apply the background style; to remove.
public static void UseTabTexture(IWin32Window window, bool enable) =>
EnableThemeDialogTexture(window.Handle, ThemeDialogTextureFlags.ETDT_USETABTEXTURE | (enable ? ThemeDialogTextureFlags.ETDT_ENABLE : ThemeDialogTextureFlags.ETDT_DISABLE));
/// Retrieves a hit test code for a point in the background specified by a visual style.
/// Device context.
/// Value that specifies the part.
/// Value that specifies the state of the part.
/// The rectangle, in logical coordinates, that bounds the background.
/// The coordinates of the point.
/// The hit test options.
/// The hit test code that indicates whether the point in is in the background area bounded by .
public System.Windows.Forms.VisualStyles.HitTestCode BackgroundHitTest(IDeviceContext dc, int partId, int stateId, Rectangle bounds, Point pt, System.Windows.Forms.VisualStyles.HitTestOptions options = 0)
{
using (var hdc = new SafeTempHDC(dc))
return HitTestThemeBackground(Handle, hdc, partId, stateId, (HitTestOptions)options, bounds, HRGN.NULL, pt, out var htcode).Succeeded ? (System.Windows.Forms.VisualStyles.HitTestCode)htcode : 0;
}
/// Retrieves a hit test code for a point in the background specified by a visual style.
/// Device context.
/// Value that specifies the part.
/// Value that specifies the state of the part.
/// The rectangle, in logical coordinates, that bounds the background.
/// A region used to specify the bounds of a hit test area.
/// The coordinates of the point.
/// The hit test options.
///
/// The hit test code that indicates whether the point in is in the background area bounded by or .
///
public System.Windows.Forms.VisualStyles.HitTestCode BackgroundHitTest(Graphics graphics, int partId, int stateId, Rectangle bounds, Region region, Point pt, System.Windows.Forms.VisualStyles.HitTestOptions options = 0)
{
using (var hdc = new SafeTempHDC(graphics))
return HitTestThemeBackground(Handle, hdc, partId, stateId, (HitTestOptions)options, bounds, new HRGN(region.GetHrgn(graphics)), pt, out var htcode).Succeeded ? (System.Windows.Forms.VisualStyles.HitTestCode)htcode : 0;
}
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
public void Dispose() { Handle?.Dispose(); }
/// Draws the background image defined by the visual style for the specified control part.
/// Used for drawing the theme-defined background image.
/// Value that specifies the part to draw.
/// Value that specifies the state of the part to draw.
/// The bounds, in logical coordinates, in which the background image is drawn.
/// An optional rectangle that specifies the bounding rectangle of the clip region.
/// if set to true mirror the device context for right to left drawing.
/// if set to true omit border when drawing.
/// if set to true omit content when drawing.
public void DrawBackground(IDeviceContext graphics, int partId, int stateId, Rectangle bounds, Rectangle? clipRect, bool rightToLeft = false, bool omitBorder = false, bool omitContent = false)
{
var o = new DTBGOPTS(clipRect) {HasMirroredDC = rightToLeft, OmitBorder = omitBorder, OmitContent = omitContent};
using (var hdc = new SafeTempHDC(graphics))
DrawThemeBackgroundEx(Handle, hdc, partId, stateId, bounds, o);
}
/// Draws one or more edges defined by the visual style of a rectangle.
/// Used for drawing the theme-defined edge.
/// Value that specifies the part to draw.
/// Value that specifies the state of the part to draw.
/// The bounding rectangle, in logical coordinates.
/// Specifies the type of inner and outer edges to draw.
///
/// Specifies the type of border to draw. If BF_ADJUST is specified, will be shrunk to exclude the edges that were drawn upon return.
///
public void DrawEdge(IDeviceContext graphics, int partId, int stateId, ref Rectangle bounds, BorderStyles3D edges = BorderStyles3D.BDR_SUNKEN, BorderFlags borderType = BorderFlags.BF_RECT | BorderFlags.BF_ADJUST)
{
using (var hdc = new SafeTempHDC(graphics))
{
DrawThemeEdge(Handle, hdc, partId, stateId, bounds, edges, borderType, out var r);
if (borderType.IsFlagSet(BorderFlags.BF_ADJUST))
bounds = r;
}
}
/// Draws an image from an image list with the icon effect defined by the visual style.
/// Used for drawing the icon.
/// Value that specifies the part to draw.
/// Value that specifies the state of the part to draw.
/// An image list that contains the image to draw.
/// Value that specifies the index of the image to draw.
/// The bounding rectangle, in logical coordinates.
public void DrawIcon(IDeviceContext graphics, int partId, int stateId, ImageList imageList, int imageIndex, Rectangle bounds)
{
using (var hdc = new SafeTempHDC(graphics))
DrawThemeIcon(Handle, hdc, partId, stateId, bounds, imageList.Handle, imageIndex);
}
/// Draws the part of a parent control that is covered by a partially-transparent or alpha-blended child control.
/// The child control.
/// The child control's device context.
///
/// The area to be drawn. The rectangle is in the child window's coordinates. If this parameter is NULL, the area to be drawn includes the entire area
/// occupied by the child control.
///
public void DrawParentBackground(IWin32Window childWindow, IDeviceContext graphics, Rectangle? bounds = null)
{
using (var hdc = new SafeTempHDC(graphics))
DrawThemeParentBackground(childWindow.Handle, hdc, bounds);
}
/// Draws text using the color and font defined by the visual style.
/// Used for drawing the text.
/// Value that specifies the part to draw.
/// Value that specifies the state of the part to draw.
/// The bounding rectangle, in logical coordinates.
/// A string that contains the text to draw.
/// One or more values that specify the string's formatting.
/// Draw text disabled.
/// The font to use when drawing the text. If null, the default system font is used.
public void DrawText(IDeviceContext graphics, int partId, int stateId, Rectangle bounds, string text, TextFormatFlags fmt = TextFormatFlags.Default, bool disabled = false, Font font = null)
{
RECT b = bounds;
using (var hdc = new SafeTempHDC(graphics))
using (var hfont = new SafeHFONT(font?.ToHfont() ?? IntPtr.Zero))
using (new GdiObjectContext(hdc, hfont))
DrawThemeText(Handle, hdc, partId, stateId, text, text.Length, (DrawTextFlags)fmt, disabled ? 1 : 0, b);
}
/// Draws text using the color and font defined by the visual style.
/// Used for drawing the text.
/// Value that specifies the part to draw.
/// Value that specifies the state of the part to draw.
/// The bounding rectangle, in logical coordinates.
/// A string that contains the text to draw.
/// One or more values that specify the string's formatting.
/// Additional formatting options.
/// The font to use when drawing the text. If null, the default system font is used.
public void DrawText(IDeviceContext graphics, int partId, int stateId, Rectangle bounds, string text, TextFormatFlags fmt = TextFormatFlags.Default, DTTOPTS? options = null, Font font = null)
{
RECT b = bounds;
var dt = options ?? DTTOPTS.Default;
using (var hdc = new SafeTempHDC(graphics))
using (var hfont = new SafeHFONT(font?.ToHfont() ?? IntPtr.Zero))
using (new GdiObjectContext(hdc, hfont))
DrawThemeTextEx(Handle, hdc, partId, stateId, text, text.Length, (DrawTextFlags)fmt, ref b, dt);
}
/// Retrieves the size of the content area for the background defined by the visual style.
/// The device context to use when drawing. This parameter may be set to null.
/// Value that specifies the part to draw.
/// Value that specifies the state of the part to draw.
/// The total background rectangle, in logical coordinates.
/// The content area background rectangle, in logical coordinates. This rectangle is calculated to fit the content area.
public Rectangle? GetBackgroundContentRect([Optional] IDeviceContext graphics, int partId, int stateId, Rectangle bounds)
{
using (var hdc = new SafeTempHDC(graphics))
return GetThemeBackgroundContentRect(Handle, hdc, partId, stateId, bounds, out var rc).Succeeded ? (Rectangle?)rc : null;
}
/// Calculates the size and location of the background, defined by the visual style, given the content area.
/// The device context to use when drawing. This parameter may be set to null.
/// Value that specifies the part that contains the content.
/// Value that specifies the state of the part that contains the content.
/// The content background rectangle, in logical coordinates.
/// The background rectangle, in logical coordinates. This rectangle is based on .
public Rectangle? GetBackgroundExtent([Optional] IDeviceContext graphics, int partId, int stateId, Rectangle bounds)
{
using (var hdc = new SafeTempHDC(graphics))
return GetThemeBackgroundExtent(Handle, hdc, partId, stateId, bounds, out var rc).Succeeded ? (Rectangle?)rc : null;
}
/// Retrieves the bitmap associated with a particular theme, part, state, and property.
/// Value that specifies the part that contains the bitmap.
/// Value that specifies the state of the part that contains the bitmap.
/// The bitmap property identifier.
/// The requested bitmap, if successful; otherwise null.
public Bitmap GetBitmap(int partId, int stateId, BitmapProperty propId) => GetThemeBitmap(Handle, partId, stateId, (int)propId, GBF.GBF_COPY, out var hBmp).Succeeded ? hBmp.ToBitmap() : null;
/// Retrieves the value of a bool property from the SysMetrics section of theme data.
/// Value that specifies the part that contains the bool property.
/// Value that specifies the state of the part that contains the bool property.
/// The bool property identifier.
/// The requested bool value, if successful; otherwise null.
public bool? GetBool(int partId, int stateId, BoolProperty propId)
{
if (GetThemeBool(Handle, partId, stateId, (int)propId, out var b).Succeeded)
return b;
else if (propId == BoolProperty.FlatMenus)
return GetThemeSysBool(Handle, (int)propId);
return null;
}
/// Retrieves the value of a color property.
/// Value that specifies the part that contains the color property.
/// Value that specifies the state of the part that contains the color property.
/// The color property identifier.
/// The requested color value, if successful; otherwise null.
public Color? GetColor(int partId, int stateId, ColorProperty propId) => GetThemeColor(Handle, partId, stateId, (int)propId, out var cr).Succeeded ? (Color?)cr : null;
/// Retrieves a data stream corresponding to this theme, starting from a specified part and state.
/// The SafeLibraryHandle of a loaded styles file.
/// Specifies the part to retrieve a stream from.
/// Specifies the state of the part.
/// The data stream.
public byte[] GetDiskStream(HINSTANCE hInst, int partId, int stateId)
{
var r = GetThemeStream(Handle, partId, stateId, (int)ThemeProperty.TMT_DISKSTREAM, out var bytes, out var bLen, hInst);
if (r.Succeeded) return bytes.ToArray((int)bLen);
if (r != 0x80070490) throw new InvalidOperationException("Bad GetThemeStream");
return null;
}
/// Retrieves the value of a enum property.
/// Value that specifies the part that contains the enum property.
/// Value that specifies the state of the part that contains the enum property.
/// The enum property identifier.
/// The requested enum value, if successful; otherwise null.
public int? GetEnumValue(int partId, int stateId, EnumProperty propId) => GetThemeEnumValue(Handle, partId, stateId, (int)propId, out var i).Succeeded ? (int?)i : null;
/// Retrieves the value of a enum property.
/// Value that specifies the part that contains the enum property.
/// Value that specifies the state of the part that contains the enum property.
/// The enum property identifier.
/// The requested enum value, if successful; otherwise null.
public T? GetEnumValue(int partId, int stateId, EnumProperty propId) where T : struct, IComparable => GetThemeEnumValue(Handle, partId, stateId, (int)propId, out var i).Succeeded ? (T?)(object)i : null;
/// Retrieves the value of a string property.
/// Value that specifies the part that contains the string property.
/// Value that specifies the state of the part that contains the string property.
/// The string property identifier.
/// The requested string value, if successful; otherwise null.
public string GetFilename(int partId, int stateId, FilenameProperty propId)
{
const int sbLen = 1024;
var sb = new StringBuilder(sbLen);
return GetThemeFilename(Handle, partId, stateId, (int)propId, sb, sbLen).Succeeded ? sb.ToString() : null;
}
/// Retrieves the value of a font property.
/// The device context from which to get the property.
/// Value that specifies the part that contains the font property.
/// Value that specifies the state of the part that contains the font property.
/// The font property identifier.
/// The requested font value, if successful; otherwise null.
public Font GetFont(IDeviceContext graphics, int partId, int stateId, FontProperty propId)
{
using (var hdc = new SafeTempHDC(graphics))
{
if (GetThemeFont(Handle, hdc, partId, stateId, (int)propId, out var f).Succeeded)
return Font.FromLogFont(f);
return GetThemeSysFont(Handle, (int)propId, out f).Succeeded ? Font.FromLogFont(f) : null;
}
}
/// Retrieves the value of an int property.
/// Value that specifies the part that contains the int property.
/// Value that specifies the state of the part that contains the int property.
/// The int property identifier.
/// The requested int value, if successful; otherwise null.
public int? GetInt(int partId, int stateId, IntProperty propId)
{
if (GetThemeInt(Handle, partId, stateId, (int)propId, out var i).Succeeded)
return i;
return GetThemeSysInt(Handle, (int)propId, out var si).Succeeded ? (int?)si : null;
}
/// Retrieves a list of int data from a visual style.
/// Value that specifies the part that contains the list of data to return.
/// Value that specifies the state of the part.
/// Value that specifies the property to retrieve.
/// The requested list of data, if successful; otherwise null.
public int[] GetIntList(int partId, int stateId, int propId = (int)ThemeProperty.TMT_TRANSITIONDURATIONS) => GetThemeIntList(Handle, partId, stateId, propId);
/// Retrieves the margins from a visual style.
/// The device context from which to get the property.
/// Value that specifies the part that contains the margins to return.
/// Value that specifies the state of the part.
/// Value that specifies the property to retrieve.
/// The requested margins, if successful; otherwise null.
public Padding? GetMargins(IDeviceContext graphics, int partId, int stateId, MarginsProperty propId)
{
using (var hdc = new SafeTempHDC(graphics))
return GetThemeMargins(Handle, hdc, partId, stateId, (int)propId, null, out var m).Succeeded ? (Padding?)new Padding(m.cxLeftWidth, m.cyTopHeight, m.cxRightWidth, m.cyBottomHeight) : null;
}
/// Retrieves the value of a metric property.
/// The device context from which to get the property.
/// Value that specifies the part that contains the metric property.
/// Value that specifies the state of the part that contains the metric property.
/// The metric property identifier.
/// The requested metric value, if successful; otherwise null.
public int? GetMetric(IDeviceContext graphics, int partId, int stateId, MetricProperty propId)
{
using (var hdc = new SafeTempHDC(graphics))
return GetThemeMetric(Handle, hdc, partId, stateId, (int)propId, out var i).Succeeded ? (int?)i : null;
}
/// Retrives the value of a property
/// The device context from which to get the property.
/// Value that specifies the part that contains the property.
/// Value that specifies the state of the part that contains the property.
/// The property identifier.
/// The requested value, if successful; otherwise null.
public object GetObject(IDeviceContext graphics, int partId, int stateId, int propId)
{
object o = null;
try
{
switch (LookupGetType(propId))
{
case PropertyType.Enum:
o = GetEnumValue(partId, stateId, (EnumProperty)propId);
break;
case PropertyType.String:
o = GetString(partId, stateId, (StringProperty)propId);
break;
case PropertyType.Int:
case PropertyType.SysInt:
o = GetInt(partId, stateId, (IntProperty)propId);
break;
case PropertyType.Metric:
o = GetMetric(graphics, partId, stateId, (MetricProperty)propId);
break;
case PropertyType.Bool:
o = GetBool(partId, stateId, (BoolProperty)propId);
break;
case PropertyType.Color:
o = GetColor(partId, stateId, (ColorProperty)propId);
break;
case PropertyType.Margins:
o = GetMargins(graphics, partId, stateId, (MarginsProperty)propId);
break;
case PropertyType.FileName:
o = GetFilename(partId, stateId, (FilenameProperty)propId);
break;
case PropertyType.Size:
o = GetPartSize(graphics, partId, stateId, null, (PartSize)propId);
break;
case PropertyType.Position:
o = GetPosition(partId, stateId, (PositionProperty)propId);
break;
case PropertyType.Rect:
o = GetRect(partId, stateId, (RectangleProperty)propId);
break;
case PropertyType.Font:
o = GetFont(graphics, partId, stateId, (FontProperty)propId);
break;
case PropertyType.IntList:
o = GetIntList(partId, stateId, propId);
break;
case PropertyType.HBitmap:
o = GetBitmap(partId, stateId, (BitmapProperty)propId);
break;
//case PropertyType.DiskStream:
// o = GetDiskStream(partId, stateId);
// break;
case PropertyType.Stream:
o = GetStream(partId, stateId);
break;
default:
System.Diagnostics.Debug.WriteLine($"Failed to get value for {partId}:{stateId}:{propId}.");
break;
}
}
catch (Exception ex)
{
o = ex;
System.Diagnostics.Debug.WriteLine($"Failed to get value for {partId}:{stateId}:{propId}.");
}
return o;
}
/// Calculates the original size of the part defined by a visual style.
/// The device context to select fonts into.
/// Value that specifies the part to calculate the size of.
/// Value that specifies the state of the part.
/// The rectangle used for the part drawing destination. This parameter may be set to null.
/// Specifies the type of size to retrieve.
/// The dimensions of the specified part.
public Size? GetPartSize(IDeviceContext graphics, int partId, int stateId, Rectangle? destRect = null, PartSize size = PartSize.Default)
{
using (var hdc = new SafeTempHDC(graphics))
return GetThemePartSize(Handle, hdc, partId, stateId, destRect, (THEMESIZE)size, out var sz).Succeeded ? (Size?)sz : null;
}
/// Retrieves the value of a position property.
/// Value that specifies the part that contains the position property.
/// Value that specifies the state of the part that contains the position property.
/// The position property identifier.
/// The requested position value, if successful; otherwise null.
public Point? GetPosition(int partId, int stateId, PositionProperty propId) => GetThemePosition(Handle, partId, stateId, (int)propId, out var i).Succeeded ? (Point?)i : null;
/// Retrieves the location of the theme property definition for a property.
/// Value of type int that specifies the part that contains the theme. See Parts and States.
/// Value of type int that specifies the state of the part. See Parts and States.
/// Value of type int that specifies the property to retrieve. You may use any of the property enum value cast to an int.
/// Value that indicates where the property was or was not found.
public PropertyOrigin GetPropertyOrigin(int partId, int stateId, int propId) => GetThemePropertyOrigin(Handle, partId, stateId, propId, out var po).Succeeded ? (PropertyOrigin)po : PropertyOrigin.NotFound;
/// Retrieves the value of a rectangle property.
/// Value that specifies the part that contains the rectangle property.
/// Value that specifies the state of the part that contains the rectangle property.
/// The rectangle property identifier.
/// The requested rectangle value, if successful; otherwise null.
public Rectangle? GetRect(int partId, int stateId, RectangleProperty propId) => GetThemeRect(Handle, partId, stateId, (int)propId, out var rc).Succeeded ? (Rectangle?)rc : null;
/// Retrieves a data stream corresponding to this theme, starting from a specified part and state.
/// Specifies the part to retrieve a stream from.
/// Specifies the state of the part.
/// The data stream.
public byte[] GetStream(int partId, int stateId)
{
var r = GetThemeStream(Handle, partId, stateId, (int)ThemeProperty.TMT_STREAM, out var bytes, out var bLen, HINSTANCE.NULL);
if (r.Succeeded) return bytes.ToArray((int)bLen);
if (r != 0x80070490) throw new InvalidOperationException("Bad GetThemeStream");
return null;
}
/// Retrieves the value of a string property.
/// Value that specifies the part that contains the string property.
/// Value that specifies the state of the part that contains the string property.
/// The string property identifier.
/// The requested string value, if successful; otherwise null.
public string GetString(int partId, int stateId, StringProperty propId)
{
const int sbLen = 1024;
var sb = new StringBuilder(sbLen);
if (GetThemeString(Handle, partId, stateId, (int)propId, sb, sbLen).Succeeded)
return sb.ToString();
sb = new StringBuilder(sbLen);
return GetThemeSysString(Handle, (int)propId, sb, sbLen).Succeeded ? sb.ToString() : null;
}
/// Retrieves a system color brush.
/// Value that specifies the color number.
/// Handle to brush data.
public Brush GetSystemBrush(SystemColorIndex colorId)
{
var hbrush = GetThemeSysColorBrush(Handle, (int)colorId);
return !hbrush.IsInvalid ? hbrush.ToBrush() : null;
}
/// Retrieves the value of a system color.
/// Value that specifies the color number.
/// The value of the specified system color.
public Color GetSystemColor(SystemColorIndex colorId) => GetThemeSysColor(Handle, colorId);
/// Gets the system font.
/// The font property identifier.
/// The value of the specified font.
public Font GetSystemFont(int fontId) => GetThemeSysFont(Handle, fontId, out var lf).Succeeded ? Font.FromLogFont(lf) : null;
/// Retrieves the value of a system size metric from theme data.
/// Value that specifies the system size metric desired.
/// Returns the size in pixels.
public int GetSystemMetric(User32.SystemMetric metric) => GetThemeSysSize(Handle, (int)metric);
/// Calculates the size and location of the specified text when rendered in the visual style font.
///
/// HDC to select the font into.
///
///
/// Value that specifies the part in which the text will be drawn. See Parts and States.
///
///
/// Value that specifies the state of the part. See Parts and States.
///
///
/// A string that contains the text to draw.
///
///
/// Enumeration value that contains one or more values that specify the string's formatting.
///
///
/// The rectangle used to control layout of the text. This parameter may be set to .
///
///
/// In logical coordinates, the rectangle required to fit the rendered text.
///
public Rectangle? GetTextExtent(IDeviceContext dc, int partId, int stateId, string text, DrawTextFlags flags, Rectangle? bounds)
{
using (var hdc = new SafeTempHDC(dc))
return GetThemeTextExtent(Handle, hdc, partId, stateId, text, -1, flags, bounds, out var ext).Succeeded ? (Rectangle?)ext : null;
}
/// Retrieves information about the font specified by a visual style for a particular part.
///
/// HDC to use for screen context. This parameter may be set to .
///
///
/// Value that specifies the part to retrieve font information about. See Parts and States.
///
///
/// Value that specifies the state of the part. See Parts and States.
///
///
/// Receives the font information.
///
public TEXTMETRIC? GetTextMetrics(IDeviceContext dc, int partId, int stateId)
{
using (var hdc = new SafeTempHDC(dc))
return GetThemeTextMetrics(Handle, hdc, partId, stateId, out var m).Succeeded ? (TEXTMETRIC?)m : null;
}
/// Gets the duration for the specified transition.
/// ID of the part.
/// State ID of the part before the transition.
/// State ID of the part after the transition.
/// The transition duration.
public TimeSpan? GetTransitionDuration(int partId, int fromStateId, int toStateId) =>
GetThemeTransitionDuration(Handle, partId, fromStateId, toStateId, (int)ThemeProperty.TMT_TRANSITIONDURATIONS, out var dur).Succeeded ? (TimeSpan?)TimeSpan.FromMilliseconds(dur) : null;
/// Retrieves whether the background specified by the visual style has transparent pieces or alpha-blended pieces.
/// Value of type int that specifies the part.
/// Value of type int that specifies the state of the part.
///
/// if the theme-specified background for a particular partId and stateId has transparent pieces or alpha-blended pieces;
/// otherwise.
///
public bool IsBackgroundPartiallyTransparent(int partId, int stateId) => IsThemeBackgroundPartiallyTransparent(Handle, partId, stateId);
/// Retrieves whether a visual style has defined parameters for the specified part and state.
/// Value that specifies the part.
/// if the theme has defined parameters for the specified part; otherwise.
public bool IsPartDefined(int partId) => IsThemePartDefined(Handle, partId, 0);
private static PropertyType LookupGetType(int propId)
{
if ((propId >= 4001 && propId <= 4015))
return PropertyType.Enum;
if ((propId >= 401 && propId <= 402) || (propId >= 600 && propId <= 608) || (propId >= 1401 && propId <= 1404) ||
(propId >= 3201 && propId <= 3202) || propId == 8001)
return PropertyType.String;
if (propId == 403 || (propId >= 1201 && propId <= 1210) || (propId >= 1801 && propId <= 1810) || propId == 5006)
return PropertyType.Int;
if (propId >= 2401 && propId <= 2434 && propId != 2431)
return PropertyType.Metric;
if (propId == 1301)
return PropertyType.SysInt;
if (propId == 1001 || (propId >= 2201 && propId <= 2220) || propId == 5001 || propId == 7001)
return PropertyType.Bool;
if ((propId >= 1601 && propId <= 1631) || (propId >= 2001 && propId <= 2010) || propId == 2431 ||
(propId >= 3801 && propId <= 3827) || propId == 5003)
return PropertyType.Color;
if ((propId >= 3601 && propId <= 3603))
return PropertyType.Margins;
if ((propId >= 3001 && propId <= 3010))
return PropertyType.FileName;
if ((propId >= 0 && propId <= 2))
return PropertyType.Size;
if ((propId >= 3401 && propId <= 3411))
return PropertyType.Position;
if (propId == 5002 || propId == 5004 || propId == 5005 || propId == 8002)
return PropertyType.Rect;
if ((propId >= 801 && propId <= 809) || propId == 2601)
return PropertyType.Font;
if (propId == 6000)
return PropertyType.IntList;
if ( /*propId == 2 ||*/ propId == 8)
return PropertyType.HBitmap;
if (propId == 8000 || propId == (int)PropertyType.DiskStream)
return PropertyType.DiskStream;
if (propId == (int)PropertyType.Stream)
return PropertyType.Stream;
System.Diagnostics.Debug.WriteLine($"Unmapped theme property: {propId}");
return PropertyType.Unknown;
}
}
}