ImGui 学习笔记(五) —— 字体文件加载问题

embedded/2025/3/18 12:27:11/

ImGui 加载字体文件的函数似乎存在编码问题,这一点可能跟源文件的编码也有关系,我目前源文件编码是 UTF-16。

当参数中包含中文字符时,ImGui 内部将字符转换为宽字符字符集时候,采用的 MultiByteToWideChar API 参数不太对,应该改为 CP_ACP 才对,原本它使用的是 CP_UTF8。

函数位于 imgui.cpp :

ImFileHandle ImFileOpen(const char* filename, const char* mode)
{
#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && (defined(__MINGW32__) || (!defined(__CYGWIN__) && !defined(__GNUC__)))// We need a fopen() wrapper because MSVC/Windows fopen doesn't handle UTF-8 filenames.// Previously we used ImTextCountCharsFromUtf8/ImTextStrFromUtf8 here but we now need to support ImWchar16 and ImWchar32!const int filename_wsize = ::MultiByteToWideChar(CP_ACP, 0, filename, -1, NULL, 0);const int mode_wsize = ::MultiByteToWideChar(CP_ACP, 0, mode, -1, NULL, 0);// Use stack buffer if possible, otherwise heap buffer. Sizes include zero terminator.// We don't rely on current ImGuiContext as this is implied to be a helper function which doesn't depend on it (see #7314).wchar_t local_temp_stack[FILENAME_MAX];ImVector<wchar_t> local_temp_heap;if (filename_wsize + mode_wsize > IM_ARRAYSIZE(local_temp_stack))local_temp_heap.resize(filename_wsize + mode_wsize);wchar_t* filename_wbuf = local_temp_heap.Data ? local_temp_heap.Data : local_temp_stack;wchar_t* mode_wbuf = filename_wbuf + filename_wsize;::MultiByteToWideChar(CP_ACP, 0, filename, -1, filename_wbuf, filename_wsize);::MultiByteToWideChar(CP_ACP, 0, mode, -1, mode_wbuf, mode_wsize);DBGPRINT(L"FileOpen Path: %s", filename_wbuf);return ::_wfopen(filename_wbuf, mode_wbuf);
#elsereturn fopen(filename, mode);
#endif

修改前,字体加载失败,然后我发现它处理相对路径的方式也不好。改用完整路径后也还是一样失败:

输出更多信息看看:
 

明显路径中中文编码出现了乱码 ?????。

按照上面方法修改后,你可能会在 Read 失败。继续看,发现这里可能有问题:
void*   ImFileLoadToMemory(const char* filename, const char* mode, size_t* out_file_size, int padding_bytes)

找到 ImFileRead(file_data, 1, file_size, f) 他直接写在条件里面的,我们把他改成两步:

size_t ret_size = ImFileRead(file_data, 1, file_size, f);
if (ret_size != file_size)
{ImFileClose(f);IM_FREE(file_data);return NULL;
}

最后,再次尝试:
 

绝对路径(加载字体文件)已经没有问题了;如果用相对路径则还有问题,并且可能与访问权限有关系。

我注入的程序在 C:\Windows\ 下,这里创建 imgui.ini 默认的配置文件失败。这个好解决,在加载函数前面加上一些路径检查和转换的代码,比如转为绝对路径(程序目录+文件名),然后检查权限,权限不够就改用 COM 或者提权(我这里不考虑跨平台,所以没关系,如果考虑跨平台,可能需要更多修改)。


http://www.ppmy.cn/embedded/173591.html

相关文章

处理变长的时间序列

pytorch中torch.nn.utils.rnn相关sequence的pad和pack操作 官网…torch.nn.utils.rnn.pack_padded_sequence 知乎pack_padded_sequence 和 pad_packed_sequence 结论 ✅ pack_padded_sequence 是最好的方法&#xff08;避免无效计算&#xff0c;提升性能&#xff09; &#x…

java 动态赋值写入word模板

最近工作中&#xff0c;客户给提供了word模板&#xff0c;要求动态赋值到word模板中&#xff0c;查阅相关资料&#xff0c;最终完成了需求&#xff0c;希望也可以帮助到大家&#xff01; 例如表格如下&#xff1a; 第一步&#xff1a;在word模板中&#xff0c;把需要动态赋值的…

ThreadLocal

多线程和 ThreadLocal 是 Java 并发编程中的两个重要概念&#xff0c;它们在处理线程安全和资源隔离时扮演关键角色。 1. 多线程基础 1.1 什么是多线程&#xff1f; 线程&#xff1a;是操作系统能够调度的最小执行单元&#xff0c;一个进程可以包含多个线程。 多线程&#xf…

高亮动态物体——前景提取与动态物体检测器(opencv实现)

目录 代码说明 1. 导入库 2. 创建背景建模对象 3. 打开视频源 4. 逐帧处理视频 5. 应用背景建模获得前景掩码 6. 形态学操作去除噪声 6.1 定义形态学核 6.2 开运算去除噪点 6.3 膨胀操作填补前景区域空洞 7. 轮廓检测识别动态物体 8. 绘制轮廓和边界框 9. 显示处理…

Spring Boot 的自动装配

Spring Boot 的自动装配&#xff08;Auto Configuration&#xff09;是其核心特性之一&#xff0c;通过智能化的条件判断和配置加载机制&#xff0c;极大简化了传统 Spring 应用的配置复杂度。其原理和实现过程可概括为以下几个关键点&#xff1a; 一、核心触发机制&#xff1a…

HarmonyOS第26天:应用发布与推广全攻略:从0到1走向市场

一、引言:开启 HarmonyOS 应用之旅 在数字化时代的浪潮中,HarmonyOS 以其独特的分布式理念和强大的跨设备协同能力,为应用开发领域开辟了一片崭新的天地。随着 HarmonyOS 市场份额的稳步增长,其生态设备数量已突破 9 亿大关,吸引了超过 254 万开发者投身其中 ,成为了开发…

【操作系统安全】任务6:Linux 系统文件与文件系统安全 学习指南

目录 一、文件系统基础概念 二、查看文件系统信息 2.1 磁盘空间查看 2.2 分区与挂载管理 2.3 文件系统类型操作 三、文件系统权限配置 3.1 基础权限管理 3.2 所有权管理 3.3 特殊权限设置 四、文件操作基础 4.1 文件创建 4.2 文件删除 4.3 文件复制与移动 4.4 文件…

Python游戏开发自学指南:从入门到实践(第四天)

Python不仅适用于数据分析、Web开发和自动化脚本&#xff0c;还可以用于游戏开发&#xff01;虽然Python不是传统意义上的游戏开发语言&#xff0c;但其简洁的语法和丰富的库使其成为初学者学习游戏开发的绝佳选择。本文将为你提供一份全面的Python游戏开发自学指南&#xff0c…