📄 mlang.c
字号:
{
*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 + -