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

文章详细介绍了在使用vs2008升级后遇到的区域设置问题导致路径转换失败的情况,特别是针对繁体字符目录下的启动异常问题进行了深入分析,并提供了关键解决方法,即在程序开始时调用SetThreadLocale(LOCALE_SYSTEM_DEFAULT)。此外,文章还解释了不同版本间字符串转换机制的变化,以及如何通过调整区域设置和代码配置来确保程序跨平台兼容性。
摘要由CSDN通过智能技术生成
升级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


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值