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 : IEquatable
{
/// 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));
}
///
public override bool Equals(object obj) => obj is COLORREF q && Equals(q);
/// Determines whether the specified object is equal to the current object.
/// The object to compare with the current object.
/// if the specified object is equal to the current object; otherwise, .
public bool Equals(COLORREF c) => c.A == A && c.B == B && c.G == G && c.R == R;
///
public override int GetHashCode() => ToArgb();
/// 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();
}
}