From 972a2d4908a4e78269e8cd515d3b356cb6606453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bl=C3=A4sing?= Date: Sat, 4 Feb 2017 21:32:18 +0100 Subject: [PATCH 1/4] Add default locale, LCID and LANG to WinNT.javas --- .../src/com/sun/jna/platform/win32/WinNT.java | 347 ++++++++++++++++++ 1 file changed, 347 insertions(+) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java index 26f432a30d..adc8111e27 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java @@ -3272,4 +3272,351 @@ protected List getFieldOrder() { byte SECURITY_STATIC_TRACKING = (byte) 0; byte BOOLEAN_TRUE = (byte) 1; byte BOOLEAN_FALSE = (byte) 0; + + /* + * Primary language IDs. + */ + public static final int LANG_NEUTRAL = 0x00; + public static final int LANG_INVARIANT = 0x7f; + + public static final int LANG_AFRIKAANS = 0x36; + public static final int LANG_ALBANIAN = 0x1c; + public static final int LANG_ARABIC = 0x01; + public static final int LANG_ARMENIAN = 0x2b; + public static final int LANG_ASSAMESE = 0x4d; + public static final int LANG_AZERI = 0x2c; + public static final int LANG_BASQUE = 0x2d; + public static final int LANG_BELARUSIAN = 0x23; + public static final int LANG_BENGALI = 0x45; + public static final int LANG_BULGARIAN = 0x02; + public static final int LANG_CATALAN = 0x03; + public static final int LANG_CHINESE = 0x04; + public static final int LANG_CROATIAN = 0x1a; + public static final int LANG_CZECH = 0x05; + public static final int LANG_DANISH = 0x06; + public static final int LANG_DIVEHI = 0x65; + public static final int LANG_DUTCH = 0x13; + public static final int LANG_ENGLISH = 0x09; + public static final int LANG_ESTONIAN = 0x25; + public static final int LANG_FAEROESE = 0x38; + public static final int LANG_FARSI = 0x29; + public static final int LANG_FINNISH = 0x0b; + public static final int LANG_FRENCH = 0x0c; + public static final int LANG_GALICIAN = 0x56; + public static final int LANG_GEORGIAN = 0x37; + public static final int LANG_GERMAN = 0x07; + public static final int LANG_GREEK = 0x08; + public static final int LANG_GUJARATI = 0x47; + public static final int LANG_HEBREW = 0x0d; + public static final int LANG_HINDI = 0x39; + public static final int LANG_HUNGARIAN = 0x0e; + public static final int LANG_ICELANDIC = 0x0f; + public static final int LANG_INDONESIAN = 0x21; + public static final int LANG_ITALIAN = 0x10; + public static final int LANG_JAPANESE = 0x11; + public static final int LANG_KANNADA = 0x4b; + public static final int LANG_KASHMIRI = 0x60; + public static final int LANG_KAZAK = 0x3f; + public static final int LANG_KONKANI = 0x57; + public static final int LANG_KOREAN = 0x12; + public static final int LANG_KYRGYZ = 0x40; + public static final int LANG_LATVIAN = 0x26; + public static final int LANG_LITHUANIAN = 0x27; + public static final int LANG_MACEDONIAN = 0x2f; // the Former Yugoslav Republic of Macedonia + public static final int LANG_MALAY = 0x3e; + public static final int LANG_MALAYALAM = 0x4c; + public static final int LANG_MANIPURI = 0x58; + public static final int LANG_MARATHI = 0x4e; + public static final int LANG_MONGOLIAN = 0x50; + public static final int LANG_NEPALI = 0x61; + public static final int LANG_NORWEGIAN = 0x14; + public static final int LANG_ORIYA = 0x48; + public static final int LANG_POLISH = 0x15; + public static final int LANG_PORTUGUESE = 0x16; + public static final int LANG_PUNJABI = 0x46; + public static final int LANG_ROMANIAN = 0x18; + public static final int LANG_RUSSIAN = 0x19; + public static final int LANG_SANSKRIT = 0x4f; + public static final int LANG_SERBIAN = 0x1a; + public static final int LANG_SINDHI = 0x59; + public static final int LANG_SLOVAK = 0x1b; + public static final int LANG_SLOVENIAN = 0x24; + public static final int LANG_SPANISH = 0x0a; + public static final int LANG_SWAHILI = 0x41; + public static final int LANG_SWEDISH = 0x1d; + public static final int LANG_SYRIAC = 0x5a; + public static final int LANG_TAMIL = 0x49; + public static final int LANG_TATAR = 0x44; + public static final int LANG_TELUGU = 0x4a; + public static final int LANG_THAI = 0x1e; + public static final int LANG_TURKISH = 0x1f; + public static final int LANG_UKRAINIAN = 0x22; + public static final int LANG_URDU = 0x20; + public static final int LANG_UZBEK = 0x43; + public static final int LANG_VIETNAMESE = 0x2a; + + /* + * Sublanguage IDs. + * + * The name immediately following SUBLANG_ dictates which primary + * language ID that sublanguage ID can be combined with to form a + * valid language ID. + */ + public static final int SUBLANG_NEUTRAL = 0x00; // language neutral + public static final int SUBLANG_DEFAULT = 0x01; // user default + public static final int SUBLANG_SYS_DEFAULT = 0x02; // system default + + public static final int SUBLANG_ARABIC_SAUDI_ARABIA = 0x01; // Arabic (Saudi Arabia) + public static final int SUBLANG_ARABIC_IRAQ = 0x02; // Arabic (Iraq) + public static final int SUBLANG_ARABIC_EGYPT = 0x03; // Arabic (Egypt) + public static final int SUBLANG_ARABIC_LIBYA = 0x04; // Arabic (Libya) + public static final int SUBLANG_ARABIC_ALGERIA = 0x05; // Arabic (Algeria) + public static final int SUBLANG_ARABIC_MOROCCO = 0x06; // Arabic (Morocco) + public static final int SUBLANG_ARABIC_TUNISIA = 0x07; // Arabic (Tunisia) + public static final int SUBLANG_ARABIC_OMAN = 0x08; // Arabic (Oman) + public static final int SUBLANG_ARABIC_YEMEN = 0x09; // Arabic (Yemen) + public static final int SUBLANG_ARABIC_SYRIA = 0x0a; // Arabic (Syria) + public static final int SUBLANG_ARABIC_JORDAN = 0x0b; // Arabic (Jordan) + public static final int SUBLANG_ARABIC_LEBANON = 0x0c; // Arabic (Lebanon) + public static final int SUBLANG_ARABIC_KUWAIT = 0x0d; // Arabic (Kuwait) + public static final int SUBLANG_ARABIC_UAE = 0x0e; // Arabic (U.A.E) + public static final int SUBLANG_ARABIC_BAHRAIN = 0x0f; // Arabic (Bahrain) + public static final int SUBLANG_ARABIC_QATAR = 0x10; // Arabic (Qatar) + public static final int SUBLANG_AZERI_LATIN = 0x01; // Azeri (Latin) + public static final int SUBLANG_AZERI_CYRILLIC = 0x02; // Azeri (Cyrillic) + public static final int SUBLANG_CHINESE_TRADITIONAL = 0x01; // Chinese (Taiwan) + public static final int SUBLANG_CHINESE_SIMPLIFIED = 0x02; // Chinese (PR China) + public static final int SUBLANG_CHINESE_HONGKONG = 0x03; // Chinese (Hong Kong S.A.R., P.R.C.) + public static final int SUBLANG_CHINESE_SINGAPORE = 0x04; // Chinese (Singapore) + public static final int SUBLANG_CHINESE_MACAU = 0x05; // Chinese (Macau S.A.R.) + public static final int SUBLANG_DUTCH = 0x01; // Dutch + public static final int SUBLANG_DUTCH_BELGIAN = 0x02; // Dutch (Belgian) + public static final int SUBLANG_ENGLISH_US = 0x01; // English (USA) + public static final int SUBLANG_ENGLISH_UK = 0x02; // English (UK) + public static final int SUBLANG_ENGLISH_AUS = 0x03; // English (Australian) + public static final int SUBLANG_ENGLISH_CAN = 0x04; // English (Canadian) + public static final int SUBLANG_ENGLISH_NZ = 0x05; // English (New Zealand) + public static final int SUBLANG_ENGLISH_EIRE = 0x06; // English (Irish) + public static final int SUBLANG_ENGLISH_SOUTH_AFRICA = 0x07; // English (South Africa) + public static final int SUBLANG_ENGLISH_JAMAICA = 0x08; // English (Jamaica) + public static final int SUBLANG_ENGLISH_CARIBBEAN = 0x09; // English (Caribbean) + public static final int SUBLANG_ENGLISH_BELIZE = 0x0a; // English (Belize) + public static final int SUBLANG_ENGLISH_TRINIDAD = 0x0b; // English (Trinidad) + public static final int SUBLANG_ENGLISH_ZIMBABWE = 0x0c; // English (Zimbabwe) + public static final int SUBLANG_ENGLISH_PHILIPPINES = 0x0d; // English (Philippines) + public static final int SUBLANG_FRENCH = 0x01; // French + public static final int SUBLANG_FRENCH_BELGIAN = 0x02; // French (Belgian) + public static final int SUBLANG_FRENCH_CANADIAN = 0x03; // French (Canadian) + public static final int SUBLANG_FRENCH_SWISS = 0x04; // French (Swiss) + public static final int SUBLANG_FRENCH_LUXEMBOURG = 0x05; // French (Luxembourg) + public static final int SUBLANG_FRENCH_MONACO = 0x06; // French (Monaco) + public static final int SUBLANG_GERMAN = 0x01; // German + public static final int SUBLANG_GERMAN_SWISS = 0x02; // German (Swiss) + public static final int SUBLANG_GERMAN_AUSTRIAN = 0x03; // German (Austrian) + public static final int SUBLANG_GERMAN_LUXEMBOURG = 0x04; // German (Luxembourg) + public static final int SUBLANG_GERMAN_LIECHTENSTEIN = 0x05; // German (Liechtenstein) + public static final int SUBLANG_ITALIAN = 0x01; // Italian + public static final int SUBLANG_ITALIAN_SWISS = 0x02; // Italian (Swiss) + public static final int SUBLANG_KASHMIRI_SASIA = 0x02; // Kashmiri (South Asia) + public static final int SUBLANG_KASHMIRI_INDIA = 0x02; // For app compatibility only + public static final int SUBLANG_KOREAN = 0x01; // Korean (Extended Wansung) + public static final int SUBLANG_LITHUANIAN = 0x01; // Lithuanian + public static final int SUBLANG_MALAY_MALAYSIA = 0x01; // Malay (Malaysia) + public static final int SUBLANG_MALAY_BRUNEI_DARUSSALAM = 0x02; // Malay (Brunei Darussalam) + public static final int SUBLANG_NEPALI_INDIA = 0x02; // Nepali (India) + public static final int SUBLANG_NORWEGIAN_BOKMAL = 0x01; // Norwegian (Bokmal) + public static final int SUBLANG_NORWEGIAN_NYNORSK = 0x02; // Norwegian (Nynorsk) + public static final int SUBLANG_PORTUGUESE = 0x02; // Portuguese + public static final int SUBLANG_PORTUGUESE_BRAZILIAN = 0x01; // Portuguese (Brazilian) + public static final int SUBLANG_SERBIAN_LATIN = 0x02; // Serbian (Latin) + public static final int SUBLANG_SERBIAN_CYRILLIC = 0x03; // Serbian (Cyrillic) + public static final int SUBLANG_SPANISH = 0x01; // Spanish (Castilian) + public static final int SUBLANG_SPANISH_MEXICAN = 0x02; // Spanish (Mexican) + public static final int SUBLANG_SPANISH_MODERN = 0x03; // Spanish (Spain) + public static final int SUBLANG_SPANISH_GUATEMALA = 0x04; // Spanish (Guatemala) + public static final int SUBLANG_SPANISH_COSTA_RICA = 0x05; // Spanish (Costa Rica) + public static final int SUBLANG_SPANISH_PANAMA = 0x06; // Spanish (Panama) + public static final int SUBLANG_SPANISH_DOMINICAN_REPUBLIC = 0x07; // Spanish (Dominican Republic) + public static final int SUBLANG_SPANISH_VENEZUELA = 0x08; // Spanish (Venezuela) + public static final int SUBLANG_SPANISH_COLOMBIA = 0x09; // Spanish (Colombia) + public static final int SUBLANG_SPANISH_PERU = 0x0a; // Spanish (Peru) + public static final int SUBLANG_SPANISH_ARGENTINA = 0x0b; // Spanish (Argentina) + public static final int SUBLANG_SPANISH_ECUADOR = 0x0c; // Spanish (Ecuador) + public static final int SUBLANG_SPANISH_CHILE = 0x0d; // Spanish (Chile) + public static final int SUBLANG_SPANISH_URUGUAY = 0x0e; // Spanish (Uruguay) + public static final int SUBLANG_SPANISH_PARAGUAY = 0x0f; // Spanish (Paraguay) + public static final int SUBLANG_SPANISH_BOLIVIA = 0x10; // Spanish (Bolivia) + public static final int SUBLANG_SPANISH_EL_SALVADOR = 0x11; // Spanish (El Salvador) + public static final int SUBLANG_SPANISH_HONDURAS = 0x12; // Spanish (Honduras) + public static final int SUBLANG_SPANISH_NICARAGUA = 0x13; // Spanish (Nicaragua) + public static final int SUBLANG_SPANISH_PUERTO_RICO = 0x14; // Spanish (Puerto Rico) + public static final int SUBLANG_SWEDISH = 0x01; // Swedish + public static final int SUBLANG_SWEDISH_FINLAND = 0x02; // Swedish (Finland) + public static final int SUBLANG_URDU_PAKISTAN = 0x01; // Urdu (Pakistan) + public static final int SUBLANG_URDU_INDIA = 0x02; // Urdu (India) + public static final int SUBLANG_UZBEK_LATIN = 0x01; // Uzbek (Latin) + public static final int SUBLANG_UZBEK_CYRILLIC = 0x02; // Uzbek (Cyrillic) + + /* + * Sorting IDs. + */ + public static final int SORT_DEFAULT = 0x0; // sorting default + + public static final int SORT_JAPANESE_XJIS = 0x0; // Japanese XJIS order + public static final int SORT_JAPANESE_UNICODE = 0x1; // Japanese Unicode order + + public static final int SORT_CHINESE_BIG5 = 0x0; // Chinese BIG5 order + public static final int SORT_CHINESE_PRCP = 0x0; // PRC Chinese Phonetic order + public static final int SORT_CHINESE_UNICODE = 0x1; // Chinese Unicode order + public static final int SORT_CHINESE_PRC = 0x2; // PRC Chinese Stroke Count order + public static final int SORT_CHINESE_BOPOMOFO = 0x3; // Traditional Chinese Bopomofo order + + public static final int SORT_KOREAN_KSC = 0x0; // Korean KSC order + public static final int SORT_KOREAN_UNICODE = 0x1; // Korean Unicode order + + public static final int SORT_GERMAN_PHONE_BOOK = 0x1; // German Phone Book order + + public static final int SORT_HUNGARIAN_DEFAULT = 0x0; // Hungarian Default order + public static final int SORT_HUNGARIAN_TECHNICAL = 0x1; // Hungarian Technical order + + public static final int SORT_GEORGIAN_TRADITIONAL = 0x0; // Georgian Traditional order + public static final int SORT_GEORGIAN_MODERN = 0x1; // Georgian Modern order + + public static final int NLS_VALID_LOCALE_MASK = 0x000fffff; + + /** + *

A language ID is a 16 bit value which is the combination of a + * primary language ID and a secondary language ID. The bits are + * allocated as follows:

+ * + *
+     *       +-----------------------+-------------------------+
+     *       |     Sublanguage ID    |   Primary Language ID   |
+     *       +-----------------------+-------------------------+
+     *        15                   10 9                       0   bit
+     *  
+ * + *

WARNING: This pattern isn't always follows, Serbina, Bosnian & Croation for example.

+ * + *

It is recommended that applications test for locale names or actual LCIDs.

+ * + *

Note that the LANG, SUBLANG construction is not always consistent. + * The named locale APIs (eg GetLocaleInfoEx) are recommended.

+ * + *

Language IDs do not exist for all locales

+ * + *

A locale ID is a 32 bit value which is the combination of a + * language ID, a sort ID, and a reserved area. The bits are + * allocated as follows:

+ * + *
+     *   +-------------+---------+-------------------------+
+     *   |   Reserved  | Sort ID |      Language ID        |
+     *   +-------------+---------+-------------------------+
+     *    31         20 19     16 15                      0   bit
+     * 
+ * + *

WARNING: This pattern isn't always followed (es-ES_tradnl vs es-ES for example)

+ * + *

It is recommended that applications test for locale names or actual LCIDs.

+ */ + public static final class LocaleMacros { + private static final int _MAKELCID(int lgid, int srtid) { + return (srtid << 16) | lgid; + } + + /** + * construct the locale id from a language id and a sort id. + * + * @param lgid + * @param srtid + * @return + */ + public static final LCID MAKELCID(int lgid, int srtid) { + return new LCID(_MAKELCID(lgid, srtid)); + } + + /** + * construct the locale id from a language id, sort id, and sort version. + * + * @param lgid + * @param srtid + * @param ver + * @return + */ + public static final LCID MAKESORTLCID(int lgid, int srtid, int ver) { + return new LCID(_MAKELCID(lgid, srtid) | (ver << 20)); + } + + /** + * extract the language id from a locale id. + * + * @param lcid + * @return + */ + public static final int LANGIDFROMLCID(LCID lcid) { + return lcid.intValue() & 0xFFFF; + } + + /** + * extract the sort id from a locale id. + * + * @param lcid + * @return + */ + public static final int SORTIDFROMLCID(LCID lcid) { + return (lcid.intValue() >>> 16) & 0xf; + } + + /** + * extract the sort version from a locale id. + * + * @param lcid + * @return + */ + public static final int SORTVERSIONFROMLCID(LCID lcid) { + return (lcid.intValue() >>> 20) & 0xf; + } + + /** + * Construct language id from a primary language id and a sublanguage id. + * + * @param p Language ID + * @param s Sublanguage ID + * @return + */ + public static final int MAKELANGID(int p, int s) { + return (s << 10) | (p & 0xFFFF); + } + + /** + * Extract primary language id from a language id. + * + * @param lgid Language ID + * @return + */ + public static final int PRIMARYLANGID(int lgid) { + return lgid & 0x3ff; + } + + /** + * Extract sublanguage id from a language id. + * + * @param lgid Language ID + * @return + */ + public static final int SUBLANGID(int lgid) { + return (lgid & 0xFFFF) >>> 10; + } + } + + public static final int LANG_SYSTEM_DEFAULT = LocaleMacros.MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT); + public static final int LANG_USER_DEFAULT = LocaleMacros.MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT); + + public static final LCID LOCALE_SYSTEM_DEFAULT = LocaleMacros.MAKELCID(LANG_SYSTEM_DEFAULT, SORT_DEFAULT); + public static final LCID LOCALE_USER_DEFAULT = LocaleMacros.MAKELCID(LANG_USER_DEFAULT, SORT_DEFAULT); + + public static final LCID LOCALE_NEUTRAL = LocaleMacros.MAKELCID(LocaleMacros.MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), SORT_DEFAULT); + + public static final LCID LOCALE_INVARIANT = LocaleMacros.MAKELCID(LocaleMacros.MAKELANGID(LANG_INVARIANT, SUBLANG_NEUTRAL), SORT_DEFAULT); } From 21404bf5f2583f0431f8ad3de149ab4b9c6dd752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bl=C3=A4sing?= Date: Sun, 5 Feb 2017 16:19:05 +0100 Subject: [PATCH 2/4] Add VARIANT conversion functions to OleAuto --- .../com/sun/jna/platform/win32/OleAuto.java | 158 ++++++++++++++++++ .../sun/jna/platform/win32/OleAutoTest.java | 31 ++++ 2 files changed, 189 insertions(+) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/OleAuto.java b/contrib/platform/src/com/sun/jna/platform/win32/OleAuto.java index 535955de6f..80a31b89d3 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/OleAuto.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/OleAuto.java @@ -239,6 +239,164 @@ public interface OleAuto extends StdCallLibrary { * @return the hresult */ HRESULT VariantClear(VARIANT pvarg); + + public static final short VARIANT_NOVALUEPROP = 0x01; + /** For VT_BOOL to VT_BSTR conversions, convert to "True"/"False" instead of "-1"/"0" */ + public static final short VARIANT_ALPHABOOL = 0x02; + /** For conversions to/from VT_BSTR, passes LOCALE_NOUSEROVERRIDE to core coercion routines */ + public static final short VARIANT_NOUSEROVERRIDE = 0x04; + public static final short VARIANT_CALENDAR_HIJRI = 0x08; + /** For VT_BOOL to VT_BSTR and back, convert to local language rather than English */ + public static final short VARIANT_LOCALBOOL = 0x10; + /** SOUTHASIA calendar support */ + public static final short VARIANT_CALENDAR_THAI = 0x20; + /** SOUTHASIA calendar support */ + public static final short VARIANT_CALENDAR_GREGORIAN = 0x40; + /** NLS function call support */ + public static final short VARIANT_USE_NLS = 0x80; + + /** + * Converts a variant from one type to another. + * @param pvargDest [out] The destination variant. If this is the same as + * pvarSrc, the variant will be converted in place. + * @param pvarSrc [in] The variant to convert. + * @param wFlags Combination of the following flags + * + * + * + * + * + * + * + * + * + * + *
wFlags
ValueMeaning
{@link #VARIANT_NOVALUEPROP}Prevents the function from attempting to coerce an object to a fundamental type by getting the Value property. Applications should set this flag only if necessary, because it makes their behavior inconsistent with other applications.
{@link #VARIANT_ALPHABOOL}Converts a {@link Variant#VT_BOOL VT_BOOL} value to a string containing either "True" or "False".
{@link #VARIANT_NOUSEROVERRIDE}For conversions to or from {@link Variant#VT_BSTR VT_BSTR}, passes LOCALE_NOUSEROVERRIDE to the core coercion routines.
{@link #VARIANT_LOCALBOOL}For conversions from {@link Variant#VT_BOOL VT_BOOL} to {@link Variant#VT_BSTR VT_BSTR} and back, uses the language specified by the locale in use on the local computer.
+ * @param vt The type to convert to. If the return code is {@link WinError#S_OK S_OK}, the vt + * field of the vargDest is guaranteed to be equal to this value. + * @return This function can return one of these values: + * + * + * + * + * + * + * + * + * + * + * + * + *
Return codeDescription
{@link WinError#S_OK S_OK}Success.
{@link WinError#DISP_E_BADVARTYPE DISP_E_BADVARTYPE}The variant type is not a valid type of variant.
{@link WinError#DISP_E_OVERFLOW DISP_E_OVERFLOW}The data pointed to by pvarSrc does not fit in the destination type.
{@link WinError#DISP_E_TYPEMISMATCH DISP_E_TYPEMISMATCH}The argument could not be coerced to the specified type.
{@link WinError#E_INVALIDARG E_INVALIDARG}One of the arguments is not valid.
{@link WinError#E_OUTOFMEMORY E_OUTOFMEMORY}Insufficient memory to complete the operation.
+ *

+ * Remarks + *

+ * The VariantChangeType function handles coercions between the fundamental + * types (including numeric-to-string and string-to-numeric coercions). The + * pvarSrc argument is changed during the conversion process. For example, + * if the source variant is of type {@link Variant#VT_BOOL VT_BOOL} and the + * destination is of type {@link Variant#VT_UINT VT_UINT}, the pvarSrc + * argument is first converted to {@link Variant#VT_I2 VT_I2} and then the + * conversion proceeds. A variant that has {@link Variant#VT_BYREF VT_BYREF} + * set is coerced to a value by obtaining the referenced value. An object is + * coerced to a value by invoking the object's Value property + * ({@link OaIdl#DISPID_VALUE DISPID_VALUE}). + *

+ * Typically, the implementor of + * {@link com.sun.jna.platform.win32.COM.IDispatch#Invoke IDispatch.Invoke} + * determines which member is being accessed, and then calls + * VariantChangeType to get the value of one or more arguments. For example, + * if the IDispatch call specifies a SetTitle member that takes one string + * argument, the implementor would call VariantChangeType to attempt to + * coerce the argument to {@link Variant#VT_BSTR VT_BSTR}. If + * VariantChangeType does not return an error, the argument could then be + * obtained directly from the + * {@link Variant.VARIANT._VARIANT.__VARIANT#bstrVal bstrVal} field of the + * {@link Variant.VARIANT VARIANT}. If VariantChangeType returns + * {@link WinError#DISP_E_TYPEMISMATCH DISP_E_TYPEMISMATCH}, the implementor + * would set {@link com.sun.jna.platform.win32.COM.IDispatch#Invoke Invoke} + * puArgErr parameter referenced value to 0 (indicating the + * argument in error) and return DISP_E_TYPEMISMATCH from Invoke. + *

+ * Arrays of one type cannot be converted to arrays of another type with + * this function. + *

+ * Note The type of a {@link Variant.VARIANT VARIANT} should not be + * changed in the {@link DISPPARAMS#rgvarg rgvarg} array in place. + */ + HRESULT VariantChangeType(VARIANT pvargDest, VARIANT pvarSrc, short wFlags, VARTYPE vt); + + /** + * Converts a variant from one type to another. + * @param pvargDest [out] The destination variant. If this is the same as + * pvarSrc, the variant will be converted in place. + * @param pvarSrc [in] The variant to convert. + * @param wFlags Combination of the following flags + * + * + * + * + * + * + * + * + * + * + *
wFlags
ValueMeaning
{@link #VARIANT_NOVALUEPROP}Prevents the function from attempting to coerce an object to a fundamental type by getting the Value property. Applications should set this flag only if necessary, because it makes their behavior inconsistent with other applications.
{@link #VARIANT_ALPHABOOL}Converts a {@link Variant#VT_BOOL VT_BOOL} value to a string containing either "True" or "False".
{@link #VARIANT_NOUSEROVERRIDE}For conversions to or from {@link Variant#VT_BSTR VT_BSTR}, passes LOCALE_NOUSEROVERRIDE to the core coercion routines.
{@link #VARIANT_LOCALBOOL}For conversions from {@link Variant#VT_BOOL VT_BOOL} to {@link Variant#VT_BSTR VT_BSTR} and back, uses the language specified by the locale in use on the local computer.
+ * @param vt The type to convert to. If the return code is {@link WinError#S_OK S_OK}, the vt + * field of the vargDest is guaranteed to be equal to this value. + * @return This function can return one of these values: + * + * + * + * + * + * + * + * + * + * + * + * + *
Return codeDescription
{@link WinError#S_OK S_OK}Success.
{@link WinError#DISP_E_BADVARTYPE DISP_E_BADVARTYPE}The variant type is not a valid type of variant.
{@link WinError#DISP_E_OVERFLOW DISP_E_OVERFLOW}The data pointed to by pvarSrc does not fit in the destination type.
{@link WinError#DISP_E_TYPEMISMATCH DISP_E_TYPEMISMATCH}The argument could not be coerced to the specified type.
{@link WinError#E_INVALIDARG E_INVALIDARG}One of the arguments is not valid.
{@link WinError#E_OUTOFMEMORY E_OUTOFMEMORY}Insufficient memory to complete the operation.
+ *

+ * Remarks + *

+ * The VariantChangeType function handles coercions between the fundamental + * types (including numeric-to-string and string-to-numeric coercions). The + * pvarSrc argument is changed during the conversion process. For example, + * if the source variant is of type {@link Variant#VT_BOOL VT_BOOL} and the + * destination is of type {@link Variant#VT_UINT VT_UINT}, the pvarSrc + * argument is first converted to {@link Variant#VT_I2 VT_I2} and then the + * conversion proceeds. A variant that has {@link Variant#VT_BYREF VT_BYREF} + * set is coerced to a value by obtaining the referenced value. An object is + * coerced to a value by invoking the object's Value property + * ({@link OaIdl#DISPID_VALUE DISPID_VALUE}). + *

+ * Typically, the implementor of + * {@link com.sun.jna.platform.win32.COM.IDispatch#Invoke IDispatch.Invoke} + * determines which member is being accessed, and then calls + * VariantChangeType to get the value of one or more arguments. For example, + * if the IDispatch call specifies a SetTitle member that takes one string + * argument, the implementor would call VariantChangeType to attempt to + * coerce the argument to {@link Variant#VT_BSTR VT_BSTR}. If + * VariantChangeType does not return an error, the argument could then be + * obtained directly from the + * {@link Variant.VARIANT._VARIANT.__VARIANT#bstrVal bstrVal} field of the + * {@link Variant.VARIANT VARIANT}. If VariantChangeType returns + * {@link WinError#DISP_E_TYPEMISMATCH DISP_E_TYPEMISMATCH}, the implementor + * would set {@link com.sun.jna.platform.win32.COM.IDispatch#Invoke Invoke} + * puArgErr parameter referenced value to 0 (indicating the + * argument in error) and return DISP_E_TYPEMISMATCH from Invoke. + *

+ * Arrays of one type cannot be converted to arrays of another type with + * this function. + *

+ * Note The type of a {@link Variant.VARIANT VARIANT} should not be + * changed in the {@link DISPPARAMS#rgvarg rgvarg} array in place. + */ + HRESULT VariantChangeType(VARIANT.ByReference pvargDest, VARIANT.ByReference pvarSrc, short wFlags, VARTYPE vt); + /** * Creates a new array descriptor, allocates and initializes the data for diff --git a/contrib/platform/test/com/sun/jna/platform/win32/OleAutoTest.java b/contrib/platform/test/com/sun/jna/platform/win32/OleAutoTest.java index 1f8f758c38..ec22397fa8 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/OleAutoTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/OleAutoTest.java @@ -20,6 +20,8 @@ import com.sun.jna.platform.win32.WinDef.LCID; import com.sun.jna.platform.win32.WinNT.HRESULT; import com.sun.jna.platform.win32.COM.COMUtils; +import com.sun.jna.platform.win32.Variant.VARIANT; +import com.sun.jna.platform.win32.WTypes.VARTYPE; import com.sun.jna.ptr.PointerByReference; /** @@ -62,4 +64,33 @@ public void testLoadRegTypeLib() { assertEquals(0, hr.intValue()); } + public void testVariantConvertBoolean() { + VARIANT variant = new Variant.VARIANT(true); + OleAuto.INSTANCE.VariantChangeType(variant, variant, OleAuto.VARIANT_ALPHABOOL, new VARTYPE(Variant.VT_BSTR)); + assertEquals("Variant-Type", Variant.VT_BSTR, variant.getVarType().intValue()); + assertEquals("Variant-Value", "True", variant.stringValue()); + OleAuto.INSTANCE.VariantClear(variant); + + VARIANT.ByReference variant2 = new Variant.VARIANT.ByReference(); + variant2.setValue(Variant.VT_BOOL, new OaIdl.VARIANT_BOOL(true)); + OleAuto.INSTANCE.VariantChangeType(variant2, variant2, OleAuto.VARIANT_ALPHABOOL, new VARTYPE(Variant.VT_BSTR)); + assertEquals("Variant-Type", Variant.VT_BSTR, variant2.getVarType().intValue()); + assertEquals("Variant-Value", "True", variant2.stringValue()); + OleAuto.INSTANCE.VariantClear(variant2); + } + + public void testVariantConvertBSTR() { + VARIANT variant = new Variant.VARIANT("42"); + OleAuto.INSTANCE.VariantChangeType(variant, variant, (short) 0, new VARTYPE(Variant.VT_INT)); + assertEquals("Variant-Type", Variant.VT_INT, variant.getVarType().intValue()); + assertEquals("Variant-Value", 42, variant.intValue()); + OleAuto.INSTANCE.VariantClear(variant); + + VARIANT.ByReference variant2 = new Variant.VARIANT.ByReference(); + variant2.setValue(Variant.VT_BSTR, OleAuto.INSTANCE.SysAllocString("42")); + OleAuto.INSTANCE.VariantChangeType(variant2, variant2, (short) 0, new VARTYPE(Variant.VT_INT)); + assertEquals("Variant-Type", Variant.VT_INT, variant2.getVarType().intValue()); + assertEquals("Variant-Value", 42, variant2.intValue()); + OleAuto.INSTANCE.VariantClear(variant2); + } } From 2242c099b44696594eb6b44d7c242f9185824fbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bl=C3=A4sing?= Date: Sun, 5 Feb 2017 21:07:27 +0100 Subject: [PATCH 3/4] Add Ole32 Functions: * OleBuildVersion * OleInitialize * OleUninitialize * OleFlushClipboard * OleRun --- .../src/com/sun/jna/platform/win32/Ole32.java | 113 ++++++++++++++++++ .../com/sun/jna/platform/win32/Ole32Test.java | 12 ++ 2 files changed, 125 insertions(+) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java b/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java index 7ce2eb1b2f..bb3480a0b0 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java @@ -352,4 +352,117 @@ HRESULT CoCreateInstance(GUID rclsid, Pointer pUnkOuter, int dwClsContext, */ boolean CoIsHandlerConnected(Pointer pUnk); + + /** + * Initializes the COM library on the current apartment, identifies the + * concurrency model as single-thread apartment (STA), and enables + * additional functionality described in the Remarks section below. + * Applications must initialize the COM library before they can call COM + * library functions other than CoGetMalloc and memory allocation functions. + * @param pvReserved Reserved; must be null. + * @return {@link WinError#S_OK S_OK} if the COM library and additional functionality were + * initialized successfully on this apartment.

+ * {@link WinError#S_FALSE S_FALSE} if the COM library is already initialized on this apartment.

+ * {@link WinError#OLE_E_WRONGCOMPOBJ OLE_E_WRONGCOMPOBJ} if the versions of COMPOBJ.DLL and OLE2.DLL on + * your machine are incompatible with each other.

+ * {@link WinError#RPC_E_CHANGED_MODE RPC_E_CHANGED_MODE} if a previous call to CoInitializeEx specified + * the concurrency model for this apartment as + * multithread apartment (MTA). If running + * Windows 2000, this could also mean that a + * change from neutral threaded apartment to + * single threaded apartment occurred. + */ + HRESULT OleInitialize(Pointer pvReserved); + + /** + * Closes the COM library on the apartment, releases any class factories, + * other COM objects, or servers held by the apartment, disables RPC on the + * apartment, and frees any resources the apartment maintains. + * + * Remarks: + * Call OleUninitialize on application shutdown, as the last COM library + * call, if the apartment was initialized with a call to + * {@link #OleInitialize}. OleUninitialize calls the CoUninitialize function + * internally to shut down the OLE Component Object(COM) Library. + * + * If the COM library was initialized on the apartment with a call to + * CoInitialize or CoInitializeEx, it must be closed with a call to + * CoUninitialize. + * + * The {@link #OleInitialize} and OleUninitialize calls must be balanced — + * if there are multiple calls to the {@link #OleInitialize} function, there + * must be the same number of calls to OleUninitialize: Only the + * OleUninitialize call corresponding to the {@link #OleInitialize} call + * that actually initialized the library can close it. + */ + void OleUninitialize(); + + /** + * Carries out the clipboard shutdown sequence. It also releases the + * IDataObject pointer that was placed on the clipboard by the + * OleSetClipboard function. + * @return {@link WinError#S_OK S_OK} on success.

+ * {@link WinError#CLIPBRD_E_CANT_OPEN CLIPBRD_E_CANT_OPEN} The Windows OpenClipboard function used + * within OleFlushClipboard failed.

+ * {@link WinError#CLIPBRD_E_CANT_CLOSE CLIPBRD_E_CANT_CLOSE} The Windows CloseClipboard function used + * within OleFlushClipboard failed.

+ * Remarks

+ * OleFlushClipboard renders the data from a data object onto the clipboard + * and releases the IDataObject pointer to the data object. While the + * application that put the data object on the clipboard is running, the + * clipboard holds only a pointer to the data object, thus saving memory. + * If you are writing an application that acts as the source of a clipboard + * operation, you can call the OleFlushClipboard function when your + * application is closed, such as when the user exits from your application. + * Calling OleFlushClipboard enables pasting and paste-linking of OLE + * objects after application shutdown. + * Before calling OleFlushClipboard, you can easily determine if your data + * is still on the clipboard with a call to the OleIsCurrentClipboard + * function. + * + * OleFlushClipboard leaves all formats offered by the data transfer object, + * including the OLE 1 compatibility formats, on the clipboard so they are + * available after application shutdown. In addition to OLE 1 compatibility + * formats, these include all formats offered on a global handle medium (all + * except for TYMED_FILE) and formatted with a null target device. For + * example, if a data-source application offers a particular clipboard + * format (say cfFOO) on an IStorage object, and calls the OleFlushClipboard + * function, the storage object is copied into memory and the hglobal memory + * handle is put on the clipboard. + * + * To retrieve the information on the clipboard, you can call the + * OleGetClipboard function from another application, which creates a + * default data object, and the hglobal from the clipboard again becomes a + * storage object. Furthermore, the FORMATETC enumerator and the + * IDataObject::QueryGetData method would all correctly indicate that the + * original clipboard format (cfFOO) is again available on a TYMED_ISTORAGE. + * + * To empty the clipboard, call the OleSetClipboard function specifying a + * null value for its parameter. The application should call this when it + * closes if there is no need to leave data on the clipboard after shutdown, + * or if data will be placed on the clipboard using the standard Windows + * clipboard functions. + */ + HRESULT OleFlushClipboard(); + + /** + * Puts an OLE compound document object into the running state. + * @param pUnknown [in] Pointer to the {@link IUnknown IUnknown} interface + * on the object, with which it will query for a pointer to + * the IRunnableObject interface, and then call its Run method. + * @return This function returns on success. + * Other possible values include the following.

+ * {@link WinError#OLE_E_CLASSDIFF OLE_E_CLASSDIFF} The source of an + * OLE link has been converted to a different class.

+ * Remarks

+ * The OleRun function puts an object in the running state. The + * implementation of OleRun was changed in OLE 2.01 to coincide with the + * publication of the IRunnableObject interface. You can use OleRun and + * IRunnableObject::Run interchangeably. OleRun queries the object for a + * pointer to IRunnableObject. If successful, the function returns the + * results of calling the IRunnableObject::Run method.

+ * For more information on using this function, see IRunnableObject::Run. + */ + HRESULT OleRun(Pointer pUnknown); + } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Ole32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Ole32Test.java index 73ce524542..3cae8086c2 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Ole32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Ole32Test.java @@ -126,4 +126,16 @@ public void testCoTaskMemRealloc() { Ole32.INSTANCE.CoTaskMemFree(ptr); } + + public void testOleFunctions() { + HRESULT initResult = Ole32.INSTANCE.OleInitialize(Pointer.NULL); + + assertTrue(W32Errors.SUCCEEDED(initResult)); + + // For a real test, a test component will be needed + Ole32.INSTANCE.OleFlushClipboard(); + Ole32.INSTANCE.OleRun(Pointer.NULL); + + Ole32.INSTANCE.CoUninitialize(); + } } From 244dfe02f03257734e492aea330864d1f0e6535d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bl=C3=A4sing?= Date: Sat, 1 Apr 2017 22:10:35 +0200 Subject: [PATCH 4/4] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index e71c9445dd..7ed28ac20b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,7 @@ Release 4.5.0 (Next release) Features -------- * [#774](https://github.com/java-native-access/jna/pull/774): Addition win32 api : SendMessage, GetActiveWindow, COPYDATASTRUCT and a few constants + a demo application - [@cnico](https://github.com/cnico). +* [#783](https://github.com/java-native-access/jna/pull/783): Add Ole32 functions: `OleBuildVersion`, `OleInitialize`, `OleUninitialize`, `OleFlushClipboard`, `OleRun`, add VARIANT conversion functions to OleAuto, add default locale, LCID and LANG to WinNT - [@matthiasblaesing](https://github.com/matthiasblaesing). Bug Fixes ---------