首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > VSTS >

升级vs2008后,区域设置不正常导致路径转换失败的有关问题

2012-06-20 
升级vs2008后,区域设置不正常导致路径转换失败的问题升级vs2008后,区域设置不正常导致路径转换失败的问题

升级vs2008后,区域设置不正常导致路径转换失败的问题
升级vs2008后,区域设置不正常导致路径转换失败的问题

繁体版本更新vs2008版本后,有玩家来报客户端启动不正常的问题,经沟通和调查,发现重现的环境是这样的

1. 玩家区域设置使用英文
2. 玩家客户端目录含有繁体字符


而如果是vs6的版本,启动是正常的

调试发现,在使用CShockwaveFlash类,设置flash路径的时候就产生了问题。

vs6

VC98\MFC\SRC\OLEDISP2.CPP    

COleDispatchDriver::InvokeHelperV

#if !defined(_UNICODE) && !defined(OLE2ANSI)
            case VT_BSTRA:
                {
                    LPCSTR lpsz = va_arg(argList, LPSTR);
                    pArg->bstrVal = ::SysAllocString(T2COLE(lpsz));            // Line 252
                    if (lpsz != NULL && pArg->bstrVal == NULL)
                        AfxThrowMemoryException();
                    pArg->vt = VT_BSTR;
                }
                break;
#endif
}


T2COLE 在默认未定义 _CONVERSION_USES_THREAD_LOCALE 的情况下,使用的是CP_ACP来做转换的


vs2008


VC\atlmfc\src\mfc\oledisp2.cpp

COleDispatchDriver::InvokeHelperV

#if !defined(_UNICODE)
            case VT_BSTRA:
                {
                    LPCSTR lpsz = va_arg(argList, LPSTR);
                    CStringW strMBToUnicode(lpsz);        // Line 286
                    pArg->bstrVal = ::SysAllocString(static_cast<LPCWSTR>(strMBToUnicode));
                    if (lpsz != NULL && pArg->bstrVal == NULL)
                        AfxThrowMemoryException();
                    pArg->vt = VT_BSTR;
                }
                break;
#endif

CStringW strMBToUnicode(lpsz);

使用的acp

inline UINT WINAPI _AtlGetConversionACP() throw()
{
#ifdef _CONVERSION_DONT_USE_THREAD_LOCALE
    return CP_ACP;
#else
    return CP_THREAD_ACP;
#endif
}


在默认未定义_CONVERSION_DONT_USE_THREAD_LOCALE的情况下,使用的是CP_THREAD_ACP。


MSDN提到了这个变化

http://msdn.microsoft.com/en-us/library/w1sc4t4k%28VS.80%29.aspx

ATL and MFC Changes: ATL 7.0 and MFC 7.0  

String Conversions

In versions of ATL up to and including ATL 3.0 in Visual C++ 6.0, string conversions using the macros in atlconv.h were always performed using the ANSI code page of the system (CP_ACP). Starting with ATL 7.0 in Visual C++ .NET, string conversions are performed using the default ANSI code page of the current thread, unless _CONVERSION_DONT_USE_THREAD_LOCALE is defined, in which case the ANSI code page of the system is used as before.





在区域设置使用英文的情况下,表现就会产生和vs6不一样的效果。注意,区域设置(Dxdiag中看到的语言版本),决定了默认的CP_THREAD_ACP,但CP_ACP,取决于系统设置,在区域设置高级里面,用于匹配非Unicode程序的版本


参: Setting the user and system locales
http://mihai-nita.net/2005/06/11/setting-the-user-and-system-locales/


解决方法是,在程序的开始出调用

SetThreadLocale(LOCALE_SYSTEM_DEFAULT);




参考资料:

1. http://msdn.microsoft.com/en-us/library/w1sc4t4k(VS.80).aspx
1. http://connect.microsoft.com/VisualStudio/feedback/details/100887/conversion-dont-use-thread-locale-does-not-work
3. http://blogs.msdn.com/b/michkap/archive/2007/05/28/2960411.aspx
4. http://mihai-nita.net/2005/06/11/setting-the-user-and-system-locales/
5. http://blogs.msdn.com/b/shawnste/archive/2011/11/09/user-locale-system-locale-ui-language-language-profile-amp-all-that.aspx
6. http://blog.donews.com/me1105/archive/2010/11/26/49.aspx
7. http://www.microsoftfaqs.com/Articles/14842531/Problems_with_garbage_characters_in_Chinese_Win7_under_VS2008


热点排行