【发布时间】:2017-05-13 18:06:01
【问题描述】:
我只是想知道,Windows 中是否有用于从字节数组(缓冲区)加载HICON 的 API?假设我下载了一个*.ico 文件,并且我在某个缓冲区中有这个文件的内容。我希望能够从该缓冲区创建HICON。
可以从位于硬盘驱动器上的*.ico 加载HICON,所以我想应该有一个同样简单的方法可以从内存缓冲区中加载它?
到目前为止,我只找到了 2 个解决方案,但没有一个适合我。
第一个involved ATL usage and GDI+(我正在使用 Rust,我没有任何与 GDI+ 的绑定)。
第二个是基于LookupIconIdFromDirectoryEx() 和CreateIconFromResourceEx() 的使用。首先我调用LookupIconIdFromDirectoryEx() 来获取正确图标的偏移量,然后我尝试调用CreateIconFromResourceEx()(和CreateIconFromResource())来获取HICON,但在所有情况下我都会收到NULL 值作为结果,@ 987654337@ 虽然返回 0。我对这些函数的使用基于this article(我尝试不仅传递0 作为第二个参数,还传递数组缓冲区的大小,不包括偏移量,但仍然失败)。
我想到的唯一剩下的解决方案是手动解析*.ico文件,然后从中提取PNG图像,然后使用here描述的方法从PNG图像创建一个图标。但这似乎更像是一种解决方法(Qt 使用类似的方法,也许他们无法找到不同的解决方案)。有没有更简单的方法(可能是一些 WinAPI 调用)来完成任务?
UPD。这是我尝试过的一些测试代码(您应该有一个图标,以便在不崩溃的情况下运行示例)。
#include <cstdio>
#include <cstdlib>
#include <Windows.h>
#pragma comment(lib, "User32.lib")
int main()
{
// Read the icon into the memory
FILE* f = fopen("icon.ico", "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET);
char* data = (char*)malloc(fsize + 1);
fread(data, fsize, 1, f);
fclose(f);
static const int icon_size = 32;
int offset = LookupIconIdFromDirectoryEx((PBYTE)data, TRUE, icon_size, icon_size, LR_DEFAULTCOLOR);
if (offset != 0) {
HICON hicon = CreateIconFromResourceEx((PBYTE)data + offset, 0, TRUE, 0x30000, icon_size, icon_size, LR_DEFAULTCOLOR);
if (hicon != NULL) {
printf("SUCCESS");
return 0;
}
}
printf("FAIL %d", GetLastError());
return 1;
}
【问题讨论】:
-
看起来您的代码中存在错误。除非您提供minimal reproducible example,否则我们无法为您提供帮助。
-
修复代码而不是放弃
-
@IInspectable,我最初没有添加它,因为它与我链接的文章中的基本相同。但现在我更新了描述并附上了源代码。在我的情况下,它总是打印“FAIL 0”。
-
@DavidHeffernan 我很乐意修复它,我尝试了几种不同的方案,但它仍然不起作用,这就是我决定问的原因。我刚刚附上了我尝试使用的代码,不幸的是它总是失败。
-
这不是minimal reproducible example。它缺少输入。如果无法上传图标,请在代码中添加一个静态数组,初始化为出现错误的最小图标。同时,您可以仔细检查,您的图标确实包含 32x32 图像。