diff --git a/PInvoke/Ole/Ole32/WTypes.CY.cs b/PInvoke/Ole/Ole32/WTypes.CY.cs
new file mode 100644
index 00000000..defdd8b4
--- /dev/null
+++ b/PInvoke/Ole/Ole32/WTypes.CY.cs
@@ -0,0 +1,179 @@
+using System;
+using System.ComponentModel;
+using System.Globalization;
+using System.Runtime.InteropServices;
+
+namespace Vanara
+{
+ /// Managed instance of the OLE CY type.
+ [StructLayout(LayoutKind.Sequential), Serializable]
+ [TypeConverter(typeof(CYTypeConverter))]
+ public struct CY : IEquatable, IComparable, IEquatable, IComparable, IConvertible, IComparable
+ {
+ private long int64;
+
+ /// Initializes a new instance of the struct.
+ /// The value.
+ public CY(decimal value) : this(decimal.ToOACurrency(value)) { }
+
+ /// Initializes a new instance of the struct.
+ /// The value.
+ public CY(long value)
+ {
+ if (value > (long.MaxValue / 10000) || value < (long.MinValue / 10000))
+ throw new ArgumentOutOfRangeException();
+ int64 = value * 10000;
+ }
+
+ /// Gets the value.
+ /// The value.
+ public decimal Value => decimal.FromOACurrency(int64);
+
+ /// Performs an implicit conversion from to .
+ /// The value.
+ /// The result of the conversion.
+ public static implicit operator CY(decimal value) => new CY(value);
+
+ /// Performs an explicit conversion from to .
+ /// The value.
+ /// The result of the conversion.
+ public static explicit operator decimal(CY value) => value.Value;
+
+ /// Indicates whether two instances are not equal.
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is not equal to the value of ; otherwise, .
+ ///
+ public static bool operator !=(CY s1, CY s2) => !s1.Equals(s2);
+
+ /// Indicates whether a specified is less than another specified .
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is less than the value of ; otherwise, .
+ ///
+ public static bool operator <(CY s1, CY s2) => s1.CompareTo(s2) < 0;
+
+ /// Indicates whether a specified is less than or equal to another specified .
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is less than or equal to the value of ;
+ /// otherwise, .
+ ///
+ public static bool operator <=(CY s1, CY s2) => s1.CompareTo(s2) <= 0;
+
+ /// Indicates whether two instances are equal.
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is equal to the value of ; otherwise, .
+ ///
+ public static bool operator ==(CY s1, CY s2) => s1.Equals(s2);
+
+ /// Indicates whether a specified is greater than another specified .
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is greater than the value of ; otherwise, .
+ ///
+ public static bool operator >(CY s1, CY s2) => s1.CompareTo(s2) > 0;
+
+ /// Indicates whether a specified is greater than or equal to another specified .
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is greater than or equal to the value of ;
+ /// otherwise, .
+ ///
+ public static bool operator >=(CY s1, CY s2) => s1.CompareTo(s2) >= 0;
+
+ ///
+ public int CompareTo(CY other) => Value.CompareTo(other.Value);
+
+ ///
+ public int CompareTo(decimal other) => Value.CompareTo(other);
+
+ ///
+ public override bool Equals(object obj) => obj is CY s ? Equals(s) : (obj is decimal b ? Value.Equals(b) : Value.Equals(obj));
+
+ ///
+ public bool Equals(CY other) => Value.Equals(other.Value);
+
+ ///
+ public bool Equals(decimal other) => Value.Equals(other);
+
+ ///
+ public override int GetHashCode() => Value.GetHashCode();
+
+ ///
+ public TypeCode GetTypeCode() => Value.GetTypeCode();
+
+ ///
+ public override string ToString() => Value.ToString();
+
+ ///
+ public string ToString(IFormatProvider provider) => Value.ToString(provider);
+
+ ///
+ int IComparable.CompareTo(object obj) => Value.CompareTo(Convert.ChangeType(obj, typeof(decimal)));
+
+ ///
+ bool IConvertible.ToBoolean(IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider);
+
+ ///
+ byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)Value).ToByte(provider);
+
+ ///
+ char IConvertible.ToChar(IFormatProvider provider) => ((IConvertible)Value).ToChar(provider);
+
+ ///
+ DateTime IConvertible.ToDateTime(IFormatProvider provider) => ((IConvertible)Value).ToDateTime(provider);
+
+ ///
+ decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)Value).ToDecimal(provider);
+
+ ///
+ double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)Value).ToDouble(provider);
+
+ ///
+ short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)Value).ToInt16(provider);
+
+ ///
+ int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)Value).ToInt32(provider);
+
+ ///
+ long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)Value).ToInt64(provider);
+
+ ///
+ sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)Value).ToSByte(provider);
+
+ ///
+ float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)Value).ToSingle(provider);
+
+ ///
+ object IConvertible.ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider);
+
+ ///
+ ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)Value).ToUInt16(provider);
+
+ ///
+ uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)Value).ToUInt32(provider);
+
+ ///
+ ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)Value).ToUInt64(provider);
+
+ internal class CYTypeConverter : DecimalConverter
+ {
+ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
+ {
+ if (!(value is CY b)) throw new ArgumentException();
+ return base.ConvertTo(context, culture, b.Value, destinationType);
+ }
+
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) =>
+ new CY((decimal)base.ConvertFrom(context, culture, value));
+ }
+ }
+}
\ No newline at end of file
diff --git a/PInvoke/Ole/Ole32/WTypes.DATE.cs b/PInvoke/Ole/Ole32/WTypes.DATE.cs
new file mode 100644
index 00000000..a3d14e45
--- /dev/null
+++ b/PInvoke/Ole/Ole32/WTypes.DATE.cs
@@ -0,0 +1,170 @@
+using System;
+using System.ComponentModel;
+using System.Globalization;
+using System.Runtime.InteropServices;
+
+namespace Vanara
+{
+ /// Managed instance of the OLE DATE type.
+ [StructLayout(LayoutKind.Sequential), Serializable]
+ [TypeConverter(typeof(DATETypeConverter))]
+ public struct DATE : IEquatable, IComparable, IEquatable, IComparable, IConvertible, IComparable
+ {
+ private double value;
+
+ /// Initializes a new instance of the struct.
+ /// The value.
+ public DATE(DateTime value) => this.value = value.ToOADate();
+
+ /// Gets the value.
+ /// The value.
+ public DateTime Value => DateTime.FromOADate(value);
+
+ /// Performs an implicit conversion from to .
+ /// The value.
+ /// The result of the conversion.
+ public static implicit operator DATE(DateTime value) => new DATE(value);
+
+ /// Performs an explicit conversion from to .
+ /// The value.
+ /// The result of the conversion.
+ public static explicit operator DateTime(DATE value) => value.Value;
+
+ /// Indicates whether two instances are not equal.
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is not equal to the value of ; otherwise, .
+ ///
+ public static bool operator !=(DATE s1, DATE s2) => !s1.Equals(s2);
+
+ /// Indicates whether a specified is less than another specified .
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is less than the value of ; otherwise, .
+ ///
+ public static bool operator <(DATE s1, DATE s2) => s1.CompareTo(s2) < 0;
+
+ /// Indicates whether a specified is less than or equal to another specified .
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is less than or equal to the value of ;
+ /// otherwise, .
+ ///
+ public static bool operator <=(DATE s1, DATE s2) => s1.CompareTo(s2) <= 0;
+
+ /// Indicates whether two instances are equal.
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is equal to the value of ; otherwise, .
+ ///
+ public static bool operator ==(DATE s1, DATE s2) => s1.Equals(s2);
+
+ /// Indicates whether a specified is greater than another specified .
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is greater than the value of ; otherwise, .
+ ///
+ public static bool operator >(DATE s1, DATE s2) => s1.CompareTo(s2) > 0;
+
+ /// Indicates whether a specified is greater than or equal to another specified .
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is greater than or equal to the value of ;
+ /// otherwise, .
+ ///
+ public static bool operator >=(DATE s1, DATE s2) => s1.CompareTo(s2) >= 0;
+
+ ///
+ public int CompareTo(DATE other) => Value.CompareTo(other.Value);
+
+ ///
+ public int CompareTo(DateTime other) => Value.CompareTo(other);
+
+ ///
+ public override bool Equals(object obj) => obj is DATE s ? Equals(s) : (obj is DateTime b ? Value.Equals(b) : Value.Equals(obj));
+
+ ///
+ public bool Equals(DATE other) => Value.Equals(other.Value);
+
+ ///
+ public bool Equals(DateTime other) => Value.Equals(other);
+
+ ///
+ public override int GetHashCode() => Value.GetHashCode();
+
+ ///
+ public TypeCode GetTypeCode() => Value.GetTypeCode();
+
+ ///
+ public override string ToString() => Value.ToString();
+
+ ///
+ public string ToString(IFormatProvider provider) => Value.ToString(provider);
+
+ ///
+ int IComparable.CompareTo(object obj) => Value.CompareTo(Convert.ChangeType(obj, typeof(DateTime)));
+
+ ///
+ bool IConvertible.ToBoolean(IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider);
+
+ ///
+ byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)Value).ToByte(provider);
+
+ ///
+ char IConvertible.ToChar(IFormatProvider provider) => ((IConvertible)Value).ToChar(provider);
+
+ ///
+ DateTime IConvertible.ToDateTime(IFormatProvider provider) => ((IConvertible)Value).ToDateTime(provider);
+
+ ///
+ decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)Value).ToDecimal(provider);
+
+ ///
+ double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)Value).ToDouble(provider);
+
+ ///
+ short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)Value).ToInt16(provider);
+
+ ///
+ int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)Value).ToInt32(provider);
+
+ ///
+ long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)Value).ToInt64(provider);
+
+ ///
+ sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)Value).ToSByte(provider);
+
+ ///
+ float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)Value).ToSingle(provider);
+
+ ///
+ object IConvertible.ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider);
+
+ ///
+ ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)Value).ToUInt16(provider);
+
+ ///
+ uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)Value).ToUInt32(provider);
+
+ ///
+ ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)Value).ToUInt64(provider);
+
+ internal class DATETypeConverter : DecimalConverter
+ {
+ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
+ {
+ if (!(value is DATE b)) throw new ArgumentException();
+ return base.ConvertTo(context, culture, b.Value, destinationType);
+ }
+
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) =>
+ new DATE((DateTime)base.ConvertFrom(context, culture, value));
+ }
+ }
+}
\ No newline at end of file
diff --git a/PInvoke/Ole/Ole32/WTypes.DECIMAL.cs b/PInvoke/Ole/Ole32/WTypes.DECIMAL.cs
new file mode 100644
index 00000000..a6358121
--- /dev/null
+++ b/PInvoke/Ole/Ole32/WTypes.DECIMAL.cs
@@ -0,0 +1,184 @@
+using System;
+using System.ComponentModel;
+using System.Globalization;
+using System.Runtime.InteropServices;
+
+namespace Vanara
+{
+ /// Managed instance of the OLE DECIMAL type.
+ [StructLayout(LayoutKind.Sequential), Serializable]
+ [TypeConverter(typeof(DECIMALTypeConverter))]
+ public struct DECIMAL : IEquatable, IComparable, IEquatable, IComparable, IConvertible, IComparable
+ {
+ private ushort wReserved;
+ private byte scale;
+ private byte sign;
+ private uint Hi32;
+ private uint Lo32;
+ private uint Mid32;
+
+ /// Initializes a new instance of the struct.
+ /// The value.
+ public DECIMAL(decimal value)
+ {
+ wReserved = 0;
+ var bits = decimal.GetBits(value);
+ Lo32 = unchecked((uint)bits[0]);
+ Mid32 = unchecked((uint)bits[1]);
+ Hi32 = unchecked((uint)bits[2]);
+ sign = value < 0m ? (byte)0x80 : (byte)0;
+ scale = (byte)((unchecked((uint)bits[3]) | 0x00FF0000) >> 16);
+ }
+
+ /// Gets the value.
+ /// The value.
+ public decimal Value => new decimal(unchecked((int)Lo32), unchecked((int)Mid32), unchecked((int)Hi32), sign == 0x80, scale);
+
+ /// Performs an implicit conversion from to .
+ /// The value.
+ /// The result of the conversion.
+ public static implicit operator DECIMAL(decimal value) => new DECIMAL(value);
+
+ /// Performs an explicit conversion from to .
+ /// The value.
+ /// The result of the conversion.
+ public static explicit operator decimal(DECIMAL value) => value.Value;
+
+ /// Indicates whether two instances are not equal.
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is not equal to the value of ; otherwise, .
+ ///
+ public static bool operator !=(DECIMAL s1, DECIMAL s2) => !s1.Equals(s2);
+
+ /// Indicates whether a specified is less than another specified .
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is less than the value of ; otherwise, .
+ ///
+ public static bool operator <(DECIMAL s1, DECIMAL s2) => s1.CompareTo(s2) < 0;
+
+ /// Indicates whether a specified is less than or equal to another specified .
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is less than or equal to the value of ;
+ /// otherwise, .
+ ///
+ public static bool operator <=(DECIMAL s1, DECIMAL s2) => s1.CompareTo(s2) <= 0;
+
+ /// Indicates whether two instances are equal.
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is equal to the value of ; otherwise, .
+ ///
+ public static bool operator ==(DECIMAL s1, DECIMAL s2) => s1.Equals(s2);
+
+ /// Indicates whether a specified is greater than another specified .
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is greater than the value of ; otherwise, .
+ ///
+ public static bool operator >(DECIMAL s1, DECIMAL s2) => s1.CompareTo(s2) > 0;
+
+ /// Indicates whether a specified is greater than or equal to another specified .
+ /// The first integral size to compare.
+ /// The second integral size to compare.
+ ///
+ /// if the value of is greater than or equal to the value of ;
+ /// otherwise, .
+ ///
+ public static bool operator >=(DECIMAL s1, DECIMAL s2) => s1.CompareTo(s2) >= 0;
+
+ ///
+ public int CompareTo(DECIMAL other) => Value.CompareTo(other.Value);
+
+ ///
+ public int CompareTo(decimal other) => Value.CompareTo(other);
+
+ ///
+ public override bool Equals(object obj) => obj is DECIMAL s ? Equals(s) : (obj is decimal b ? Value.Equals(b) : Value.Equals(obj));
+
+ ///
+ public bool Equals(DECIMAL other) => Value.Equals(other.Value);
+
+ ///
+ public bool Equals(decimal other) => Value.Equals(other);
+
+ ///
+ public override int GetHashCode() => Value.GetHashCode();
+
+ ///
+ public TypeCode GetTypeCode() => Value.GetTypeCode();
+
+ ///
+ public override string ToString() => Value.ToString();
+
+ ///
+ public string ToString(IFormatProvider provider) => Value.ToString(provider);
+
+ ///
+ int IComparable.CompareTo(object obj) => Value.CompareTo(Convert.ChangeType(obj, typeof(decimal)));
+
+ ///
+ bool IConvertible.ToBoolean(IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider);
+
+ ///
+ byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)Value).ToByte(provider);
+
+ ///
+ char IConvertible.ToChar(IFormatProvider provider) => ((IConvertible)Value).ToChar(provider);
+
+ ///
+ DateTime IConvertible.ToDateTime(IFormatProvider provider) => ((IConvertible)Value).ToDateTime(provider);
+
+ ///
+ decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)Value).ToDecimal(provider);
+
+ ///
+ double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)Value).ToDouble(provider);
+
+ ///
+ short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)Value).ToInt16(provider);
+
+ ///
+ int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)Value).ToInt32(provider);
+
+ ///
+ long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)Value).ToInt64(provider);
+
+ ///
+ sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)Value).ToSByte(provider);
+
+ ///
+ float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)Value).ToSingle(provider);
+
+ ///
+ object IConvertible.ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider);
+
+ ///
+ ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)Value).ToUInt16(provider);
+
+ ///
+ uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)Value).ToUInt32(provider);
+
+ ///
+ ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)Value).ToUInt64(provider);
+
+ internal class DECIMALTypeConverter : DecimalConverter
+ {
+ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
+ {
+ if (!(value is DECIMAL b)) throw new ArgumentException();
+ return base.ConvertTo(context, culture, b.Value, destinationType);
+ }
+
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) =>
+ new DECIMAL((decimal)base.ConvertFrom(context, culture, value));
+ }
+ }
+}
\ No newline at end of file