我正在编写一个 C++(特别是 MFC)类,它使用外部 .gif 图像文件并在经过一些处理后生成另一个图像文件。如果初始图像可以以某种方式嵌入到代码中,那就太好了。我在 MSDN 中阅读了有关使用多个 .rc 文件的信息,整个事情看起来相当复杂。
我想从经历过这个问题的人那里知道如何处理这个问题。
编辑:对不起,我不清楚。我正在编写的课程应该是独立的,所以我可以再次使用它。如果我将图像放在资源文件中,那么如果在新项目中使用该类将无法编译。
我正在编写一个 C++(特别是 MFC)类,它使用外部 .gif 图像文件并在经过一些处理后生成另一个图像文件。如果初始图像可以以某种方式嵌入到代码中,那就太好了。我在 MSDN 中阅读了有关使用多个 .rc 文件的信息,整个事情看起来相当复杂。
我想从经历过这个问题的人那里知道如何处理这个问题。
编辑:对不起,我不清楚。我正在编写的课程应该是独立的,所以我可以再次使用它。如果我将图像放在资源文件中,那么如果在新项目中使用该类将无法编译。
在解决方案资源管理器中,转到资源视图,右键单击并单击,Add Resource
然后单击Import
并添加 gif 文件。现在您可以使用您的Resource ID
来访问代码中的 gif 文件。
您不能将 MFC 资源嵌入到类或类似的 C++ 容器中。它们只能嵌入到 DLL 或 EXE 文件中——在生成的二进制文件的单独部分中。由于您希望您的类可重用,因此您必须将其放入 DLL 中。因此,您必须使用AFX_EXT_CLASS关键字标记您的类。
有两种解决方案。
解决方案#1:
MFC Extension DLL
)。叫它MyLibrary
什么的。HINSTANCE
您的 DLL 中加载资源,如下所述。有几种方法可以检索HINSTANCE
您的 DLL。如果你问我,最好的解决方案是抓住它DllMain
。如果您选择MFC Extension DLL
配置,这将自动完成:
static AFX_EXTENSION_MODULE MyLibDLL = { NULL, NULL }; // Make this variable global!
// Then access the hInstance as follows:
LoadResource(MyLibDLL.hModule, ...)
解决方案#2:
将您的资源存储为字节缓冲区。或者更好的是,将其转换为Base64并将其存储为 ASCII 字符串。但请记住不要炸毁堆栈!在项目设置中保持资源较小或增加堆栈大小。例子:
const char *encodedResource = "SGVsbG8gd29ybGQh";
char *data = decode(encodedResource);
foo(data);
只是将文件添加到资源中不会将该文件嵌入到实际资源文件中,它只是链接到该文件。如果你打开你的 .rc 文件,你会看到它说:
IDB_GIF_MYIMAGE GIF "artwork\\mygif.gif"
在编译过程中,资源将包含在 EXE 中,您使用资源 id 引用它IDB_GIF_MYIMAGE
。您可以在其他项目中引用相同的文件,而无需复制该文件。
要在不使用资源文件的情况下将图像(或任何其他类型的二进制数据)嵌入到您的类中,请使用 bin2c 实用程序,例如,您可以从此处下载它:http ://www.opensource.apple.com/source/libpcap /libpcap-16/libpcap/msdos/bin2c.c。在文件上运行它会产生基本上是一个静态数组,其中文件的字节作为该数组的成员。将此数组填充到 .h 文件中(或将其放在类的标题中,或使其成为静态成员...),然后您将在内存中使用该文件,而无需使用 LoadResource() 及其兄弟.
如果您想将它与 CImage::Load() 一起使用,您将必须编写自己的从 IStream 派生的类,并以某种方式实现一些方法,以便它们从内存中“读取”。我不知道有什么方法可以让 CImage 从 gif 文件的内存表示中解码图像。
我认为最好的解决方案就是记录要使用该类,您还必须将某个 .gif 文件导入到您的项目中,并给它一个特定的预期标识符(例如 IDB_MYCLASS_MYGIF)。然后,您可以使用预处理器来检测资源是否已正确添加,例如:
#ifndef IDB_MYCLASS_MYGIF
#error Make sure you import mygif.gif to the project. See docs for more info.
#endif
这将阻止类编译,直到用户正确导入图像。或者,如果未提供默认图像,您可以只使用 #ifdefs 回退到不使用默认图像的代码。
查看http://www.codeproject.com/Articles/5371/ToDoList-6-5-4-Feature-Release-An-effective-and-fl中提供的 CRuntimeDialog 类。它提供了一种从构成资源定义的字符串创建对话框的方法。