cocos2d-x 解决win32下 从文件对话框选择文件,显示在游戏中乱码的问题

本文档介绍了如何在cocos2d-x中解决Win32环境下,从文件对话框选择文件后出现的乱码问题。首先,通过调用Win32 API获取文件名,然后将宽字符WCHAR转换为多字节char字符串,最后将GBK字符串转换为UTF8,以适应cocos2d-x的需求。通过转换函数和cocos2d-x的iconv库,成功解决中文文件名的乱码显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文章分为三个部分:
1. 讲解调用win32的API打开文件系统对话框,选择文件(支持多选)
2. 讲解如何把win32使用的宽字符字符串(WCHAR*)转换为多字节(char*)字符串
3. 讲解如何把win32使用的多字节gbk字符串(char*)转换为cocos2d-x使用的多字节utf8字符串(char*)

一. 从文件对话框的调用
我们在应用程序中,经常可以在“打开”按钮中调出windows的文件对话框,选择一些文件。中文文档中比较少讲到多选的方法,这里注明一下:

    **//初始化配置**
    OPENFILENAME opfn;
    WCHAR strfilename[MAX_PATH * 100]; // strfilename用来存储API返回的用户选择的文件的文件名。如果是多选,也全部存在这个字符串中,文件中用\0隔开,最后再多一个\0;其中第一个是文件夹的路径,接下去是文件名,例如:"文件夹\0文件A\0文件B\0\0"
    ZeroMemory(&opfn, sizeof(OPENFILENAME)); // 初始化,不用改,其实调用了memset( .. ,0, ..)
    opfn.lStructSize = sizeof(OPENFILENAME); // 初始化,不用改
    opfn.lpstrFilter = L"jpg\0*.jpg\0"; // 格式为"显示允许的格式名\0允许的格式\0",比如"全部\0*.*\0",也可以有多个过滤器,连接起来即可
    opfn.nFilterIndex = 1; // 默认选择哪一个过滤器,一般都是第一个,不用改
    opfn.lpstrFile = strfilename; // 不用改
    opfn.lpstrFile[0] = '\0'; // 不用改
    opfn.nMaxFile = sizeof(strfilename); // 不用改
    opfn.Flags = OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; // 多选的话一定要有OFN_ALLOWMULTISELECT,否则单选

    **//调用GetOpenFileName,打开文件选择对话框**
    if (!GetOpenFileName(&opfn)) { return -1;}

    // 前面说了多选的存储方式,这里提供一种取出每个文件名的实现
    WCHAR *filename = strfilename;
    WCHAR allFileNames[MAX_PATH * 100];
    allFileNames[0] = '\0';

    do {
        wcscat(allFileNames, filename); // wcscat是strcat的宽字符版。大家可以直接把*filename拿去用,例如放在一个vector里。我这里是连起来放在一个字符串里,方便显示
        wcscat(allFileNames, ",");
        filename = filename + (wcslen(filename) + 1); // wcslen是strlen的宽字符版
    } while (*filename);

到这里,我们就获得了allFileNames这个宽字符串!里面存储了用户选择的所有文件名的连接,用”,”隔开

二. 把WCHAR的allFileNames转换为char的c_allFileNames

char c_allFileNames[MAX_PATH * 100 * (sizeof(WCHAR)/sizeof(char))];

int ulBytes = WideCharToMultiByte(CP_ACP, 0, allFileNames, -1, NULL, 0, NULL, NULL); // 计算出allFileNames占用的多字节字符串长度为ulBytes
ulBytes = WideCharToMultiByte(CP_ACP, 0, allFileNames, -1, c_allFileNames, ulBytes, NULL, NULL); // 将宽字符字符串转换为多字节字符串

三. 把win32使用的多字节gbk字符串(char*)转换为cocos2d-x使用的多字节utf8字符串(char*)

http://www.tuicool.com/articles/juaeaiR
(大意是:cocos2dx有自带的iconv库,v3.8版本在external/win32-specific/icon下,找不到的搜索看看即可。需要添加头文件和库文件。文章中还封装了iconv_convert函数)

我这边就直接调用上文中封装的iconv_convert了:

    char outStr[1024];
    iconv_convert(&c_allFileNames, strlen(c_allFileNames), "GBK", &outStr, sizeof(outStr), "UTF-8");

    auto label = Label::createWithSystemFont(outStr, "宋体", 12);
  1. 中文字体显示乱码问题
    原本代码为:
auto label = Label::createWithTTF(name, "simsun.ttf", 14); 

显示的字体出现了乱码,而只要把代码改成:

auto label = Label::createWithTTF(name, "simsun.ttf", tabFontSize * 2);
label->setScale(0.5);

猜测原因可能是实际字体大小 = 14 / 设计分辨率 * 实际分辨率,而实际字体大小过小了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值