解决Mygui不支持中文路径


昨日不可追, 今日尤可为.勤奋,炽诚,不忘初心


 

 

外国人写的Mygui库,不支持中文路径,情有可原,中文编码嘛,中国的标准,对吧.

但是! 中国那么多用Mygui的大虾呢?网上居然找不到一篇博客是解决Mygui中文路径的,这是我无法容忍的,

我更加无法容忍的,是那种逃避的心理 :我问了很多人,想询问一些解决方案,绝大多数人反问说:不能用中文,那干嘛用中文...

(其实我是第一个想逃的,被老大教训了一通,人呐,不逼逼就不能称得上是人~!都是被逼出来的~...)

 

行吧,搞就搞吧,准备了度娘,狗狗,鼻音,还怕有解决不了的问题吗,害怕搜不到答案吗?

结果...充分验证了墨菲定律(如果一件事情有可能发生,那么她一定会发生...)

搜了一天无果,再无法淡定,破骂网上一群庸才耳.

问题还是要解决的:通过这次的研究,明白了一些编码的原理个规则,还有,出现乱码的原因.

 

 

从问题入手,抓住主要矛盾.老毛的源程序用了中文路径后,就会报:throw invalid_data( "invalid UTF-8 sequence header value" );

无效的UTF-8,可以推断出,老毛采用的是UTF-8编码.

关于UTF-8的介绍,有一篇文章写的还是不错,百度的解释,云里雾里,魂淡.

博客地址:UTF-8编码介绍

我感觉啊,vs(中国)默认用的是ANSI编码(简体中文)

ansi的给力解释:

解决Mygui不支持中文路径_第1张图片

写一些转换函数:

	//--------------------begin------------------------------------------------------------------
	string UnicodeToUTF8(const wchar_t* str)
	{
		char* result;
		int textlen;
		textlen = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
		result = (char *)malloc((textlen + 1)*sizeof(char));
		memset(result, 0, sizeof(char)* (textlen + 1));
		WideCharToMultiByte(CP_UTF8, 0, str, -1, result, textlen, NULL, NULL);
		return result;
	}

	wchar_t * ANSIToUnicode(const char* str)
	{
		int textlen;
		wchar_t * result;
		textlen = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
		result = (wchar_t *)malloc((textlen + 1)*sizeof(wchar_t));
		memset(result, 0, (textlen + 1)*sizeof(wchar_t));
		MultiByteToWideChar(CP_ACP, 0, str, -1, (LPWSTR)result, textlen);
		return result;
	}

	string ANSIToUTF8(const string str)
	{
		return UnicodeToUTF8(ANSIToUnicode(str.c_str()));
	}
	//--------------------end------------------------------------------------------------------

修改Mygui源文件目录MyGUI_3.2.0\Platforms\DirectX\DirectXPlatform\src下的MyGUI_DirectXDataManager.cpp文件,修改addResourceLocation这个函数

代码如下:

 

	void DirectXDataManager::addResourceLocation(const std::string& _name, bool _recursive)
	{
		ArhivInfo info;

		//将路径名字转成utf-8格式编码:
		string utf8Name = ANSIToUTF8(_name);

		info.name = MyGUI::UString(utf8Name).asWStr();
		info.recursive = _recursive;
		mPaths.push_back(info);
	}

 

 

 

 

 

 

光这样还不行,因为加载资源的时候,windows不认识UTF-8编码格式(知道这个很重要.)

所以,真正加载资源的时候,要把utf8再转换成ANSI(windows不认识utf8,这个说过了)

代码如下:

添加 Utf8到ANSI的转换函数:

string  Utf8ToGBK(const std::string& strUTF8)//转GBK测试结果也对,不知道可不可以.以后验证了再改
{
	int len = MultiByteToWideChar(CP_UTF8, 0, strUTF8.c_str(), -1, NULL, 0);
	unsigned short * wszGBK = new unsigned short[len + 1];
	memset(wszGBK, 0, len * 2 + 2);
	MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUTF8.c_str(), -1, (LPWSTR)wszGBK, len);
	len = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)wszGBK, -1, NULL, 0, NULL, NULL);
	char *szGBK = new char[len + 1];
	memset(szGBK, 0, len + 1);
	WideCharToMultiByte(CP_ACP, 0, (LPWSTR)wszGBK, -1, szGBK, len, NULL, NULL);
	//strUTF8 = szGBK; 
	std::string strTemp(szGBK);
	delete[]szGBK;
	delete[]wszGBK;
	return strTemp;
}

修改MyGUI_DirectXDataManager.cpp中getData函数:

代码如下:

	IDataStream* DirectXDataManager::getData(const std::string& _name)
	{
		std::string filepath = getDataPath(_name);

		//utf8转ansi
		string relpath = Utf8ToGBK(filepath);

		if (relpath.empty())//filepath
			return nullptr;
		std::ifstream* stream = new std::ifstream();
		stream->open(relpath.c_str(), std::ios_base::binary);
		if (!stream->is_open())
		{
			delete stream;
			return nullptr;
		}
		DataFileStream* data = new DataFileStream(stream);
		return data;
	}


结果图展示:

解决Mygui不支持中文路径_第2张图片

解决Mygui不支持中文路径_第3张图片

转换函数可能有问题,最后可能应该转成ANSI,而我转成了GBK,不知道可不可以.

修改了作者源库文件,要重新编译,把dll,lib,头文件更新到自己的程序中...



你可能感兴趣的:(C++)