cpp_quote("#include <winapifamily.h>")

//+-------------------------------------------------------------------------
//
//  Microsoft Windows
//  Copyright (c) Microsoft Corporation. All rights reserved.
//
//  File: mlang.idl
//
//  Contents: IMultiLanguage interface definition
//
//
//--------------------------------------------------------------------------

cpp_quote("//=--------------------------------------------------------------------------=")
cpp_quote("// MLang.h                                                                    ")
cpp_quote("//=--------------------------------------------------------------------------=")
cpp_quote("// Copyright (c) Microsoft Corporation. All rights reserved.")
cpp_quote("//                                                                            ")
cpp_quote("// THIS CODE AND INFORMATION IS PROVIDED \"AS IS\" WITHOUT WARRANTY OF        ")
cpp_quote("// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO        ")
cpp_quote("// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A             ")
cpp_quote("// PARTICULAR PURPOSE.                                                        ")
cpp_quote("//=--------------------------------------------------------------------------=")
cpp_quote("                                                                              ")
cpp_quote("#pragma comment(lib,\"uuid.lib\")                                             ")
cpp_quote("                                                                              ")
cpp_quote("//----------------------------------------------------------------------------")
cpp_quote("// IMultiLanguage Interfaces.                                                 ")
cpp_quote("                                                                              ")

#ifndef DO_NO_IMPORTS
import "unknwn.idl";
#endif

interface IStream;

#pragma region Desktop Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)")

    [
        local,
        uuid(D24ACD21-BA72-11D0-B188-00AA0038C969),
        helpstring("IMLangStringBufW Interface"),
        pointer_default(unique)
    ]
    interface IMLangStringBufW : IUnknown
    {
        HRESULT GetStatus([out, annotation("_Out_opt_")] long* plFlags, [out, annotation("_Out_opt_")] long* pcchBuf);
        HRESULT LockBuf([in] long cchOffset, [in] long cchMaxLock, [out, size_is(,*pcchBuf), annotation("_Outptr_result_buffer_(*pcchBuf)")] WCHAR** ppszBuf, [out, annotation("_Out_opt_")] long* pcchBuf);
        HRESULT UnlockBuf([in, size_is(cchWrite - cchOffset), annotation("_In_reads_(cchWrite-cchOffset)")] const WCHAR* pszBuf, [in] long cchOffset, [in] long cchWrite);
        HRESULT Insert([in] long cchOffset, [in] long cchMaxInsert, [out, annotation("_Out_opt_")] long* pcchActual);
        HRESULT Delete([in] long cchOffset, [in] long cchDelete);
    };

    [
        local,
        uuid(D24ACD23-BA72-11D0-B188-00AA0038C969),
        helpstring("IMLangStringBufA Interface"),
        pointer_default(unique)
    ]
    interface IMLangStringBufA : IUnknown
    {
        HRESULT GetStatus([out, annotation("_Out_opt_")] long* plFlags, [out, annotation("_Out_opt_")] long* pcchBuf);
        HRESULT LockBuf([in] long cchOffset, [in] long cchMaxLock, [out, size_is(,*pcchBuf), annotation("_Outptr_result_buffer_(*pcchBuf)")] CHAR** ppszBuf, [out, annotation("_Out_opt_")] long* pcchBuf);
        HRESULT UnlockBuf([in, size_is(cchWrite - cchOffset), annotation("_In_reads_(cchWrite-cchOffset)")] const CHAR* pszBuf, [in] long cchOffset, [in] long cchWrite);
        HRESULT Insert([in] long cchOffset, [in] long cchMaxInsert, [out, annotation("_Out_opt_")] long* pcchActual);
        HRESULT Delete([in] long cchOffset, [in] long cchDelete);
    };

    [
        local,
        uuid(C04D65CE-B70D-11D0-B188-00AA0038C969),
        helpstring("IMLangString Interface"),
        pointer_default(unique)
    ]
    interface IMLangString : IUnknown
    {
        HRESULT Sync([in] BOOL fNoAccess);
        HRESULT GetLength([out, retval, annotation("_Out_opt_")] long* plLen);
        HRESULT SetMLStr([in] long lDestPos, [in] long lDestLen, [in, annotation("_In_")] IUnknown* pSrcMLStr, [in] long lSrcPos, [in] long lSrcLen);
        HRESULT GetMLStr([in] long lSrcPos, [in] long lSrcLen, [in, annotation("_In_")] IUnknown* pUnkOuter, [in] DWORD dwClsContext, [in, annotation("_In_")] const IID* piid, [out, annotation("_Outptr_")] IUnknown** ppDestMLStr, [out, annotation("_Out_opt_")] long* plDestPos, [out, annotation("_Out_opt_")] long* plDestLen);
    };

    [
        local,
        uuid(C04D65D0-B70D-11D0-B188-00AA0038C969),
        helpstring("IMLangStringWStr Interface"),
        pointer_default(unique)
    ]
    interface IMLangStringWStr : IMLangString
    {
        HRESULT SetWStr([in] long lDestPos, [in] long lDestLen, [in, string, size_is(cchSrc), annotation("_In_reads_(cchSrc)")] LPCWSTR pszSrc, [in] long cchSrc, [out, annotation("_Out_opt_")] long* pcchActual, [out, annotation("_Out_opt_")] long* plActualLen);
        HRESULT SetStrBufW([in] long lDestPos, [in] long lDestLen, [in, unique, annotation("_In_opt_")] IMLangStringBufW* pSrcBuf, [out, annotation("_Out_opt_")] long* pcchActual, [out, annotation("_Out_opt_")] long* plActualLen);
        HRESULT GetWStr([in] long lSrcPos, [in] long lSrcLen, [out, size_is(cchDest), annotation("_Out_writes_opt_(cchDest)")] LPWSTR pszDest, [in] long cchDest, [out, annotation("_Out_opt_")] long* pcchActual, [out, annotation("_Out_opt_")] long* plActualLen);
        HRESULT GetStrBufW([in] long lSrcPos, [in] long lSrcMaxLen, [out, annotation("_Outptr_")] IMLangStringBufW** ppDestBuf, [out, annotation("_Out_opt_")] long* plDestLen);
        HRESULT LockWStr([in] long lSrcPos, [in] long lSrcLen, [in] long lFlags, [in] long cchRequest, [out, size_is(,*pcchDest), annotation("_Outptr_opt_result_buffer_(*pcchDest)")] LPWSTR* ppszDest, [out, annotation("_Out_opt_")] long* pcchDest, [out, annotation("_Out_opt_")] long* plDestLen);
        HRESULT UnlockWStr([in, string, size_is(cchSrc), annotation("_In_reads_(cchSrc)")] LPCWSTR pszSrc, [in] long cchSrc, [out, annotation("_Out_opt_")] long* pcchActual, [out, annotation("_Out_opt_")] long* plActualLen);
        HRESULT SetLocale([in] long lDestPos, [in] long lDestLen, [in] LCID locale);
        HRESULT GetLocale([in] long lSrcPos, [in] long lSrcMaxLen, [out, annotation("_Out_opt_")] LCID* plocale, [out, annotation("_Out_opt_")] long* plLocalePos, [out, annotation("_Out_opt_")] long* plLocaleLen);
    };

    [
        local,
        uuid(C04D65D2-B70D-11D0-B188-00AA0038C969),
        helpstring("IMLangStringAStr Interface"),
        pointer_default(unique)
    ]
    interface IMLangStringAStr : IMLangString
    {
        HRESULT SetAStr([in] long lDestPos, [in] long lDestLen, [in] UINT uCodePage, [in, size_is(cchSrc), annotation("_In_reads_(cchSrc)")] LPCSTR pszSrc, [in] long cchSrc, [out, annotation("_Out_opt_")] long* pcchActual, [out, annotation("_Out_opt_")] long* plActualLen);
        HRESULT SetStrBufA([in] long lDestPos, [in] long lDestLen, [in] UINT uCodePage, [in, annotation("_In_opt_")] IMLangStringBufA* pSrcBuf, [out, annotation("_Out_opt_")] long* pcchActual, [out, annotation("_Out_opt_")] long* plActualLen);
        HRESULT GetAStr([in] long lSrcPos, [in] long lSrcLen, [in] UINT uCodePageIn, [out, annotation("_Reserved_")] UINT* puCodePageOut, [out, size_is(cchDest), annotation("_Out_writes_opt_(cchDest)")] LPSTR pszDest, [in] long cchDest, [out, annotation("_Out_opt_")] long* pcchActual, [out, annotation("_Out_opt_")] long* plActualLen);
        HRESULT GetStrBufA([in] long lSrcPos, [in] long lSrcMaxLen, [out, annotation("_Out_opt_")] UINT* puDestCodePage, [out, annotation("_Outptr_")] IMLangStringBufA** ppDestBuf, [out, annotation("_Out_opt_")] long* plDestLen);
        HRESULT LockAStr([in] long lSrcPos, [in] long lSrcLen, [in] long lFlags, [in] UINT uCodePageIn, [in] long cchRequest, [out, annotation("_Out_opt_")] UINT* puCodePageOut, [out, size_is(,*pcchDest), annotation("_Outptr_opt_result_buffer_(*pcchDest)")] LPSTR* ppszDest, [out, annotation("_Out_opt_")] long* pcchDest, [out, annotation("_Out_opt_")] long* plDestLen);
        HRESULT UnlockAStr([in, size_is(cchSrc), annotation("_In_reads_(cchSrc)")] LPCSTR pszSrc, [in] long cchSrc, [out, annotation("_Out_opt_")] long* pcchActual, [out, annotation("_Out_opt_")] long* plActualLen);
        HRESULT SetLocale([in] long lDestPos, [in] long lDestLen, [in] LCID locale);
        HRESULT GetLocale([in] long lSrcPos, [in] long lSrcMaxLen, [out, annotation("_Out_opt_")] LCID* plocale, [out, annotation("_Out_opt_")] long* plLocalePos, [out, annotation("_Out_opt_")] long* plLocaleLen);
    };

    [
        uuid(F5BE2EE1-BFD7-11D0-B188-00AA0038C969),
        helpstring("IMLangLineBreakConsole Interface"),
        pointer_default(unique),
        local
    ]
    interface IMLangLineBreakConsole : IUnknown
    {
        [helpstring("method BreakLineML")] HRESULT BreakLineML([in, annotation("_In_")] IMLangString* pSrcMLStr, [in] long lSrcPos, [in] long lSrcLen, [in] long cMinColumns, [in] long cMaxColumns, [out, annotation("_Out_opt_")] long* plLineLen, [out, annotation("_Out_opt_")] long* plSkipLen);
        [helpstring("method BreakLineW")] HRESULT BreakLineW([in] LCID locale, [in, size_is(cchSrc), annotation("_In_reads_(cchSrc)")] const WCHAR* pszSrc, [in] long cchSrc, [in] long cMaxColumns, [out, annotation("_Out_opt_")] long* pcchLine, [out, annotation("_Out_opt_")] long* pcchSkip);
        [helpstring("method BreakLineA")] HRESULT BreakLineA([in] LCID locale, [in] UINT uCodePage, [in, size_is(cchSrc), annotation("_In_reads_(cchSrc)")] const CHAR* pszSrc, [in] long cchSrc, [in] long cMaxColumns, [out, annotation("_Out_opt_")] long* pcchLine, [out, annotation("_Out_opt_")] long* pcchSkip);
    };

cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */")
#pragma endregion

#pragma region Application Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)")

    [
        object,
        uuid(275c23e3-3747-11d0-9fea-00aa003f8646),
        pointer_default(unique),
        local
    ]
    interface IEnumCodePage : IUnknown
    {
        const USHORT MAX_MIMECP_NAME    = 64;
        const USHORT MAX_MIMECSET_NAME  = 50;
        const USHORT MAX_MIMEFACE_NAME  = 32;

        typedef enum tagMIMECONTF
        {
            MIMECONTF_MAILNEWS          = 0x00000001,
            MIMECONTF_BROWSER           = 0x00000002,
            MIMECONTF_MINIMAL           = 0x00000004,
            MIMECONTF_IMPORT            = 0x00000008,
            MIMECONTF_SAVABLE_MAILNEWS  = 0x00000100,
            MIMECONTF_SAVABLE_BROWSER   = 0x00000200,
            MIMECONTF_EXPORT            = 0x00000400,
            MIMECONTF_PRIVCONVERTER     = 0x00010000,
            MIMECONTF_VALID             = 0x00020000,
            MIMECONTF_VALID_NLS         = 0x00040000,
            MIMECONTF_MIME_IE4          = 0x10000000,
            MIMECONTF_MIME_LATEST       = 0x20000000,
            MIMECONTF_MIME_REGISTRY     = 0x40000000
        } MIMECONTF;

        typedef struct tagMIMECPINFO
        {
            DWORD   dwFlags;
            UINT    uiCodePage;
            UINT    uiFamilyCodePage;
            WCHAR   wszDescription[MAX_MIMECP_NAME];
            WCHAR   wszWebCharset[MAX_MIMECSET_NAME];
            WCHAR   wszHeaderCharset[MAX_MIMECSET_NAME];
            WCHAR   wszBodyCharset[MAX_MIMECSET_NAME];
            WCHAR   wszFixedWidthFont[MAX_MIMEFACE_NAME];
            WCHAR   wszProportionalFont[MAX_MIMEFACE_NAME];
            BYTE    bGDICharset;
        } MIMECPINFO, *PMIMECPINFO;

        typedef struct tagMIMECSETINFO
        {
            UINT    uiCodePage;
            UINT    uiInternetEncoding;
            WCHAR   wszCharset[MAX_MIMECSET_NAME];
        } MIMECSETINFO, *PMIMECSETINFO;

        typedef [unique] IEnumCodePage *LPENUMCODEPAGE;

        HRESULT Clone
        (
            [out, annotation("_Reserved_")] IEnumCodePage **ppEnum
        );

        HRESULT Next
        (
            [in]  ULONG                             celt,
            [out, annotation("_Out_")] PMIMECPINFO  rgelt,
            [out, annotation("_Out_opt_")] ULONG    *pceltFetched
        );

        HRESULT Reset();

        HRESULT Skip
        (
            [in]  ULONG         celt
        );
    };

    [
        object,
        uuid(3dc39d1d-c030-11d0-b81b-00c04fc9b31f),
        pointer_default(unique),
        local
    ]
    interface IEnumRfc1766 : IUnknown
    {
        const USHORT MAX_RFC1766_NAME   = 6;
        const USHORT MAX_LOCALE_NAME    = 32;

        typedef struct tagRFC1766INFO
        {
            LCID    lcid;
            WCHAR   wszRfc1766[MAX_RFC1766_NAME];
            WCHAR   wszLocaleName[MAX_LOCALE_NAME];
        } RFC1766INFO, *PRFC1766INFO;

        typedef [unique] IEnumRfc1766 *LPENUMRFC1766;

        HRESULT Clone
        (
            [out, annotation("_Reserved_")] IEnumRfc1766 **ppEnum
        );

        HRESULT Next
        (
            [in]  ULONG                             celt,
            [out, annotation("_Out_")] PRFC1766INFO rgelt,
            [out, annotation("_Out_opt_")] ULONG    *pceltFetched
        );

        HRESULT Reset();

        HRESULT Skip
        (
            [in]  ULONG         celt
        );
    };

    [
        object,
        uuid(AE5F1430-388B-11d2-8380-00C04F8F5DA1),
        pointer_default(unique),
        local
    ]
    interface IEnumScript : IUnknown
    {
        const USHORT MAX_SCRIPT_NAME    = 48;
        typedef BYTE    SCRIPT_ID;
        typedef __int64 SCRIPT_IDS;


        typedef enum tagSCRIPTCONTF
        {
            sidDefault,          // 0
            sidMerge,            // 1
            sidAsciiSym,         // 2
            sidAsciiLatin,       // 3
            sidLatin,            // 4
            sidGreek,            // 5
            sidCyrillic,         // 6
            sidArmenian,         // 7
            sidHebrew,           // 8
            sidArabic,           // 9
            sidDevanagari,       // 10
            sidBengali,          // 11
            sidGurmukhi,         // 12
            sidGujarati,         // 13
            sidOriya,            // 14
            sidTamil,            // 15
            sidTelugu,           // 16
            sidKannada,          // 17
            sidMalayalam,        // 18
            sidThai,             // 19
            sidLao,              // 20
            sidTibetan,          // 21
            sidGeorgian,         // 22
            sidHangul,           // 23
            sidKana,             // 24
            sidBopomofo,         // 25
            sidHan,              // 26
            sidEthiopic,         // 27
            sidCanSyllabic,      // 28
            sidCherokee,         // 29
            sidYi,               // 30
            sidBraille,          // 31
            sidRunic,            // 32
            sidOgham,            // 33
            sidSinhala,          // 34
            sidSyriac,           // 35
            sidBurmese,          // 36
            sidKhmer,            // 37
            sidThaana,           // 38
            sidMongolian,        // 39
            sidUserDefined,      // 40
            sidLim,              // 41
            sidFEFirst = sidHangul,
            sidFELast = sidHan
        } SCRIPTCONTF;

        typedef struct tagSCRIPTINFO
        {
            SCRIPT_ID   ScriptId;
            UINT        uiCodePage;                         
            WCHAR       wszDescription[MAX_SCRIPT_NAME];    
            WCHAR       wszFixedWidthFont[MAX_MIMEFACE_NAME];
            WCHAR       wszProportionalFont[MAX_MIMEFACE_NAME];
        } SCRIPTINFO, *PSCRIPTINFO;


        typedef [unique] IEnumScript *LPENUMScript;

        HRESULT Clone
        (
            [out, annotation("_Reserved_")] IEnumScript **ppEnum
        );

        HRESULT Next
        (
            [in]  ULONG                             celt,
            [out, annotation("_Out_")] PSCRIPTINFO  rgelt,
            [out, annotation("_Out_opt_")] ULONG    *pceltFetched
        );

        HRESULT Reset();

        HRESULT Skip
        (
            [in]  ULONG         celt
        );
    };



    [
        object,
        uuid(d66d6f98-cdaa-11d0-b822-00c04fc9b31f),
        pointer_default(unique),
        local
    ]
    interface IMLangConvertCharset : IUnknown
    {
        typedef enum tagMLCONVCHARF
        {
            MLCONVCHARF_AUTODETECT      = 1,
            MLCONVCHARF_ENTITIZE        = 2,
            MLCONVCHARF_NCR_ENTITIZE    = 2,
            MLCONVCHARF_NAME_ENTITIZE   = 4,
            MLCONVCHARF_USEDEFCHAR      = 8,
            MLCONVCHARF_NOBESTFITCHARS  = 16,
            MLCONVCHARF_DETECTJPN       = 32
        } MLCONVCHAR;

        typedef enum tagMLCPF
        {
            MLDETECTF_MAILNEWS          = 0x0001, // Outgoing encoding for mail client
            MLDETECTF_BROWSER           = 0x0002, // Outgoing encoding for browser client
            MLDETECTF_VALID             = 0x0004, // Detection result must be valid for conversion and text rendering
            MLDETECTF_VALID_NLS         = 0x0008, // Detection result must be valid for conversion
            MLDETECTF_PRESERVE_ORDER    = 0x0010, // Perserve perferred code page order
            MLDETECTF_PREFERRED_ONLY    = 0x0020, // Only return one of preferred code pages as detection result
            MLDETECTF_FILTER_SPECIALCHAR= 0x0040, // Filter out graphical symbols and punctuations
            MLDETECTF_EURO_UTF8         = 0x0080, // Force dection result to be UTF8 when EURO character encountered
        } MLCP;

        typedef [unique] IMLangConvertCharset *LPMLANGCONVERTCHARSET;

        HRESULT Initialize
        (
            [in]  UINT  uiSrcCodePage,
            [in]  UINT  uiDstCodePage,
            [in]  DWORD dwProperty
        );

        HRESULT GetSourceCodePage
        (
            [out, annotation("_Out_")] UINT  *puiSrcCodePage
        );

        HRESULT GetDestinationCodePage
        (
            [out, annotation("_Out_")] UINT  *puiDstCodePage
        );

        HRESULT GetProperty
        (
            [out, annotation("_Out_")] DWORD *pdwProperty
        );

        HRESULT DoConversion
        (
            [in, annotation("_In_reads_bytes_(*pcSrcSize)")]  BYTE    *pSrcStr,
            [in,out, annotation("_Inout_opt_")]  UINT            *pcSrcSize,
            [out, annotation("_Out_writes_bytes_(*pcDstSize)")]  BYTE  *pDstStr,
            [in,out, annotation("_Inout_opt_")]  UINT            *pcDstSize
        );

        HRESULT DoConversionToUnicode
        (
            [in, annotation("_In_reads_bytes_(*pcSrcSize)")]  CHAR    *pSrcStr,
            [in,out, annotation("_Inout_opt_")]  UINT            *pcSrcSize,
            [out, annotation("_Out_writes_(*pcDstSize)")]  WCHAR *pDstStr,
            [in,out, annotation("_Inout_opt_")]  UINT            *pcDstSize
        );

        HRESULT DoConversionFromUnicode
        (
            [in, annotation("_In_reads_(*pcSrcSize)")]  WCHAR  *pSrcStr,
            [in,out, annotation("_Inout_opt_")]  UINT           *pcSrcSize,
            [out, annotation("_Out_writes_bytes_(*pcDstSize)")]  CHAR *pDstStr,
            [in,out, annotation("_Inout_opt_")]  UINT           *pcDstSize
        );

    };

    [
        object,
        uuid(275c23e1-3747-11d0-9fea-00aa003f8646),
        pointer_default(unique),
        local
    ]
    interface IMultiLanguage : IUnknown
    {
        typedef [unique] IMultiLanguage *LPMULTILANGUAGE;

        HRESULT GetNumberOfCodePageInfo
        (
            [out, annotation("_Out_")] UINT  *pcCodePage
        );

        HRESULT GetCodePageInfo
        (
            [in]  UINT                              uiCodePage,
            [out, annotation("_Out_")] PMIMECPINFO  pCodePageInfo
        );

        HRESULT GetFamilyCodePage
        (
            [in]  UINT                              uiCodePage,
            [out, annotation("_Out_")] UINT         *puiFamilyCodePage
        );

        HRESULT EnumCodePages
        (
            [in]  DWORD                                     grfFlags,
            [out, annotation("_Outptr_")] IEnumCodePage  **ppEnumCodePage
        );

        HRESULT GetCharsetInfo
        (
            [in]  BSTR                                  Charset,
            [out, annotation("_Out_")] PMIMECSETINFO    pCharsetInfo
        );

        HRESULT IsConvertible
        (
            [in]  DWORD         dwSrcEncoding,
            [in]  DWORD         dwDstEncoding
        );

        HRESULT ConvertString
        (
            [in,out, annotation("_Inout_opt_")]  DWORD              *pdwMode,
            [in]  DWORD                                             dwSrcEncoding,
            [in]  DWORD                                             dwDstEncoding,
            [in, annotation("_In_reads_bytes_opt_(*pcSrcSize)")]  BYTE   *pSrcStr,
            [in,out, annotation("_Inout_opt_")]  UINT               *pcSrcSize,
            [out, annotation("_Out_writes_bytes_to_opt_(*pcDstSize, *pcDstSize)")]  BYTE *pDstStr,
            [in,out, annotation("_Inout_opt_")]  UINT               *pcDstSize
        );

        HRESULT ConvertStringToUnicode
        (
            [in,out, annotation("_Inout_opt_")]  DWORD                  *pdwMode,
            [in]  DWORD                                                 dwEncoding,
            [in, annotation("_In_reads_bytes_opt_(*pcSrcSize)")]  CHAR       *pSrcStr,
            [in,out, annotation("_Inout_opt_")]  UINT                   *pcSrcSize,
            [out, annotation("_Out_writes_to_opt_(*pcDstSize, *pcDstSize)")]  WCHAR    *pDstStr,
            [in,out, annotation("_Inout_opt_")]  UINT                   *pcDstSize
        );

        HRESULT ConvertStringFromUnicode
        (
            [in,out, annotation("_Inout_opt_")]  DWORD                  *pdwMode,
            [in]  DWORD                                                 dwEncoding,
            [in, annotation("_In_reads_opt_(*pcSrcSize)")]  WCHAR      *pSrcStr,
            [in,out, annotation("_Inout_opt_")]  UINT                   *pcSrcSize,
            [out, annotation("_Out_writes_bytes_to_opt_(*pcDstSize, *pcDstSize)")]  CHAR     *pDstStr,
            [in,out, annotation("_Inout_opt_")]  UINT                   *pcDstSize
        );

        HRESULT ConvertStringReset();

        HRESULT GetRfc1766FromLcid
        (
            [in]  LCID                              Locale,
            [out, annotation("_Outptr_")] BSTR   *pbstrRfc1766
        );

        HRESULT GetLcidFromRfc1766
        (
            [out, annotation("_Out_")] LCID *pLocale,
            [in, annotation("_In_")]  BSTR  bstrRfc1766
        );

        HRESULT EnumRfc1766
        (
            [out, annotation("_Outptr_")] IEnumRfc1766 **ppEnumRfc1766
        );

        HRESULT GetRfc1766Info
        (
            [in]  LCID                              Locale,
            [out, annotation("_Out_")] PRFC1766INFO pRfc1766Info
        );

        HRESULT CreateConvertCharset
        (
            [in]  UINT                                              uiSrcCodePage,
            [in]  UINT                                              uiDstCodePage,
            [in]  DWORD                                             dwProperty,
            [out, annotation("_Outptr_")] IMLangConvertCharset   **ppMLangConvertCharset
        );

    };

cpp_quote("// dwfIODControl definitions for ValidateCodePageEx()")
cpp_quote("#define CPIOD_PEEK          0x40000000L")
cpp_quote("#define CPIOD_FORCE_PROMPT  0x80000000L")

    [
        object,
        uuid(DCCFC164-2B38-11d2-B7EC-00C04F8F5D9A),
        pointer_default(unique),
        local
    ]
    interface IMultiLanguage2 : IUnknown
    {
        typedef [unique] IMultiLanguage2 *LPMULTILANGUAGE2;

        typedef enum tagMLDETECTCP
        {
            MLDETECTCP_NONE     = 0,
            MLDETECTCP_7BIT     = 1,
            MLDETECTCP_8BIT     = 2,
            MLDETECTCP_DBCS     = 4,
            MLDETECTCP_HTML     = 8,
            MLDETECTCP_NUMBER   = 16
        } MLDETECTCP ;

        typedef struct tagDetectEncodingInfo
        {
            UINT     nLangID;            // Win32 primary language ID
            UINT     nCodePage;          // Win32 code page (valid for SBCS and DBCS input only!)
            INT     nDocPercent;        // % of doc in this language, 0-100
            INT     nConfidence;        // Relative confidence measure, approx 0-100
        } DetectEncodingInfo, *pDetectEncodingInfo;


        typedef enum tagSCRIPTFONTCONTF
        {
            SCRIPTCONTF_FIXED_FONT          = 0x00000001,
            SCRIPTCONTF_PROPORTIONAL_FONT   = 0x00000002,
            SCRIPTCONTF_SCRIPT_USER     = 0x00010000,
            SCRIPTCONTF_SCRIPT_HIDE         = 0x00020000,
            SCRIPTCONTF_SCRIPT_SYSTEM       = 0x00040000
        } SCRIPTFONTCONTF;

        typedef struct tagSCRIPFONTINFO
        {
            SCRIPT_IDS  scripts;
            WCHAR       wszFont[MAX_MIMEFACE_NAME];
        } SCRIPTFONTINFO, *PSCRIPTFONTINFO;


        HRESULT GetNumberOfCodePageInfo
        (
            [out, annotation("_Out_")] UINT          *pcCodePage
        );

        HRESULT GetCodePageInfo
        (
            [in]  UINT                              uiCodePage,
            [in]  LANGID                            LangId,
            [out, annotation("_Out_")] PMIMECPINFO  pCodePageInfo
        );

        HRESULT GetFamilyCodePage
        (
            [in]  UINT                              uiCodePage,
            [out, annotation("_Out_")] UINT         *puiFamilyCodePage
        );

        HRESULT EnumCodePages
        (
            [in]  DWORD                                     grfFlags,
            [in]  LANGID                                    LangId,
            [out, annotation("_Outptr_")] IEnumCodePage  **ppEnumCodePage
        );

        HRESULT GetCharsetInfo
        (
            [in]  BSTR                                  Charset,
            [out, annotation("_Out_")] PMIMECSETINFO    pCharsetInfo
        );

        HRESULT IsConvertible
        (
            [in]  DWORD         dwSrcEncoding,
            [in]  DWORD         dwDstEncoding
        );

        HRESULT ConvertString
        (
            [in,out, annotation("_Inout_opt_")]  DWORD              *pdwMode,
            [in]  DWORD                                             dwSrcEncoding,
            [in]  DWORD                                             dwDstEncoding,
            [in, annotation("_In_reads_bytes_opt_(*pcSrcSize)")]  BYTE   *pSrcStr,
            [in,out, annotation("_Inout_opt_")]  UINT               *pcSrcSize,
            [out, annotation("_Out_writes_bytes_opt_(*pcDstSize)")]  BYTE *pDstStr,
            [in,out, annotation("_Inout_opt_")]  UINT               *pcDstSize
        );

        HRESULT ConvertStringToUnicode
        (
            [in,out, annotation("_Inout_opt_")]  DWORD                  *pdwMode,
            [in]  DWORD                                                 dwEncoding,
            [in, annotation("_In_reads_bytes_opt_(*pcSrcSize)")]  CHAR       *pSrcStr,
            [in,out, annotation("_Inout_opt_")]  UINT                   *pcSrcSize,
            [out, annotation("_Out_writes_opt_(*pcDstSize)")]  WCHAR    *pDstStr,
            [in,out, annotation("_Inout_opt_")]  UINT                   *pcDstSize
        );

        HRESULT ConvertStringFromUnicode
        (
            [in,out, annotation("_Inout_opt_")]  DWORD              *pdwMode,
            [in]  DWORD                                             dwEncoding,
            [in, annotation("_In_reads_opt_(*pcSrcSize)")]  WCHAR  *pSrcStr,
            [in,out, annotation("_Inout_opt_")]  UINT               *pcSrcSize,
            [out, annotation("_Out_writes_bytes_opt_(*pcDstSize)")]  CHAR *pDstStr,
            [in,out, annotation("_Inout_opt_")]  UINT               *pcDstSize
        );

        HRESULT ConvertStringReset();

        HRESULT GetRfc1766FromLcid
        (
            [in]  LCID                              Locale,
            [out, annotation("_Outptr_")] BSTR   *pbstrRfc1766
        );

        HRESULT GetLcidFromRfc1766
        (
            [out, annotation("_Out_")] LCID         *pLocale,
            [in, annotation("_In_")]  BSTR          bstrRfc1766
        );

        HRESULT EnumRfc1766
        (
            [in]  LANGID                                    LangId,
            [out, annotation("_Outptr_")] IEnumRfc1766   **ppEnumRfc1766
        );

        HRESULT GetRfc1766Info
        (
            [in]  LCID                              Locale,
            [in]  LANGID                            LangId,
            [out, annotation("_Out_")] PRFC1766INFO pRfc1766Info
        );

        HRESULT CreateConvertCharset
        (
            [in]  UINT                                              uiSrcCodePage,
            [in]  UINT                                              uiDstCodePage,
            [in]  DWORD                                             dwProperty,
            [out, annotation("_Outptr_")] IMLangConvertCharset   **ppMLangConvertCharset
        );

        HRESULT ConvertStringInIStream
        (
            [in,out, annotation("_Inout_opt_")]  DWORD  *pdwMode,
            [in]  DWORD                                 dwFlag,
            [in, annotation("_In_opt_")]  WCHAR         *lpFallBack,
            [in]  DWORD                                 dwSrcEncoding,
            [in]  DWORD                                 dwDstEncoding,
            [in, annotation("_In_")]  IStream           *pstmIn,
            [in, annotation("_In_")]  IStream           *pstmOut
        );

        HRESULT ConvertStringToUnicodeEx
        (
            [in,out, annotation("_Inout_opt_")]  DWORD              *pdwMode,
            [in]  DWORD                                             dwEncoding,
            [in, annotation("_In_reads_bytes_(*pcSrcSize)")]  CHAR       *pSrcStr,
            [in,out, annotation("_Inout_opt_")]  UINT               *pcSrcSize,
            [out, annotation("_Out_writes_(*pcDstSize)")]  WCHAR    *pDstStr,
            [in,out, annotation("_Inout_opt_")]  UINT               *pcDstSize,
            [in]  DWORD                                             dwFlag,
            [in, annotation("_In_opt_")]  WCHAR                     *lpFallBack
        );

        HRESULT ConvertStringFromUnicodeEx
        (
            [in,out, annotation("_Inout_opt_")]  DWORD          *pdwMode,
            [in]  DWORD                                         dwEncoding,
            [in, annotation("_In_reads_(*pcSrcSize)")]  WCHAR  *pSrcStr,
            [in,out, annotation("_Inout_opt_")]  UINT           *pcSrcSize,
            [out, annotation("_Out_writes_bytes_(*pcDstSize)")]  CHAR *pDstStr,
            [in,out, annotation("_Inout_opt_")]  UINT           *pcDstSize,
            [in]  DWORD                                         dwFlag,
            [in, annotation("_In_opt_")]  WCHAR                 *lpFallBack
        );

        HRESULT DetectCodepageInIStream
        (
            [in]  DWORD                                     dwFlag,
            [in]  DWORD                                     dwPrefWinCodePage,
            [in, annotation("_In_")]  IStream               *pstmIn,
            [out, annotation("_Out_")] DetectEncodingInfo   *lpEncoding,
            [in,out, annotation("_Inout_")] INT             *pnScores
        );

        HRESULT DetectInputCodepage
        (
            [in]  DWORD                                         dwFlag,
            [in]  DWORD                                         dwPrefWinCodePage,
            [in, annotation("_In_reads_bytes_(*pcSrcSize)")]  CHAR   *pSrcStr,
            [in,out, annotation("_Inout_")] INT                 *pcSrcSize,
            [out, annotation("_Out_")] DetectEncodingInfo       *lpEncoding,
            [in,out, annotation("_Inout_")] INT                 *pnScores
        );

        HRESULT ValidateCodePage
        (
            [in] UINT      uiCodePage,
            [in] HWND      hwnd
        );

        HRESULT GetCodePageDescription
        (
            [in] UINT                                                                   uiCodePage,
            [in] LCID                                                                   lcid, 
            [out,size_is(cchWideChar), annotation("_Out_writes_(cchWideChar)")]LPWSTR   lpWideCharStr,
            [in]  int                                                                   cchWideChar
        );

        HRESULT IsCodePageInstallable
        (
            [in] UINT      uiCodePage
        );

        HRESULT SetMimeDBSource
        (
            [in] MIMECONTF dwSource
        );

        HRESULT GetNumberOfScripts
        (
            [out, annotation("_Out_")] UINT          *pnScripts
        );


        HRESULT EnumScripts
        (
            [in]  DWORD                                     dwFlags,
            [in]  LANGID                                    LangId,
            [out, annotation("_Outptr_")] IEnumScript   **ppEnumScript
        );

        HRESULT ValidateCodePageEx
        (
            [in] UINT      uiCodePage,
            [in] HWND      hwnd,
            [in] DWORD     dwfIODControl
        );

    };

cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */")
#pragma endregion

#pragma region Desktop Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)")


    [
        uuid(359F3443-BD4A-11D0-B188-00AA0038C969),
        helpstring("IMLangCodePages Interface"),
        pointer_default(unique),
        local
    ]
    interface IMLangCodePages : IUnknown
    {
        typedef [unique] IMLangCodePages* PMLANGCODEPAGES;

        [helpstring("method GetCharCodePages")] HRESULT GetCharCodePages([in] WCHAR chSrc, [out, annotation("_Out_")] DWORD* pdwCodePages);
        [helpstring("method GetStrCodePages")] HRESULT GetStrCodePages([in, size_is(cchSrc), annotation("_In_reads_(cchSrc)")] const WCHAR* pszSrc, [in] long cchSrc, [in] DWORD dwPriorityCodePages, [out, annotation("_Out_opt_")] DWORD* pdwCodePages, [out, annotation("_Out_opt_")] long* pcchCodePages);
        [helpstring("method CodePageToCodePages")] HRESULT CodePageToCodePages([in] UINT uCodePage, [out, annotation("_Out_")] DWORD* pdwCodePages);
        [helpstring("method CodePagesToCodePage")] HRESULT CodePagesToCodePage([in] DWORD dwCodePages, [in] UINT uDefaultCodePage, [out, annotation("_Out_")] UINT* puCodePage);

    };

    [
        uuid(359F3441-BD4A-11D0-B188-00AA0038C969),
        helpstring("IMLangFontLink Interface"),
        pointer_default(unique),
        local
    ]
    interface IMLangFontLink : IMLangCodePages
    {
        typedef [unique] IMLangFontLink* PMLANGFONTLINK;

        [helpstring("method GetFontCodePages")] HRESULT GetFontCodePages([in] HDC hDC, [in] HFONT hFont, [out, annotation("_Out_opt_")] DWORD* pdwCodePages);
        [helpstring("method MapFont")] HRESULT MapFont([in] HDC hDC, [in] DWORD dwCodePages, [in] HFONT hSrcFont, [out, annotation("_Out_opt_")] HFONT* phDestFont);
        [helpstring("method ReleaseFont")] HRESULT ReleaseFont([in] HFONT hFont);
        [helpstring("method ResetFontMapping")] HRESULT ResetFontMapping();

    };

    [
        uuid(DCCFC162-2B38-11d2-B7EC-00C04F8F5D9A),
        helpstring("IMLangFontLink2 Interface"),
        pointer_default(unique),
        local
    ]
    interface IMLangFontLink2 : IMLangCodePages
    {
        typedef struct tagUNICODERANGE
        {
            WCHAR wcFrom;
            WCHAR wcTo;
        } UNICODERANGE;

        typedef [unique] IMLangFontLink2* PMLANGFONTLINK2;

        [helpstring("method GetFontCodePages")] HRESULT GetFontCodePages([in] HDC hDC, [in] HFONT hFont, [out, annotation("_Out_opt_")] DWORD* pdwCodePages);
        [helpstring("method ReleaseFont")] HRESULT ReleaseFont([in] HFONT hFont);
        [helpstring("method ResetFontMapping")] HRESULT ResetFontMapping();
        [helpstring("method MapFont")] HRESULT MapFont([in] HDC hDC, [in] DWORD dwCodePages,  [in] WCHAR chSrc, [out, annotation("_Out_opt_")] HFONT* pFont );
        [helpstring("method GetFontUnicodeRanges")] HRESULT GetFontUnicodeRanges([in] HDC hDC, [in,out, annotation("_In_")] UINT *puiRanges, [out, annotation("_Out_opt_")] UNICODERANGE* pUranges);
        [helpstring("method GetScriptFontInfo")]HRESULT GetScriptFontInfo([in] SCRIPT_ID sid, [in] DWORD dwFlags, [in, out, annotation("_Inout_")] UINT *puiFonts, [out, annotation("_Out_opt_")] SCRIPTFONTINFO* pScriptFont);
        [helpstring("method CodePageToScriptID")] HRESULT CodePageToScriptID([in] UINT uiCodePage, [out, annotation("_Out_")] SCRIPT_ID *pSid);
    };

    [
        object,
        uuid(4e5868ab-b157-4623-9acc-6a1d9caebe04),
        pointer_default(unique),
        local
    ]
    interface IMultiLanguage3 : IMultiLanguage2
    {
       typedef [unique] IMultiLanguage3 *LPMULTILANGUAGE3;
       HRESULT DetectOutboundCodePage(
            [in] DWORD           dwFlags,                
            [in, size_is(cchWideChar), annotation("_In_reads_(cchWideChar)")] LPCWSTR lpWideCharStr,          
            [in] UINT            cchWideChar,            
            [in, size_is(nPreferredCodePages), annotation("_In_reads_opt_(nPreferredCodePages)")] const UINT* puiPreferredCodePages,  
            [in] UINT            nPreferredCodePages,    
            [out, size_is(*pnDetectedCodePages), annotation("_Out_writes_to_(*pnDetectedCodePages, *pnDetectedCodePages)")] UINT* puiDetectedCodePages,   
            [in, out, annotation("_Inout_")] UINT*      pnDetectedCodePages,    
            [in, unique, string, annotation("_In_opt_")] LPCWSTR lpSpecialChar
            );

       HRESULT DetectOutboundCodePageInIStream(
            [in] DWORD          dwFlags,                
            [in, annotation("_In_")] IStream*       pStrIn,                 
            [in, size_is(nPreferredCodePages), annotation("_In_reads_opt_(nPreferredCodePages)")] const UINT* puiPreferredCodePages,
            [in] UINT           nPreferredCodePages,    
            [out, size_is(*pnDetectedCodePages), annotation("_Out_writes_to_(*pnDetectedCodePages, *pnDetectedCodePages)")] UINT* puiDetectedCodePages,   
            [in, out, annotation("_Inout_")] UINT*     pnDetectedCodePages,                                                        
            [in, unique, string, annotation("_In_opt_")] LPCWSTR lpSpecialChar
            );
    };

cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */")
#pragma endregion

[
    uuid(275c23e0-3747-11d0-9fea-00aa003f8646),
    helpstring("MultiLanguage Object Model"),
    lcid(0x0000),
    version(0.2)
]
library MultiLanguage
{
    importlib("stdole2.tlb");
    
    typedef WORD LANGID;

    typedef enum tagMLSTR_FLAGS
    {
        MLSTR_READ                  = 1,
        MLSTR_WRITE                 = 2
    } MLSTR_FLAGS;
    
    [
        uuid(C04D65CF-B70D-11D0-B188-00AA0038C969),
        helpstring("MLangString Class")
    ]
    coclass CMLangString
    {
        [default] interface IMLangString;
        interface IMLangStringWStr;
        interface IMLangStringAStr;
    };

    [
      uuid(d66d6f99-cdaa-11d0-b822-00c04fc9b31f),
    ]
    coclass CMLangConvertCharset
    {
        [default] interface IMLangConvertCharset;
    };

    [
        uuid(275c23e2-3747-11d0-9fea-00aa003f8646),
    ]
    coclass CMultiLanguage
    {
        [default] interface IMultiLanguage;
        interface IMLangCodePages;
        interface IMLangFontLink;
        interface IMLangLineBreakConsole;
        interface IMultiLanguage2;
        interface IMLangFontLink2;
        interface IMultiLanguage3;
    };
}

#pragma region Desktop Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)")



cpp_quote("#ifndef _MLANG_H_API_DEF_                                                     ")
cpp_quote("#define _MLANG_H_API_DEF_                                                     ")
cpp_quote("                                                                              ")
cpp_quote("// APIs prototypes                                                            ")
cpp_quote("STDAPI LcidToRfc1766A(_In_ LCID Locale, _Out_writes_bytes_(iMaxLength) LPSTR pszRfc1766, _In_ int iMaxLength);         ")
cpp_quote("STDAPI LcidToRfc1766W(_In_ LCID Locale, _Out_writes_(nChar) LPWSTR pwszRfc1766, _In_ int nChar);             ")
cpp_quote("#ifdef UNICODE                                                                ")
cpp_quote("#define LcidToRfc1766        LcidToRfc1766W                                   ")
cpp_quote("#else                                                                         ")
cpp_quote("#define LcidToRfc1766        LcidToRfc1766A                                   ")
cpp_quote("#endif                                                                        ")
cpp_quote("STDAPI Rfc1766ToLcidA(_Out_ LCID *pLocale, _In_ LPCSTR pszRfc1766);           ")
cpp_quote("STDAPI Rfc1766ToLcidW(_Out_ LCID *pLocale, _In_ LPCWSTR pszRfc1766);          ")
cpp_quote("#ifdef UNICODE                                                                ")
cpp_quote("#define Rfc1766ToLcid        Rfc1766ToLcidW                                   ")
cpp_quote("#else                                                                         ")
cpp_quote("#define Rfc1766ToLcid        Rfc1766ToLcidA                                   ")
cpp_quote("#endif                                                                        ")
cpp_quote("                                                                              ")
cpp_quote("STDAPI IsConvertINetStringAvailable(DWORD dwSrcEncoding, DWORD dwDstEncoding);")
cpp_quote("STDAPI ConvertINetString(_Inout_opt_ LPDWORD lpdwMode, _In_ DWORD dwSrcEncoding, _In_ DWORD dwDstEncoding, _In_reads_bytes_opt_(*lpnSrcSize) LPCSTR lpSrcStr, _Inout_opt_ LPINT lpnSrcSize, _Out_writes_bytes_to_opt_(*lpnDstSize, *lpnDstSize) LPSTR lpDstStr, _Inout_opt_ LPINT lpnDstSize); ")
cpp_quote("STDAPI ConvertINetMultiByteToUnicode(_Inout_opt_ LPDWORD lpdwMode, _In_ DWORD dwEncoding, _In_reads_bytes_opt_(*lpnMultiCharCount) LPCSTR lpSrcStr, _Inout_opt_ LPINT lpnMultiCharCount, _Out_writes_to_opt_(*lpnWideCharCount, *lpnWideCharCount) LPWSTR lpDstStr, _Inout_opt_ LPINT lpnWideCharCount); ")
cpp_quote("STDAPI ConvertINetUnicodeToMultiByte(_Inout_opt_ LPDWORD lpdwMode, _In_ DWORD dwEncoding, _In_reads_opt_(*lpnWideCharCount) LPCWSTR lpSrcStr, _Inout_opt_ LPINT lpnWideCharCount, _Out_writes_bytes_to_opt_(*lpnMultiCharCount, *lpnMultiCharCount) LPSTR lpDstStr, _Inout_opt_ LPINT lpnMultiCharCount); ")
cpp_quote("                                                                              ")
cpp_quote("#endif // _MLANG_H_API_DEF_                                                   ")

cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */")
#pragma endregion

