using System; using System.Drawing; using System.Runtime.InteropServices; namespace Vanara.PInvoke { /// The COLORREF value is used to specify an RGB color in the form 0x00bbggrr. // typedef DWORD COLORREF;typedef DWORD* LPCOLORREF; https://msdn.microsoft.com/en-us/library/windows/desktop/dd183449(v=vs.85).aspx [PInvokeData("Windef.h", MSDNShortId = "dd183449")] [StructLayout(LayoutKind.Explicit, Size = 4)] public struct COLORREF { /// The DWORD value [FieldOffset(0)] private uint Value; /// The intensity of the red color. [FieldOffset(0)] public byte R; /// The intensity of the green color. [FieldOffset(1)] public byte G; /// The intensity of the blue color. [FieldOffset(2)] public byte B; /// The transparency. [FieldOffset(3)] public byte A; private const uint CLR_NONE = 0xFFFFFFFF; private const uint CLR_DEFAULT = 0xFF000000; /// Initializes a new instance of the struct. /// The intensity of the red color. /// The intensity of the green color. /// The intensity of the blue color. public COLORREF(byte r, byte g, byte b) { Value = 0; A = 0; R = r; G = g; B = b; } /// Initializes a new instance of the struct. /// The packed DWORD value. public COLORREF(uint value) { R = 0; G = 0; B = 0; A = 0; Value = value & 0x00FFFFFF; } /// Initializes a new instance of the struct. /// The color. public COLORREF(Color color) : this(color.R, color.G, color.B) { if (color == Color.Transparent) Value = CLR_NONE; } /// A method to darken a color by a percentage of the difference between the color and Black. /// The percentage by which to darken the original color. /// /// The return color's Alpha value will be unchanged, but the RGB content will have been increased by the specified percentage. If /// percent is 100 then the returned Color will be Black with original Alpha. /// public COLORREF Darken(float percent) { if (percent < 0 || percent > 1.0) throw new ArgumentOutOfRangeException(nameof(percent)); return new(Conv(R), Conv(G), Conv(B)) { Value = Value }; byte Conv(byte c) => (byte)(c - (int)(c * percent)); } /// A method to lighten a color by a percentage of the difference between the color and Black. /// The percentage by which to lighten the original color. /// /// The return color's Alpha value will be unchanged, but the RGB content will have been decreased by the specified percentage. If /// percent is 100 then the returned Color will be White with original Alpha. /// public COLORREF Lighten(float percent) { if (percent < 0 || percent > 1.0) throw new ArgumentOutOfRangeException(nameof(percent)); return new(Conv(R), Conv(G), Conv(B)) { Value = Value }; byte Conv(byte c) => (byte)(c + (int)((255f - c) * percent)); } /// Gets the 32-bit ARGB value of this structure. /// The 32-bit ARGB value of this structure. public int ToArgb() => unchecked((int)Value); /// Performs an implicit conversion from to . /// The value. /// The result of the conversion. public static implicit operator Color(COLORREF cr) => cr.Value == CLR_NONE ? Color.Transparent : Color.FromArgb(cr.R, cr.G, cr.B); /// Performs an implicit conversion from to . /// The value. /// The result of the conversion. public static implicit operator COLORREF(Color clr) => new(clr); /// Performs an implicit conversion from to . /// The tuple containing the R, G, and B values. /// The resulting instance from the conversion. public static implicit operator COLORREF((byte r, byte g, byte b) clr) => new(clr.r, clr.g, clr.b); /// Performs an implicit conversion from to . /// The value. /// The result of the conversion. public static implicit operator uint(COLORREF cr) => cr.Value; /// Performs an implicit conversion from to . /// The value. /// The result of the conversion. public static implicit operator COLORREF(uint value) => new(value); /// Static reference for CLR_NONE representing no color. public static COLORREF None = new(CLR_NONE); /// Static reference for CLR_DEFAULT representing the default color. public static COLORREF Default = new(0xFF000000); /// public override string ToString() => ((Color)this).ToString(); } }