diff --git a/PInvoke/Shared/WinNT/LCID.cs b/PInvoke/Shared/WinNT/LCID.cs
index 9885fbf4..4a1aca89 100644
--- a/PInvoke/Shared/WinNT/LCID.cs
+++ b/PInvoke/Shared/WinNT/LCID.cs
@@ -1,5 +1,4 @@
using System;
-using System.ComponentModel;
using System.Globalization;
using System.Runtime.InteropServices;
@@ -8,14 +7,76 @@ namespace Vanara.PInvoke
///
/// An LCID is a 4-byte value. The value supplied in an LCID is a standard numeric substitution for the international [RFC5646] string.
///
+ ///
+ ///
+ ///
+ ///
///
- ///
- ///
+ ///
+ ///
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("winnls.h")]
- public partial struct LCID : IComparable, IComparable, IEquatable
+ public partial struct LCID : IComparable, IComparable, IConvertible, IEquatable, IEquatable
{
- internal readonly uint _value;
+ /// Sort order identifiers.
+ public enum SORT : byte
+ {
+ /// sorting default
+ SORT_DEFAULT = 0x0,
+
+ /// Invariant (Mathematical Symbols)
+ SORT_INVARIANT_MATH = 0x1,
+
+ /// Japanese XJIS order
+ SORT_JAPANESE_XJIS = 0x0,
+
+ /// Japanese Unicode order (no longer supported)
+ SORT_JAPANESE_UNICODE = 0x1,
+
+ /// Japanese radical/stroke order
+ SORT_JAPANESE_RADICALSTROKE = 0x4,
+
+ /// Chinese BIG5 order
+ SORT_CHINESE_BIG5 = 0x0,
+
+ /// PRC Chinese Phonetic order
+ SORT_CHINESE_PRCP = 0x0,
+
+ /// Chinese Unicode order (no longer supported)
+ SORT_CHINESE_UNICODE = 0x1,
+
+ /// PRC Chinese Stroke Count order
+ SORT_CHINESE_PRC = 0x2,
+
+ /// Traditional Chinese Bopomofo order
+ SORT_CHINESE_BOPOMOFO = 0x3,
+
+ /// Traditional Chinese radical/stroke order.
+ SORT_CHINESE_RADICALSTROKE = 0x4,
+
+ /// Korean KSC order
+ SORT_KOREAN_KSC = 0x0,
+
+ /// Korean Unicode order (no longer supported)
+ SORT_KOREAN_UNICODE = 0x1,
+
+ /// German Phone Book order
+ SORT_GERMAN_PHONE_BOOK = 0x1,
+
+ /// Hungarian Default order
+ SORT_HUNGARIAN_DEFAULT = 0x0,
+
+ /// Hungarian Technical order
+ SORT_HUNGARIAN_TECHNICAL = 0x1,
+
+ /// Georgian Traditional order
+ SORT_GEORGIAN_TRADITIONAL = 0x0,
+
+ /// Georgian Modern order
+ SORT_GEORGIAN_MODERN = 0x1,
+ }
+
+ internal uint _value;
private const int langMask = 0x0FFFF;
private const uint sortMask = 0xF0000;
@@ -25,6 +86,23 @@ namespace Vanara.PInvoke
/// The raw LCID value.
public LCID(uint rawValue) => _value = rawValue;
+ /// Initializes a new instance of the structure.
+ ///
+ /// Language identifier. This parameter is a combination of a primary language identifier and a sublanguage identifier.
+ ///
+ /// Sort order identifier.
+ public LCID(LANGID lgid, SORT srtid) => _value = (((uint)(ushort)srtid) << sortShift) | lgid;
+
+ /// Retrieves a language identifier from a locale identifier.
+ public LANGID LANGID => (LANGID)_value;
+
+ /// Retrieves a sort order identifier from a locale identifier.
+ public SORT SORTID => (SORT)(((_value) >> sortShift) & 0xf);
+
+ /// Gets the value.
+ /// The value.
+ public uint Value { get => _value; private set => _value = value; }
+
/// Compares the current object with another object of the same type.
/// An object to compare with this object.
///
@@ -44,29 +122,37 @@ namespace Vanara.PInvoke
/// than zero This instance precedes in the sort order. Zero This instance occurs in the same position in the
/// sort order as . Greater than zero This instance follows in the sort order.
///
- public int CompareTo(object obj)
- {
- if (!(obj is IConvertible c)) throw new ArgumentException(@"Object cannot be converted to a UInt32 value for comparison.", nameof(obj));
- return _value.CompareTo(c.ToUInt32(null));
- }
+ public int CompareTo(object obj) => obj is IConvertible c ? _value.CompareTo(c.ToUInt32(null)) :
+ throw new ArgumentException(@"Object cannot be converted to a UInt32 value for comparison.", nameof(obj));
/// Determines whether the specified , is equal to this instance.
/// The to compare with this instance.
/// true if the specified is equal to this instance; otherwise, false.
- public override bool Equals(object obj) => obj is IConvertible c ? _value.Equals(c.ToUInt32(null)) : false;
+ public override bool Equals(object obj) => obj is IConvertible c && _value.Equals(c.ToUInt32(null));
/// Indicates whether the current object is equal to another object of the same type.
/// An object to compare with this object.
/// true if the current object is equal to the parameter; otherwise, false.
public bool Equals(LCID other) => other._value == _value;
+ /// Indicates whether the current object is equal to another object of the same type.
+ /// An object to compare with this object.
+ /// true if the current object is equal to the parameter; otherwise, false.
+ public bool Equals(uint other) => other == _value;
+
/// Returns a hash code for this instance.
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
public override int GetHashCode() => _value.GetHashCode();
+ ///
+ public TypeCode GetTypeCode() => Value.GetTypeCode();
+
/// Returns a that represents this instance.
/// A that represents this instance.
- public override string ToString() => string.Format(CultureInfo.InvariantCulture, "0x{0:X8}", _value);
+ public override string ToString() => ToString(CultureInfo.InvariantCulture);
+
+ ///
+ public string ToString(IFormatProvider provider) => string.Format(provider, "0x{0:X8}", _value);
/// Implements the operator ==.
/// The first .
@@ -92,14 +178,104 @@ namespace Vanara.PInvoke
/// The result of the operator.
public static bool operator !=(LCID hrLeft, uint hrRight) => !(hrLeft == hrRight);
- /// Performs an implicit conversion from to .
+ /// Performs an implicit conversion from to .
/// The value.
/// The result of the conversion.
- public static implicit operator LCID(uint value) => new LCID(value);
+ public static implicit operator LCID(uint value) => new(value);
- /// Performs an explicit conversion from to .
+ /// Performs an explicit conversion from to .
/// The value.
/// The result of the conversion.
public static explicit operator uint(LCID value) => value._value;
+
+ /// The default locale for the operating system. The value of this constant is 0x0800.
+ public static LCID LOCALE_SYSTEM_DEFAULT = new(LANGID.LANG_SYSTEM_DEFAULT, SORT.SORT_DEFAULT);
+
+ /// The default locale for the user or process. The value of this constant is 0x0400.
+ public static LCID LOCALE_USER_DEFAULT = new(LANGID.LANG_USER_DEFAULT, SORT.SORT_DEFAULT);
+
+ ///
+ /// Windows Vista and later: The default custom locale. When an NLS function must return a locale identifier for a supplemental
+ /// locale for the current user, the function returns this value instead of LOCALE_USER_DEFAULT. The value of LOCALE_CUSTOM_DEFAULT
+ /// is 0x0C00.
+ ///
+ public static LCID LOCALE_CUSTOM_DEFAULT => new(new LANGID(LANGID.LANG.LANG_NEUTRAL, LANGID.SUBLANG.SUBLANG_CUSTOM_DEFAULT), SORT.SORT_DEFAULT);
+
+ ///
+ /// Windows Vista and later: An unspecified custom locale, used to identify all supplemental locales except the locale for the
+ /// current user. Supplemental locales cannot be distinguished from one another by their locale identifiers, but can be
+ /// distinguished by their locale names. Certain NLS functions can return this constant to indicate that they cannot provide a
+ /// useful identifier for a particular locale. The value of LOCALE_CUSTOM_UNSPECIFIED is 0x1000.
+ ///
+ public static LCID LOCALE_CUSTOM_UNSPECIFIED => new(new LANGID(LANGID.LANG.LANG_NEUTRAL, LANGID.SUBLANG.SUBLANG_CUSTOM_UNSPECIFIED), SORT.SORT_DEFAULT);
+
+ ///
+ /// Windows Vista and later: The default custom locale for MUI. The user preferred UI languages and the system preferred UI
+ /// languages can include at most a single language that is implemented by a Language Interface Pack (LIP) and for which the
+ /// language identifier corresponds to a supplemental locale. If there is such a language in a list, the constant is used to refer
+ /// to that language in certain contexts. The value of LOCALE_CUSTOM_UI_DEFAULT is 0x1400.
+ ///
+ public static LCID LOCALE_CUSTOM_UI_DEFAULT => new(new LANGID(LANGID.LANG.LANG_NEUTRAL, LANGID.SUBLANG.SUBLANG_UI_CUSTOM_DEFAULT), SORT.SORT_DEFAULT);
+
+ ///
+ /// The neutral locale. This constant is generally not used when calling NLS APIs. Instead, use either LOCALE_SYSTEM_DEFAULT or
+ /// LOCALE_USER_DEFAULT. The value of LOCALE_NEUTRAL is 0x0000.
+ ///
+ public static LCID LOCALE_NEUTRAL => new(new LANGID(LANGID.LANG.LANG_NEUTRAL, LANGID.SUBLANG.SUBLANG_NEUTRAL), SORT.SORT_DEFAULT);
+
+ ///
+ /// Windows XP: The locale used for operating system-level functions that require consistent and locale-independent results. For
+ /// example, the invariant locale is used when an application compares character strings using the CompareString function and
+ /// expects a consistent result regardless of the user locale. The settings of the invariant locale are similar to those for English
+ /// (United States) but should not be used to display formatted data. Typically, an application does not use LOCALE_INVARIANT
+ /// because it expects the results of an action to depend on the rules governing each individual locale. The value of
+ /// LOCALE_INVARIANT IS 0x007f.
+ ///
+ public static LCID LOCALE_INVARIANT => new(new LANGID(LANGID.LANG.LANG_INVARIANT, LANGID.SUBLANG.SUBLANG_NEUTRAL), SORT.SORT_DEFAULT);
+
+ ///
+ 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);
}
}
\ No newline at end of file