- add stubbed support for IEnumScript interface

- ConvertINetMultiByteToUnicode/ConvertINetUnicodeToMultiByte should
  return required target length if the target buffer is NULL
- add the tests for all the above
- fix IMultiLanguage2 vtable (it was missing ConvertStringFromUnicodeEx)
This commit is contained in:
Dmitry Timoshkov 2004-08-11 18:53:02 +00:00 committed by Alexandre Julliard
parent 1dac53bc76
commit 8c2ff3ca6d
5 changed files with 582 additions and 23 deletions

View File

@ -412,6 +412,7 @@ HRESULT WINAPI ConvertINetMultiByteToUnicode(
*pcSrcSize = lstrlenW((LPCWSTR)pSrcStr);
*pcDstSize = min(*pcSrcSize, *pcDstSize);
*pcSrcSize *= sizeof(WCHAR);
if (pDstStr)
memmove(pDstStr, pSrcStr, *pcDstSize * sizeof(WCHAR));
break;
@ -419,7 +420,10 @@ HRESULT WINAPI ConvertINetMultiByteToUnicode(
if (*pcSrcSize == -1)
*pcSrcSize = lstrlenA(pSrcStr);
if (pDstStr)
*pcDstSize = MultiByteToWideChar(dwEncoding, 0, pSrcStr, *pcSrcSize, pDstStr, *pcDstSize);
else
*pcDstSize = MultiByteToWideChar(dwEncoding, 0, pSrcStr, *pcSrcSize, NULL, 0);
break;
}
@ -461,6 +465,7 @@ HRESULT WINAPI ConvertINetUnicodeToMultiByte(
if (*pcSrcSize == -1)
*pcSrcSize = lstrlenW(pSrcStr);
*pcDstSize = min(*pcSrcSize * sizeof(WCHAR), *pcDstSize);
if (pDstStr)
memmove(pDstStr, pSrcStr, *pcDstSize);
break;
@ -468,7 +473,10 @@ HRESULT WINAPI ConvertINetUnicodeToMultiByte(
if (*pcSrcSize == -1)
*pcSrcSize = lstrlenW(pSrcStr);
if (pDstStr)
*pcDstSize = WideCharToMultiByte(dwEncoding, 0, pSrcStr, *pcSrcSize, pDstStr, *pcDstSize, NULL, NULL);
else
*pcDstSize = WideCharToMultiByte(dwEncoding, 0, pSrcStr, *pcSrcSize, NULL, 0, NULL, NULL);
break;
}
@ -687,7 +695,7 @@ typedef struct tagMLang_impl
ICOM_VTABLE(IMultiLanguage) *vtbl_IMultiLanguage;
ICOM_VTABLE(IMultiLanguage2) *vtbl_IMultiLanguage2;
DWORD ref;
DWORD total;
DWORD total_cp, total_scripts;
} MLang_impl;
static ULONG WINAPI MLang_AddRef( MLang_impl* This)
@ -887,6 +895,7 @@ static HRESULT EnumCodePage_create( MLang_impl* mlang, DWORD grfFlags,
ecp = HeapAlloc( GetProcessHeap(), 0, sizeof (EnumCodePage_impl) );
ecp->vtbl_IEnumCodePage = &IEnumCodePage_vtbl;
ecp->ref = 1;
ecp->pos = 0;
ecp->total = 0;
for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++)
{
@ -919,6 +928,161 @@ static HRESULT EnumCodePage_create( MLang_impl* mlang, DWORD grfFlags,
/******************************************************************************/
typedef struct tagEnumScript_impl
{
ICOM_VTABLE(IEnumScript) *vtbl_IEnumScript;
DWORD ref;
SCRIPTINFO *script_info;
DWORD total, pos;
} EnumScript_impl;
static HRESULT WINAPI fnIEnumScript_QueryInterface(
IEnumScript* iface,
REFIID riid,
void** ppvObject)
{
ICOM_THIS_MULTI(EnumScript_impl, vtbl_IEnumScript, iface);
TRACE("%p -> %s\n", This, debugstr_guid(riid) );
if (IsEqualGUID(riid, &IID_IUnknown)
|| IsEqualGUID(riid, &IID_IEnumScript))
{
IEnumScript_AddRef(iface);
TRACE("Returning IID_IEnumScript %p ref = %ld\n", This, This->ref);
*ppvObject = &(This->vtbl_IEnumScript);
return S_OK;
}
WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
return E_NOINTERFACE;
}
static ULONG WINAPI fnIEnumScript_AddRef(
IEnumScript* iface)
{
ICOM_THIS_MULTI(EnumScript_impl, vtbl_IEnumScript, iface);
return ++(This->ref);
}
static ULONG WINAPI fnIEnumScript_Release(
IEnumScript* iface)
{
ICOM_THIS_MULTI(EnumScript_impl, vtbl_IEnumScript, iface);
ULONG ref = --This->ref;
TRACE("%p ref = %ld\n", This, ref);
if (ref == 0)
{
TRACE("Destroying %p\n", This);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
static HRESULT WINAPI fnIEnumScript_Clone(
IEnumScript* iface,
IEnumScript** ppEnum)
{
ICOM_THIS_MULTI(EnumScript_impl, vtbl_IEnumScript, iface);
FIXME("%p %p: stub!\n", This, ppEnum);
return E_NOTIMPL;
}
static HRESULT WINAPI fnIEnumScript_Next(
IEnumScript* iface,
ULONG celt,
PSCRIPTINFO rgelt,
ULONG* pceltFetched)
{
ICOM_THIS_MULTI(EnumScript_impl, vtbl_IEnumScript, iface);
TRACE("%p %lu %p %p\n", This, celt, rgelt, pceltFetched);
if (!pceltFetched || !rgelt) return E_FAIL;
*pceltFetched = 0;
if (This->pos + celt > This->total)
celt = This->total - This->pos;
if (!celt) return S_FALSE;
memcpy(rgelt, This->script_info + This->pos, celt * sizeof(SCRIPTINFO));
*pceltFetched = celt;
This->pos += celt;
return S_OK;
}
static HRESULT WINAPI fnIEnumScript_Reset(
IEnumScript* iface)
{
ICOM_THIS_MULTI(EnumScript_impl, vtbl_IEnumScript, iface);
TRACE("%p\n", This);
This->pos = 0;
return S_OK;
}
static HRESULT WINAPI fnIEnumScript_Skip(
IEnumScript* iface,
ULONG celt)
{
ICOM_THIS_MULTI(EnumScript_impl, vtbl_IEnumScript, iface);
TRACE("%p %lu\n", This, celt);
if (celt >= This->total) return S_FALSE;
This->pos = celt; /* FIXME: should be += ?? */
return S_OK;
}
static ICOM_VTABLE(IEnumScript) IEnumScript_vtbl =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
fnIEnumScript_QueryInterface,
fnIEnumScript_AddRef,
fnIEnumScript_Release,
fnIEnumScript_Clone,
fnIEnumScript_Next,
fnIEnumScript_Reset,
fnIEnumScript_Skip
};
static HRESULT EnumScript_create( MLang_impl* mlang, DWORD dwFlags,
LANGID LangId, IEnumScript** ppEnumScript )
{
static const WCHAR defaultW[] = { 'D','e','f','a','u','l','t',0 };
EnumScript_impl *es;
FIXME("%p, %08lx, %04x, %p: stub!\n", mlang, dwFlags, LangId, ppEnumScript);
if (!dwFlags) /* enumerate all available scripts */
dwFlags = SCRIPTCONTF_SCRIPT_USER | SCRIPTCONTF_SCRIPT_HIDE | SCRIPTCONTF_SCRIPT_SYSTEM;
es = HeapAlloc( GetProcessHeap(), 0, sizeof (EnumScript_impl) );
es->vtbl_IEnumScript = &IEnumScript_vtbl;
es->ref = 1;
es->pos = 0;
es->total = 1;
es->script_info = HeapAlloc(GetProcessHeap(), 0, sizeof(SCRIPTINFO) * es->total);
/* just a fake for now */
es->script_info[0].ScriptId = 0;
es->script_info[0].uiCodePage = 0;
strcpyW(es->script_info[0].wszDescription, defaultW);
es->script_info[0].wszFixedWidthFont[0] = 0;
es->script_info[0].wszProportionalFont[0] = 0;
*ppEnumScript = (IEnumScript *)es;
return S_OK;
}
/******************************************************************************/
static HRESULT WINAPI fnIMLangFontLink_QueryInterface(
IMLangFontLink* iface,
REFIID riid,
@ -1260,7 +1424,7 @@ static HRESULT WINAPI fnIMultiLanguage2_GetNumberOfCodePageInfo(
if (!pcCodePage) return S_FALSE;
*pcCodePage = This->total;
*pcCodePage = This->total_cp;
return S_OK;
}
@ -1489,6 +1653,21 @@ static HRESULT WINAPI fnIMultiLanguage2_ConvertStringToUnicodeEx(
return E_NOTIMPL;
}
static HRESULT WINAPI fnIMultiLanguage2_ConvertStringFromUnicodeEx(
IMultiLanguage2* This,
DWORD* pdwMode,
DWORD dwEncoding,
WCHAR* pSrcStr,
UINT* pcSrcSize,
CHAR* pDstStr,
UINT* pcDstSize,
DWORD dwFlag,
WCHAR* lpFallBack)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT WINAPI fnIMultiLanguage2_DetectCodepageInIStream(
IMultiLanguage2* iface,
DWORD dwFlag,
@ -1554,8 +1733,13 @@ static HRESULT WINAPI fnIMultiLanguage2_GetNumberOfScripts(
IMultiLanguage2* iface,
UINT* pnScripts)
{
FIXME("\n");
return E_NOTIMPL;
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage2, iface);
TRACE("%p %p\n", This, pnScripts);
if (!pnScripts) return S_FALSE;
*pnScripts = This->total_scripts;
return S_OK;
}
static HRESULT WINAPI fnIMultiLanguage2_EnumScripts(
@ -1564,8 +1748,10 @@ static HRESULT WINAPI fnIMultiLanguage2_EnumScripts(
LANGID LangId,
IEnumScript** ppEnumScript)
{
FIXME("\n");
return E_NOTIMPL;
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage2, iface);
TRACE("%p %08lx %04x %p\n", This, dwFlags, LangId, ppEnumScript);
return EnumScript_create( This, dwFlags, LangId, ppEnumScript );
}
static HRESULT WINAPI fnIMultiLanguage2_ValidateCodePageEx(
@ -1574,8 +1760,10 @@ static HRESULT WINAPI fnIMultiLanguage2_ValidateCodePageEx(
HWND hwnd,
DWORD dwfIODControl)
{
FIXME("\n");
return E_NOTIMPL;
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage2, iface);
FIXME("%p %u %p %08lx: stub!\n", This, uiCodePage, hwnd, dwfIODControl);
return S_FALSE;
}
static ICOM_VTABLE(IMultiLanguage2) IMultiLanguage2_vtbl =
@ -1601,6 +1789,7 @@ static ICOM_VTABLE(IMultiLanguage2) IMultiLanguage2_vtbl =
fnIMultiLanguage2_CreateConvertCharset,
fnIMultiLanguage2_ConvertStringInIStream,
fnIMultiLanguage2_ConvertStringToUnicodeEx,
fnIMultiLanguage2_ConvertStringFromUnicodeEx,
fnIMultiLanguage2_DetectCodepageInIStream,
fnIMultiLanguage2_DetectInputCodepage,
fnIMultiLanguage2_ValidateCodePage,
@ -1624,9 +1813,11 @@ static HRESULT MultiLanguage_create(IUnknown *pUnkOuter, LPVOID *ppObj)
mlang->vtbl_IMultiLanguage = &IMultiLanguage_vtbl;
mlang->vtbl_IMultiLanguage2 = &IMultiLanguage2_vtbl;
mlang->total = 0;
mlang->total_cp = 0;
for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++)
mlang->total += mlang_data[i].number_of_cp;
mlang->total_cp += mlang_data[i].number_of_cp;
mlang->total_scripts = 1;
mlang->ref = 1;
*ppObj = (LPVOID) mlang;

View File

@ -35,6 +35,7 @@
#endif
/*#define DUMP_CP_INFO*/
/*#define DUMP_SCRIPT_INFO*/
#define TRACE_2 OutputDebugStringA
@ -45,8 +46,19 @@ static void test_multibyte_to_unicode_translations(IMultiLanguage2 *iML2)
WCHAR stringW[] = {'J','u','s','t',' ','a',' ','t','e','s','t',' ','s','t','r','i','n','g',0};
char bufA[256];
WCHAR bufW[256];
UINT lenA, lenW;
UINT lenA, lenW, expected_len;
HRESULT ret;
HMODULE hMlang;
FARPROC pConvertINetMultiByteToUnicode;
FARPROC pConvertINetUnicodeToMultiByte;
hMlang = LoadLibraryA("mlang.dll");
ok(hMlang != 0, "couldn't load mlang.dll\n");
pConvertINetMultiByteToUnicode = GetProcAddress(hMlang, "ConvertINetMultiByteToUnicode");
ok(pConvertINetMultiByteToUnicode != NULL, "couldn't resolve ConvertINetMultiByteToUnicode\n");
pConvertINetUnicodeToMultiByte = GetProcAddress(hMlang, "ConvertINetUnicodeToMultiByte");
ok(pConvertINetUnicodeToMultiByte != NULL, "couldn't resolve ConvertINetUnicodeToMultiByte\n");
/* IMultiLanguage2_ConvertStringToUnicode tests */
@ -93,6 +105,33 @@ static void test_multibyte_to_unicode_translations(IMultiLanguage2 *iML2)
bufW[lenW] = 0; /* -1 doesn't include 0 terminator */
ok(!lstrcmpA((LPCSTR)bufW, stringA), "bufW/stringA mismatch\n");
memset(bufW, 'x', sizeof(bufW));
lenA = lstrlenA(stringA);
lenW = 0;
ret = IMultiLanguage2_ConvertStringToUnicode(iML2, NULL, 1252, stringA, &lenA, NULL, &lenW);
ok(ret == S_OK, "IMultiLanguage2_ConvertStringToUnicode failed: %08lx\n", ret);
ok(lenA == lstrlenA(stringA), "expected lenA %u, got %u\n", lstrlenA(stringA), lenA);
expected_len = MultiByteToWideChar(1252, 0, stringA, lenA, NULL, 0);
ok(lenW == expected_len, "expected lenW %u, got %u\n", expected_len, lenW);
memset(bufW, 'x', sizeof(bufW));
lenA = lstrlenA(stringA);
lenW = sizeof(bufW)/sizeof(bufW[0]);
ret = pConvertINetMultiByteToUnicode(NULL, 1252, stringA, &lenA, NULL, &lenW);
ok(ret == S_OK, "ConvertINetMultiByteToUnicode failed: %08lx\n", ret);
ok(lenA == lstrlenA(stringA), "expected lenA %u, got %u\n", lstrlenA(stringA), lenA);
expected_len = MultiByteToWideChar(1252, 0, stringA, lenA, NULL, 0);
ok(lenW == expected_len, "expected lenW %u, got %u\n", expected_len, lenW);
memset(bufW, 'x', sizeof(bufW));
lenA = lstrlenA(stringA);
lenW = 0;
ret = pConvertINetMultiByteToUnicode(NULL, 1252, stringA, &lenA, NULL, &lenW);
ok(ret == S_OK, "ConvertINetMultiByteToUnicode failed: %08lx\n", ret);
ok(lenA == lstrlenA(stringA), "expected lenA %u, got %u\n", lstrlenA(stringA), lenA);
expected_len = MultiByteToWideChar(1252, 0, stringA, lenA, NULL, 0);
ok(lenW == expected_len, "expected lenW %u, got %u\n", expected_len, lenW);
/* IMultiLanguage2_ConvertStringFromUnicode tests */
memset(bufA, 'x', sizeof(bufA));
@ -138,6 +177,33 @@ static void test_multibyte_to_unicode_translations(IMultiLanguage2 *iML2)
bufA[lenA] = 0; /* -1 doesn't include 0 terminator */
bufA[lenA+1] = 0; /* sizeof(WCHAR) */
ok(!lstrcmpW((LPCWSTR)bufA, stringW), "bufA/stringW mismatch\n");
memset(bufA, 'x', sizeof(bufA));
lenW = lstrlenW(stringW);
lenA = 0;
ret = IMultiLanguage2_ConvertStringFromUnicode(iML2, NULL, 1252, stringW, &lenW, NULL, &lenA);
ok(ret == S_OK, "IMultiLanguage2_ConvertStringFromUnicode failed: %08lx\n", ret);
ok(lenW == lstrlenW(stringW), "expected lenW %u, got %u\n", lstrlenW(stringW), lenW);
expected_len = WideCharToMultiByte(1252, 0, stringW, lenW, NULL, 0, NULL, NULL);
ok(lenA == expected_len, "expected lenA %u, got %u\n", expected_len, lenA);
memset(bufA, 'x', sizeof(bufA));
lenW = lstrlenW(stringW);
lenA = sizeof(bufA);
ret = pConvertINetUnicodeToMultiByte(NULL, 1252, stringW, &lenW, NULL, &lenA);
ok(ret == S_OK, "ConvertINetUnicodeToMultiByte failed: %08lx\n", ret);
ok(lenW == lstrlenW(stringW), "expected lenW %u, got %u\n", lstrlenW(stringW), lenW);
expected_len = WideCharToMultiByte(1252, 0, stringW, lenW, NULL, 0, NULL, NULL);
ok(lenA == expected_len, "expected lenA %u, got %u\n", expected_len, lenA);
memset(bufA, 'x', sizeof(bufA));
lenW = lstrlenW(stringW);
lenA = 0;
ret = pConvertINetUnicodeToMultiByte(NULL, 1252, stringW, &lenW, NULL, &lenA);
ok(ret == S_OK, "ConvertINetUnicodeToMultiByte failed: %08lx\n", ret);
ok(lenW == lstrlenW(stringW), "expected lenW %u, got %u\n", lstrlenW(stringW), lenW);
expected_len = WideCharToMultiByte(1252, 0, stringW, lenW, NULL, 0, NULL, NULL);
ok(lenA == expected_len, "expected lenA %u, got %u\n", expected_len, lenA);
}
static void inline cpinfo_cmp(MIMECPINFO *cpinfo1, MIMECPINFO *cpinfo2)
@ -222,7 +288,7 @@ static void test_EnumCodePages(IMultiLanguage2 *iML2, DWORD flags)
n = total * 2;
TRACE_2("Call IEnumCodePage_Next\n");
ret = IEnumCodePage_Next(iEnumCP, n, cpinfo, &n);
ok(ret == S_OK && n != 0, "IEnumCodePage_Next: expected S_OK, got %08lx/%lu\n", ret, n);
ok(ret == S_OK && n != 0, "IEnumCodePage_Next: expected S_OK/!0, got %08lx/%lu\n", ret, n);
trace("flags %08lx, enumerated codepages %lu\n", flags, n);
@ -310,13 +376,13 @@ static void test_EnumCodePages(IMultiLanguage2 *iML2, DWORD flags)
/* now IEnumCodePage_Next should fail, since pointer is at the end */
n = 1;
ret = IEnumCodePage_Next(iEnumCP, 1, &cpinfo2, &n);
ok(ret == S_FALSE && n == 0, "IEnumCodePage_Next: expected S_OK/0, got %08lx/%lu\n", ret, n);
ok(ret == S_FALSE && n == 0, "IEnumCodePage_Next: expected S_FALSE/0, got %08lx/%lu\n", ret, n);
ret = IEnumCodePage_Reset(iEnumCP);
ok(ret == S_OK, "IEnumCodePage_Reset: expected S_OK, got %08lx\n", ret);
n = 0;
ret = IEnumCodePage_Next(iEnumCP, 1, &cpinfo2, &n);
ok(n == 1 && ret == S_OK, "IEnumCodePage_Next: expected 2/S_OK, got %lu/%08lx\n", n, ret);
ok(n == 1 && ret == S_OK, "IEnumCodePage_Next: expected 1/S_OK, got %lu/%08lx\n", n, ret);
cpinfo_cmp(&cpinfo[0], &cpinfo2);
#if 0
@ -338,6 +404,125 @@ static void test_EnumCodePages(IMultiLanguage2 *iML2, DWORD flags)
IEnumCodePage_Release(iEnumCP);
}
static void inline scriptinfo_cmp(SCRIPTINFO *sinfo1, SCRIPTINFO *sinfo2)
{
ok(sinfo1->ScriptId == sinfo2->ScriptId, "ScriptId mismatch: %d != %d\n", sinfo1->ScriptId, sinfo2->ScriptId);
ok(sinfo1->uiCodePage == sinfo2->uiCodePage, "uiCodePage mismatch: %u != %u\n", sinfo1->uiCodePage, sinfo2->uiCodePage);
ok(!lstrcmpW(sinfo1->wszDescription, sinfo2->wszDescription), "wszDescription mismatch\n");
ok(!lstrcmpW(sinfo1->wszFixedWidthFont, sinfo2->wszFixedWidthFont), "wszFixedWidthFont mismatch\n");
ok(!lstrcmpW(sinfo1->wszProportionalFont, sinfo2->wszProportionalFont), "wszProportionalFont mismatch\n");
}
static void test_EnumScripts(IMultiLanguage2 *iML2, DWORD flags)
{
IEnumScript *iEnumScript = NULL;
SCRIPTINFO *sinfo;
SCRIPTINFO sinfo2;
HRESULT ret;
ULONG i, n;
UINT total;
total = 0;
TRACE_2("Call IMultiLanguage2_GetNumberOfScripts\n");
ret = IMultiLanguage2_GetNumberOfScripts(iML2, &total);
ok(ret == S_OK && total != 0, "IMultiLanguage2_GetNumberOfScripts: expected S_OK/!0, got %08lx/%u\n", ret, total);
trace("total mlang supported scripts %u\n", total);
TRACE_2("Call IMultiLanguage2_EnumScripts\n");
ret = IMultiLanguage2_EnumScripts(iML2, flags, LANG_NEUTRAL, &iEnumScript);
trace("IMultiLanguage2_EnumScripts = %08lx, iEnumScript = %p\n", ret, iEnumScript);
ok(ret == S_OK && iEnumScript, "IMultiLanguage2_EnumScripts: expected S_OK/!NULL, got %08lx/%p\n", ret, iEnumScript);
TRACE_2("Call IEnumScript_Reset\n");
ret = IEnumScript_Reset(iEnumScript);
ok(ret == S_OK, "IEnumScript_Reset: expected S_OK, got %08lx\n", ret);
n = 65536;
TRACE_2("Call IEnumScript_Next\n");
ret = IEnumScript_Next(iEnumScript, 0, NULL, &n);
ok(n == 65536 && ret == E_FAIL, "IEnumScript_Next: expected 65536/E_FAIL, got %lu/%08lx\n", n, ret);
TRACE_2("Call IEnumScript_Next\n");
ret = IEnumScript_Next(iEnumScript, 0, NULL, NULL);
ok(ret == E_FAIL, "IEnumScript_Next: expected E_FAIL, got %08lx\n", ret);
sinfo = HeapAlloc(GetProcessHeap(), 0, sizeof(*sinfo) * total * 2);
n = total * 2;
TRACE_2("Call IEnumScript_Next\n");
ret = IEnumScript_Next(iEnumScript, 0, sinfo, &n);
ok(ret == S_FALSE && n == 0, "IEnumScript_Next: expected S_FALSE/0, got %08lx/%lu\n", ret, n);
n = total * 2;
TRACE_2("Call IEnumScript_Next\n");
ret = IEnumScript_Next(iEnumScript, n, sinfo, &n);
ok(ret == S_OK && n != 0, "IEnumScript_Next: expected S_OK, got %08lx/%lu\n", ret, n);
trace("flags %08lx, enumerated scripts %lu\n", flags, n);
if (!flags)
{
ok(n == total, "IEnumScript_Next: expected %u, got %lu", total, n);
flags = SCRIPTCONTF_SCRIPT_USER | SCRIPTCONTF_SCRIPT_HIDE | SCRIPTCONTF_SCRIPT_SYSTEM;
}
total = n;
for (i = 0; i < n; i++)
{
CPINFOEXA cpinfoex;
#ifdef DUMP_SCRIPT_INFO
trace("SCRIPTINFO #%lu:\n"
"ScriptId %08lx\n"
"uiCodePage %u\n"
"wszDescription %s\n"
"wszFixedWidthFont %s\n"
"wszProportionalFont %s\n\n",
i,
sinfo[i].ScriptId,
sinfo[i].uiCodePage,
wine_dbgstr_w(sinfo[i].wszDescription),
wine_dbgstr_w(sinfo[i].wszFixedWidthFont),
wine_dbgstr_w(sinfo[i].wszProportionalFont));
#endif
if (GetCPInfoExA(sinfo[i].uiCodePage, 0, &cpinfoex))
trace("CodePage %u name: %s\n", sinfo[i].uiCodePage, cpinfoex.CodePageName);
else
trace("GetCPInfoExA failed for cp %u\n", sinfo[i].uiCodePage);
trace("---\n");
}
/* now IEnumScript_Next should fail, since pointer is at the end */
n = 1;
ret = IEnumScript_Next(iEnumScript, 1, &sinfo2, &n);
ok(ret == S_FALSE && n == 0, "IEnumScript_Next: expected S_FALSE/0, got %08lx/%lu\n", ret, n);
ret = IEnumScript_Reset(iEnumScript);
ok(ret == S_OK, "IEnumScript_Reset: expected S_OK, got %08lx\n", ret);
n = 0;
ret = IEnumScript_Next(iEnumScript, 1, &sinfo2, &n);
ok(n == 1 && ret == S_OK, "IEnumScript_Next: expected 1/S_OK, got %lu/%08lx\n", n, ret);
scriptinfo_cmp(&sinfo[0], &sinfo2);
#if 0
/* Due to a bug in MS' implementation of IEnumScript_Skip
* it's not used here.
*/
ret = IEnumScript_Skip(iEnumScript, 1);
ok(ret == S_OK, "IEnumScript_Skip: expected S_OK, got %08lx\n", ret);
#endif
for (i = 0; i < total - 1; i++)
{
n = 0;
ret = IEnumScript_Next(iEnumScript, 1, &sinfo2, &n);
ok(n == 1 && ret == S_OK, "IEnumScript_Next: expected 1/S_OK, got %lu/%08lx\n", n, ret);
scriptinfo_cmp(&sinfo[i + 1], &sinfo2);
}
HeapFree(GetProcessHeap(), 0, sinfo);
IEnumScript_Release(iEnumScript);
}
START_TEST(mlang)
{
IMultiLanguage2 *iML2 = NULL;
@ -359,6 +544,10 @@ START_TEST(mlang)
/* FIXME: why MIMECONTF_MIME_REGISTRY returns 0 of supported codepages? */
/*test_EnumCodePages(iML2, MIMECONTF_MIME_REGISTRY);*/
test_EnumScripts(iML2, 0);
test_EnumScripts(iML2, SCRIPTCONTF_SCRIPT_USER);
test_EnumScripts(iML2, SCRIPTCONTF_SCRIPT_USER | SCRIPTCONTF_SCRIPT_HIDE | SCRIPTCONTF_SCRIPT_SYSTEM);
TRACE_2("Call IMultiLanguage2_IsConvertible\n");
ret = IMultiLanguage2_IsConvertible(iML2, CP_UTF8, CP_UNICODE);
ok(ret == S_OK, "IMultiLanguage2_IsConvertible(CP_UTF8 -> CP_UNICODE) = %08lx\n", ret);

View File

@ -346,14 +346,78 @@ typedef struct IEnumScript IEnumScript;
#define MAX_SCRIPT_NAME (48)
#define MAX_MIMEFACE_NAME (32)
typedef BYTE SCRIPT_ID;
typedef __int64 SCRIPT_IDS;
typedef enum tagSCRIPTCONTF {
sidDefault = 0,
sidMerge = sidDefault + 1,
sidAsciiSym = sidMerge + 1,
sidAsciiLatin = sidAsciiSym + 1,
sidLatin = sidAsciiLatin + 1,
sidGreek = sidLatin + 1,
sidCyrillic = sidGreek + 1,
sidArmenian = sidCyrillic + 1,
sidHebrew = sidArmenian + 1,
sidArabic = sidHebrew + 1,
sidDevanagari = sidArabic + 1,
sidBengali = sidDevanagari + 1,
sidGurmukhi = sidBengali + 1,
sidGujarati = sidGurmukhi + 1,
sidOriya = sidGujarati + 1,
sidTamil = sidOriya + 1,
sidTelugu = sidTamil + 1,
sidKannada = sidTelugu + 1,
sidMalayalam = sidKannada + 1,
sidThai = sidMalayalam + 1,
sidLao = sidThai + 1,
sidTibetan = sidLao + 1,
sidGeorgian = sidTibetan + 1,
sidHangul = sidGeorgian + 1,
sidKana = sidHangul + 1,
sidBopomofo = sidKana + 1,
sidHan = sidBopomofo + 1,
sidEthiopic = sidHan + 1,
sidCanSyllabic = sidEthiopic + 1,
sidCherokee = sidCanSyllabic + 1,
sidYi = sidCherokee + 1,
sidBraille = sidYi + 1,
sidRunic = sidBraille + 1,
sidOgham = sidRunic + 1,
sidSinhala = sidOgham + 1,
sidSyriac = sidSinhala + 1,
sidBurmese = sidSyriac + 1,
sidKhmer = sidBurmese + 1,
sidThaana = sidKhmer + 1,
sidMongolian = sidThaana + 1,
sidUserDefined = sidMongolian + 1,
sidLim = sidUserDefined + 1,
sidFEFirst = sidHangul,
sidFELast = sidHan
} SCRIPTCONTF;
typedef enum tagSCRIPTFONTCONTF {
SCRIPTCONTF_FIXED_FONT = 0x1,
SCRIPTCONTF_PROPORTIONAL_FONT = 0x2,
SCRIPTCONTF_SCRIPT_USER = 0x10000,
SCRIPTCONTF_SCRIPT_HIDE = 0x20000,
SCRIPTCONTF_SCRIPT_SYSTEM = 0x40000
} SCRIPTFONTCONTF;
typedef struct tagSCRIPFONTINFO {
SCRIPT_IDS scripts;
WCHAR wszFont[32];
} SCRIPTFONTINFO, *PSCRIPTFONTINFO;
typedef struct tagSCRIPTINFO {
SCRIPT_ID ScriptId;
UINT uiCodePage;
WCHAR wszDescription[48];
WCHAR wszFixedWidthFont[1];
WCHAR wszProportionalFont[1];
WCHAR wszFixedWidthFont[32];
WCHAR wszProportionalFont[32];
} SCRIPTINFO, *PSCRIPTINFO;
/*****************************************************************************
@ -489,8 +553,6 @@ typedef struct IEnumCodePage IEnumCodePage;
#define MAX_MIMECSET_NAME (50)
#define MAX_MIMEFACE_NAME (32)
typedef enum tagMIMECONTF {
MIMECONTF_MAILNEWS = 0x1,
MIMECONTF_BROWSER = 0x2,
@ -1501,6 +1563,16 @@ struct IMultiLanguage2 : public IUnknown
DWORD dwFlag,
WCHAR* lpFallBack) = 0;
virtual HRESULT STDMETHODCALLTYPE ConvertStringFromUnicodeEx(
DWORD* pdwMode,
DWORD dwEncoding,
WCHAR* pSrcStr,
UINT* pcSrcSize,
CHAR* pDstStr,
UINT* pcDstSize,
DWORD dwFlag,
WCHAR* lpFallBack) = 0;
virtual HRESULT STDMETHODCALLTYPE DetectCodepageInIStream(
DWORD dwFlag,
DWORD dwPrefWinCodePage,
@ -1678,6 +1750,17 @@ struct IMultiLanguage2Vtbl {
DWORD dwFlag,
WCHAR* lpFallBack);
HRESULT (STDMETHODCALLTYPE *ConvertStringFromUnicodeEx)(
IMultiLanguage2* This,
DWORD* pdwMode,
DWORD dwEncoding,
WCHAR* pSrcStr,
UINT* pcSrcSize,
CHAR* pDstStr,
UINT* pcDstSize,
DWORD dwFlag,
WCHAR* lpFallBack);
HRESULT (STDMETHODCALLTYPE *DetectCodepageInIStream)(
IMultiLanguage2* This,
DWORD dwFlag,
@ -1755,6 +1838,7 @@ struct IMultiLanguage2Vtbl {
#define IMultiLanguage2_CreateConvertCharset(p,a,b,c,d) (p)->lpVtbl->CreateConvertCharset(p,a,b,c,d)
#define IMultiLanguage2_ConvertStringInIStream(p,a,b,c,d,e,f,g) (p)->lpVtbl->ConvertStringInIStream(p,a,b,c,d,e,f,g)
#define IMultiLanguage2_ConvertStringToUnicodeEx(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->ConvertStringToUnicodeEx(p,a,b,c,d,e,f,g,h)
#define IMultiLanguage2_ConvertStringFromUnicodeEx(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->ConvertStringFromUnicodeEx(p,a,b,c,d,e,f,g,h)
#define IMultiLanguage2_DetectCodepageInIStream(p,a,b,c,d,e) (p)->lpVtbl->DetectCodepageInIStream(p,a,b,c,d,e)
#define IMultiLanguage2_DetectInputCodepage(p,a,b,c,d,e,f) (p)->lpVtbl->DetectInputCodepage(p,a,b,c,d,e,f)
#define IMultiLanguage2_ValidateCodePage(p,a,b) (p)->lpVtbl->ValidateCodePage(p,a,b)
@ -1791,6 +1875,7 @@ struct IMultiLanguage2Vtbl {
STDMETHOD_(HRESULT,CreateConvertCharset)(THIS_ UINT uiSrcCodePage, UINT uiDstCodePage, DWORD dwProperty, IMLangConvertCharset** ppMLangConvertCharset) PURE; \
STDMETHOD_(HRESULT,ConvertStringInIStream)(THIS_ DWORD* pdwMode, DWORD dwFlag, WCHAR* lpFallBack, DWORD dwSrcEncoding, DWORD dwDstEncoding, IStream* pstmIn, IStream* pstmOut) PURE; \
STDMETHOD_(HRESULT,ConvertStringToUnicodeEx)(THIS_ DWORD* pdwMode, DWORD dwEncoding, CHAR* pSrcStr, UINT* pcSrcSize, WCHAR* pDstStr, UINT* pcDstSize, DWORD dwFlag, WCHAR* lpFallBack) PURE; \
STDMETHOD_(HRESULT,ConvertStringFromUnicodeEx)(THIS_ DWORD* pdwMode, DWORD dwEncoding, WCHAR* pSrcStr, UINT* pcSrcSize, CHAR* pDstStr, UINT* pcDstSize, DWORD dwFlag, WCHAR* lpFallBack) PURE; \
STDMETHOD_(HRESULT,DetectCodepageInIStream)(THIS_ DWORD dwFlag, DWORD dwPrefWinCodePage, IStream* pstmIn, DetectEncodingInfo* lpEncoding, INT* pnScores) PURE; \
STDMETHOD_(HRESULT,DetectInputCodepage)(THIS_ DWORD dwFlag, DWORD dwPrefWinCodePage, CHAR* pSrcStr, INT* pcSrcSize, DetectEncodingInfo* lpEncoding, INT* pnScores) PURE; \
STDMETHOD_(HRESULT,ValidateCodePage)(THIS_ UINT uiCodePage, HWND hwnd) PURE; \
@ -1980,6 +2065,21 @@ void __RPC_STUB IMultiLanguage2_ConvertStringToUnicodeEx_Stub(
struct IRpcChannelBuffer* pRpcChannelBuffer,
PRPC_MESSAGE pRpcMessage,
DWORD* pdwStubPhase);
HRESULT CALLBACK IMultiLanguage2_ConvertStringFromUnicodeEx_Proxy(
IMultiLanguage2* This,
DWORD* pdwMode,
DWORD dwEncoding,
WCHAR* pSrcStr,
UINT* pcSrcSize,
CHAR* pDstStr,
UINT* pcDstSize,
DWORD dwFlag,
WCHAR* lpFallBack);
void __RPC_STUB IMultiLanguage2_ConvertStringFromUnicodeEx_Stub(
struct IRpcStubBuffer* This,
struct IRpcChannelBuffer* pRpcChannelBuffer,
PRPC_MESSAGE pRpcMessage,
DWORD* pdwStubPhase);
HRESULT CALLBACK IMultiLanguage2_DetectCodepageInIStream_Proxy(
IMultiLanguage2* This,
DWORD dwFlag,
@ -2088,6 +2188,7 @@ DEFINE_GUID(IID_IMLangFontLink, 0x359F3441,0xBD4A,0x11D0,0xB1,0x88,0x00,0xAA,0x0
DEFINE_GUID(IID_IMultiLanguage2, 0xDCCFC164,0x2B38,0x11d2,0xB7,0xEC,0x00,0xC0,0x4F,0x8F,0x5D,0x9A);
DEFINE_GUID(IID_IMultiLanguage, 0x275c23e1,0x3747,0x11d0,0x9f,0xea,0x00,0xaa,0x00,0x3f,0x86,0x46);
DEFINE_GUID(IID_IEnumCodePage, 0x275c23e3,0x3747,0x11d0,0x9f,0xea,0x00,0xaa,0x00,0x3f,0x86,0x46);
DEFINE_GUID(IID_IEnumScript, 0xae5f1430,0x388b,0x11d2,0x83,0x80,0x00,0xc0,0x4f,0x8f,0x5d,0xa1);
#ifdef __cplusplus
}
#endif

View File

@ -79,8 +79,73 @@ interface IMLangFontLink : IMLangCodePages
interface IEnumScript : IUnknown
{
const USHORT MAX_SCRIPT_NAME = 48;
const USHORT MAX_MIMEFACE_NAME = 32;
typedef BYTE SCRIPT_ID;
typedef __int64 SCRIPT_IDS;
typedef enum tagSCRIPTCONTF
{
sidDefault = 0,
sidMerge = sidDefault + 1,
sidAsciiSym = sidMerge + 1,
sidAsciiLatin = sidAsciiSym + 1,
sidLatin = sidAsciiLatin + 1,
sidGreek = sidLatin + 1,
sidCyrillic = sidGreek + 1,
sidArmenian = sidCyrillic + 1,
sidHebrew = sidArmenian + 1,
sidArabic = sidHebrew + 1,
sidDevanagari = sidArabic + 1,
sidBengali = sidDevanagari + 1,
sidGurmukhi = sidBengali + 1,
sidGujarati = sidGurmukhi + 1,
sidOriya = sidGujarati + 1,
sidTamil = sidOriya + 1,
sidTelugu = sidTamil + 1,
sidKannada = sidTelugu + 1,
sidMalayalam = sidKannada + 1,
sidThai = sidMalayalam + 1,
sidLao = sidThai + 1,
sidTibetan = sidLao + 1,
sidGeorgian = sidTibetan + 1,
sidHangul = sidGeorgian + 1,
sidKana = sidHangul + 1,
sidBopomofo = sidKana + 1,
sidHan = sidBopomofo + 1,
sidEthiopic = sidHan + 1,
sidCanSyllabic = sidEthiopic + 1,
sidCherokee = sidCanSyllabic + 1,
sidYi = sidCherokee + 1,
sidBraille = sidYi + 1,
sidRunic = sidBraille + 1,
sidOgham = sidRunic + 1,
sidSinhala = sidOgham + 1,
sidSyriac = sidSinhala + 1,
sidBurmese = sidSyriac + 1,
sidKhmer = sidBurmese + 1,
sidThaana = sidKhmer + 1,
sidMongolian = sidThaana + 1,
sidUserDefined = sidMongolian + 1,
sidLim = sidUserDefined + 1,
sidFEFirst = sidHangul,
sidFELast = sidHan
} SCRIPTCONTF;
typedef enum tagSCRIPTFONTCONTF
{
SCRIPTCONTF_FIXED_FONT = 0x1,
SCRIPTCONTF_PROPORTIONAL_FONT = 0x2,
SCRIPTCONTF_SCRIPT_USER = 0x10000,
SCRIPTCONTF_SCRIPT_HIDE = 0x20000,
SCRIPTCONTF_SCRIPT_SYSTEM = 0x40000
} SCRIPTFONTCONTF;
typedef struct tagSCRIPFONTINFO
{
SCRIPT_IDS scripts;
WCHAR wszFont[MAX_MIMEFACE_NAME];
} SCRIPTFONTINFO, *PSCRIPTFONTINFO;
typedef struct tagSCRIPTINFO {
SCRIPT_ID ScriptId;
@ -112,7 +177,6 @@ interface IEnumCodePage : IUnknown
{
const USHORT MAX_MIMECP_NAME = 64;
const USHORT MAX_MIMECSET_NAME = 50;
const USHORT MAX_MIMEFACE_NAME = 32;
typedef enum tagMIMECONTF
{
@ -418,6 +482,16 @@ interface IMultiLanguage2 : IUnknown
[in] DWORD dwFlag,
[in] WCHAR *lpFallBack);
HRESULT ConvertStringFromUnicodeEx(
[in,out] DWORD *pdwMode,
[in] DWORD dwEncoding,
[in] WCHAR *pSrcStr,
[in,out] UINT *pcSrcSize,
[in] CHAR *pDstStr,
[in,out] UINT *pcDstSize,
[in] DWORD dwFlag,
[in] WCHAR *lpFallBack);
HRESULT DetectCodepageInIStream(
[in] DWORD dwFlag,
[in] DWORD dwPrefWinCodePage,
@ -482,3 +556,4 @@ cpp_quote("DEFINE_GUID(IID_IMLangFontLink, 0x359F3441,0xBD4A,0x11D0,0xB1,0x88,0x
cpp_quote("DEFINE_GUID(IID_IMultiLanguage2, 0xDCCFC164,0x2B38,0x11d2,0xB7,0xEC,0x00,0xC0,0x4F,0x8F,0x5D,0x9A);")
cpp_quote("DEFINE_GUID(IID_IMultiLanguage, 0x275c23e1,0x3747,0x11d0,0x9f,0xea,0x00,0xaa,0x00,0x3f,0x86,0x46);")
cpp_quote("DEFINE_GUID(IID_IEnumCodePage, 0x275c23e3,0x3747,0x11d0,0x9f,0xea,0x00,0xaa,0x00,0x3f,0x86,0x46);")
cpp_quote("DEFINE_GUID(IID_IEnumScript, 0xae5f1430,0x388b,0x11d2,0x83,0x80,0x00,0xc0,0x4f,0x8f,0x5d,0xa1);")

View File

@ -26,6 +26,7 @@ TESTS = \
iphlpapi \
kernel32 \
mapi32 \
mlang \
msacm32 \
msvcrt \
msvcrtd \
@ -93,6 +94,8 @@ kernel32_test.exe$(DLLEXT): $(DLLDIR)/kernel/tests/kernel32_test.exe$(DLLEXT)
cp $(DLLDIR)/kernel/tests/kernel32_test.exe$(DLLEXT) $@ && $(STRIP) $@
mapi32_test.exe$(DLLEXT): $(DLLDIR)/mapi32/tests/mapi32_test.exe$(DLLEXT)
cp $(DLLDIR)/mapi32/tests/mapi32_test.exe$(DLLEXT) $@ && $(STRIP) $@
mlang_test.exe$(DLLEXT): $(DLLDIR)/mlang/tests/mlang_test.exe$(DLLEXT)
cp $(DLLDIR)/mlang/tests/mlang_test.exe$(DLLEXT) $@ && $(STRIP) $@
msacm32_test.exe$(DLLEXT): $(DLLDIR)/msacm/tests/msacm32_test.exe$(DLLEXT)
cp $(DLLDIR)/msacm/tests/msacm32_test.exe$(DLLEXT) $@ && $(STRIP) $@
msvcrt_test.exe$(DLLEXT): $(DLLDIR)/msvcrt/tests/msvcrt_test.exe$(DLLEXT)