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