⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mlang.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
    {
        *pbstrRfc1766 = SysAllocString( buf );
        return S_OK;
    }
    return E_FAIL;
}

static HRESULT WINAPI fnIMultiLanguage_GetLcidFromRfc1766(
    IMultiLanguage* iface,
    LCID* pLocale,
    BSTR bstrRfc1766)
{
    HRESULT hr;
    IEnumRfc1766 *rfc1766;

    TRACE("%p %p %s\n", iface, pLocale, debugstr_w(bstrRfc1766));

    if (!pLocale || !bstrRfc1766)
        return E_INVALIDARG;

    hr = IMultiLanguage_EnumRfc1766(iface, &rfc1766);
    if (FAILED(hr))
        return hr;

    hr = lcid_from_rfc1766(rfc1766, pLocale, bstrRfc1766);

    IEnumRfc1766_Release(rfc1766);
    return hr;
}

/******************************************************************************/

typedef struct tagEnumRfc1766_impl
{
    const IEnumRfc1766Vtbl *vtbl_IEnumRfc1766;
    LONG ref;
    RFC1766INFO *info;
    DWORD total, pos;
} EnumRfc1766_impl;

static HRESULT WINAPI fnIEnumRfc1766_QueryInterface(
        IEnumRfc1766 *iface,
        REFIID riid,
        void** ppvObject)
{
    ICOM_THIS_MULTI(EnumRfc1766_impl, vtbl_IEnumRfc1766, iface);

    TRACE("%p -> %s\n", This, debugstr_guid(riid) );

    if (IsEqualGUID(riid, &IID_IUnknown)
        || IsEqualGUID(riid, &IID_IEnumRfc1766))
    {
        IEnumRfc1766_AddRef(iface);
        TRACE("Returning IID_IEnumRfc1766 %p ref = %d\n", This, This->ref);
        *ppvObject = &(This->vtbl_IEnumRfc1766);
        return S_OK;
    }

    WARN("(%p) -> (%s,%p), not found\n",This,debugstr_guid(riid),ppvObject);
    return E_NOINTERFACE;
}

static ULONG WINAPI fnIEnumRfc1766_AddRef(
        IEnumRfc1766 *iface)
{
    ICOM_THIS_MULTI(EnumRfc1766_impl, vtbl_IEnumRfc1766, iface);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI fnIEnumRfc1766_Release(
        IEnumRfc1766 *iface)
{
    ICOM_THIS_MULTI(EnumRfc1766_impl, vtbl_IEnumRfc1766, iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("%p ref = %d\n", This, ref);
    if (ref == 0)
    {
        TRACE("Destroying %p\n", This);
        HeapFree(GetProcessHeap(), 0, This->info);
        HeapFree(GetProcessHeap(), 0, This);
    }
    return ref;
}

static HRESULT WINAPI fnIEnumRfc1766_Clone(
        IEnumRfc1766 *iface,
        IEnumRfc1766 **ppEnum)
{
    ICOM_THIS_MULTI(EnumRfc1766_impl, vtbl_IEnumRfc1766, iface);
    FIXME("%p %p\n", This, ppEnum);
    return E_NOTIMPL;
}

static  HRESULT WINAPI fnIEnumRfc1766_Next(
        IEnumRfc1766 *iface,
        ULONG celt,
        PRFC1766INFO rgelt,
        ULONG *pceltFetched)
{
    ULONG i;

    ICOM_THIS_MULTI(EnumRfc1766_impl, vtbl_IEnumRfc1766, iface);
    TRACE("%p %u %p %p\n", This, celt, rgelt, pceltFetched);

    if (!pceltFetched) return S_FALSE;
    *pceltFetched = 0;

    if (!rgelt) return S_FALSE;

    if (This->pos + celt > This->total)
        celt = This->total - This->pos;

    if (!celt) return S_FALSE;

    memcpy(rgelt, This->info + This->pos, celt * sizeof(RFC1766INFO));
    *pceltFetched = celt;
    This->pos += celt;

    for (i = 0; i < celt; i++)
    {
        TRACE("#%u: %08x %s %s\n",
              i, rgelt[i].lcid,
              wine_dbgstr_w(rgelt[i].wszRfc1766),
              wine_dbgstr_w(rgelt[i].wszLocaleName));
    }
    return S_OK;
}

static HRESULT WINAPI fnIEnumRfc1766_Reset(
        IEnumRfc1766 *iface)
{
    ICOM_THIS_MULTI(EnumRfc1766_impl, vtbl_IEnumRfc1766, iface);
    TRACE("%p\n", This);

    This->pos = 0;
    return S_OK;
}

static  HRESULT WINAPI fnIEnumRfc1766_Skip(
        IEnumRfc1766 *iface,
        ULONG celt)
{
    ICOM_THIS_MULTI(EnumRfc1766_impl, vtbl_IEnumRfc1766, iface);
    TRACE("%p %u\n", This, celt);

    if (celt >= This->total) return S_FALSE;

    This->pos += celt;
    return S_OK;
}

static const IEnumRfc1766Vtbl IEnumRfc1766_vtbl =
{
    fnIEnumRfc1766_QueryInterface,
    fnIEnumRfc1766_AddRef,
    fnIEnumRfc1766_Release,
    fnIEnumRfc1766_Clone,
    fnIEnumRfc1766_Next,
    fnIEnumRfc1766_Reset,
    fnIEnumRfc1766_Skip
};

struct enum_locales_data
{
    RFC1766INFO *info;
    DWORD total, allocated;
};

static BOOL CALLBACK enum_locales_proc(LPWSTR locale)
{
    WCHAR *end;
    struct enum_locales_data *data = TlsGetValue(MLANG_tls_index);
    RFC1766INFO *info;

    TRACE("%s\n", debugstr_w(locale));

    if (data->total >= data->allocated)
    {
        data->allocated += 32;
        data->info = HeapReAlloc(GetProcessHeap(), 0, data->info, data->allocated * sizeof(RFC1766INFO));
        if (!data->info) return FALSE;
    }

    info = &data->info[data->total];

    info->lcid = strtolW(locale, &end, 16);
    if (*end) /* invalid number */
        return FALSE;

    info->wszRfc1766[0] = 0;
    lcid_to_rfc1766W( info->lcid, info->wszRfc1766, MAX_RFC1766_NAME );

    info->wszLocaleName[0] = 0;
    GetLocaleInfoW(info->lcid, LOCALE_SLANGUAGE, info->wszLocaleName, MAX_LOCALE_NAME);
    TRACE("ISO639: %s SLANGUAGE: %s\n", wine_dbgstr_w(info->wszRfc1766), wine_dbgstr_w(info->wszLocaleName));
    
    data->total++;

    return TRUE;
}

static HRESULT EnumRfc1766_create(MLang_impl* mlang, LANGID LangId,
                                  IEnumRfc1766 **ppEnum)
{
    EnumRfc1766_impl *rfc;
    struct enum_locales_data data;

    TRACE("%p, %04x, %p\n", mlang, LangId, ppEnum);

    rfc = HeapAlloc( GetProcessHeap(), 0, sizeof(EnumRfc1766_impl) );
    rfc->vtbl_IEnumRfc1766 = &IEnumRfc1766_vtbl;
    rfc->ref = 1;
    rfc->pos = 0;
    rfc->total = 0;

    data.total = 0;
    data.allocated = 32;
    data.info = HeapAlloc(GetProcessHeap(), 0, data.allocated * sizeof(RFC1766INFO));
    if (!data.info) return S_FALSE;

    TlsSetValue(MLANG_tls_index, &data);
    EnumSystemLocalesW(enum_locales_proc, 0/*LOCALE_SUPPORTED*/);
    TlsSetValue(MLANG_tls_index, NULL);

    TRACE("enumerated %d rfc1766 structures\n", data.total);

    if (!data.total) return FALSE;

    rfc->info = data.info;
    rfc->total = data.total;

    *ppEnum = (IEnumRfc1766 *)rfc;
    return S_OK;
}

static HRESULT WINAPI fnIMultiLanguage_EnumRfc1766(
    IMultiLanguage *iface,
    IEnumRfc1766 **ppEnumRfc1766)
{
    ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage, iface);
    TRACE("%p %p\n", This, ppEnumRfc1766);

    return EnumRfc1766_create(This, 0, ppEnumRfc1766);
}

/******************************************************************************/

static HRESULT WINAPI fnIMultiLanguage_GetRfc1766Info(
    IMultiLanguage* iface,
    LCID Locale,
    PRFC1766INFO pRfc1766Info)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI fnIMultiLanguage_CreateConvertCharset(
    IMultiLanguage* iface,
    UINT uiSrcCodePage,
    UINT uiDstCodePage,
    DWORD dwProperty,
    IMLangConvertCharset** ppMLangConvertCharset)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static const IMultiLanguageVtbl IMultiLanguage_vtbl =
{
    fnIMultiLanguage_QueryInterface,
    fnIMultiLanguage_AddRef,
    fnIMultiLanguage_Release,
    fnIMultiLanguage_GetNumberOfCodePageInfo,
    fnIMultiLanguage_GetCodePageInfo,
    fnIMultiLanguage_GetFamilyCodePage,
    fnIMultiLanguage_EnumCodePages,
    fnIMultiLanguage_GetCharsetInfo,
    fnIMultiLanguage_IsConvertible,
    fnIMultiLanguage_ConvertString,
    fnIMultiLanguage_ConvertStringToUnicode,
    fnIMultiLanguage_ConvertStringFromUnicode,
    fnIMultiLanguage_ConvertStringReset,
    fnIMultiLanguage_GetRfc1766FromLcid,
    fnIMultiLanguage_GetLcidFromRfc1766,
    fnIMultiLanguage_EnumRfc1766,
    fnIMultiLanguage_GetRfc1766Info,
    fnIMultiLanguage_CreateConvertCharset,
};


/******************************************************************************/

static HRESULT WINAPI fnIMultiLanguage2_QueryInterface(
    IMultiLanguage3* iface,
    REFIID riid,
    void** ppvObject)
{
    ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage3, iface);
    return MLang_QueryInterface( This, riid, ppvObject );
}

static ULONG WINAPI fnIMultiLanguage2_AddRef( IMultiLanguage3* iface )
{
    ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage3, iface);
    return MLang_AddRef( This );
}

static ULONG WINAPI fnIMultiLanguage2_Release( IMultiLanguage3* iface )
{
    ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage3, iface);
    return MLang_Release( This );
}

static HRESULT WINAPI fnIMultiLanguage2_GetNumberOfCodePageInfo(
    IMultiLanguage3* iface,
    UINT* pcCodePage)
{
    ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage3, iface);
    TRACE("%p, %p\n", This, pcCodePage);

    if (!pcCodePage) return S_FALSE;

    *pcCodePage = This->total_cp;
    return S_OK;
}

static void fill_cp_info(const struct mlang_data *ml_data, UINT index, MIMECPINFO *mime_cp_info)
{
    CHARSETINFO csi;

    if (TranslateCharsetInfo((DWORD *)ml_data->family_codepage, &csi, TCI_SRCCODEPAGE))
        mime_cp_info->bGDICharset = csi.ciCharset;
    else
        mime_cp_info->bGDICharset = DEFAULT_CHARSET;

    mime_cp_info->dwFlags = ml_data->mime_cp_info[index].flags;
    mime_cp_info->uiCodePage = ml_data->mime_cp_info[index].cp;
    mime_cp_info->uiFamilyCodePage = ml_data->family_codepage;
    MultiByteToWideChar(CP_ACP, 0, ml_data->mime_cp_info[index].description, -1,
                        mime_cp_info->wszDescription, sizeof(mime_cp_info->wszDescription)/sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, ml_data->mime_cp_info[index].web_charset, -1,
                        mime_cp_info->wszWebCharset, sizeof(mime_cp_info->wszWebCharset)/sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, ml_data->mime_cp_info[index].header_charset, -1,
                        mime_cp_info->wszHeaderCharset, sizeof(mime_cp_info->wszHeaderCharset)/sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, ml_data->mime_cp_info[index].body_charset, -1,
                        mime_cp_info->wszBodyCharset, sizeof(mime_cp_info->wszBodyCharset)/sizeof(WCHAR));

    MultiByteToWideChar(CP_ACP, 0, ml_data->fixed_font, -1,
        mime_cp_info->wszFixedWidthFont, sizeof(mime_cp_info->wszFixedWidthFont)/sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, ml_data->proportional_font, -1,
        mime_cp_info->wszProportionalFont, sizeof(mime_cp_info->wszProportionalFont)/sizeof(WCHAR));

    TRACE("%08x %u %u %s %s %s %s %s %s %d\n",
          mime_cp_info->dwFlags, mime_cp_info->uiCodePage,
          mime_cp_info->uiFamilyCodePage,
          wine_dbgstr_w(mime_cp_info->wszDescription),
          wine_dbgstr_w(mime_cp_info->wszWebCharset),
          wine_dbgstr_w(mime_cp_info->wszHeaderCharset),
          wine_dbgstr_w(mime_cp_info->wszBodyCharset),
          wine_dbgstr_w(mime_cp_info->wszFixedWidthFont),
          wine_dbgstr_w(mime_cp_info->wszProportionalFont),
          mime_cp_info->bGDICharset);
}

static HRESULT WINAPI fnIMultiLanguage2_GetCodePageInfo(
    IMultiLanguage3* iface,
    UINT uiCodePage,
    LANGID LangId,
    PMIMECPINFO pCodePageInfo)
{
    UINT i, n;

    ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage3, iface);
    TRACE("%p, %u, %04x, %p\n", This, uiCodePage, LangId, pCodePageInfo);

    for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++)
    {
        for (n = 0; n < mlang_data[i].number_of_cp; n++)
        {
            if (mlang_data[i].mime_cp_info[n].cp == uiCodePage)
            {
                fill_cp_info(&mlang_data[i], n, pCodePageInfo);
                return S_OK;
            }
        }
    }

    return S_FALSE;
}

static HRESULT WINAPI fnIMultiLanguage2_GetFamilyCodePage(
    IMultiLanguage3* iface,
    UINT uiCodePage,
    UINT* puiFamilyCodePage)
{
    return GetFamilyCodePage(uiCodePage, puiFamilyCodePage);
}

static HRESULT WINAPI fnIMultiLanguage2_EnumCodePages(
    IMultiLanguage3* iface,
    DWORD grfFlags,
    LANGID LangId,
    IEnumCodePage** ppEnumCodePage)
{
    ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage3, iface);
    TRACE("%p %08x %04x %p\n", This, grfFlags, LangId, ppEnumCodePage);

    return EnumCodePage_create( This, grfFlags, LangId, ppEnumCodePage );
}

static HRESULT WINAPI fnIMultiLanguage2_GetCharsetInfo(
    IMultiLanguage3* 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -