Class 在可重用MFC类中嵌入资源的正确方法是什么? 我正在编写一个C++(MFC特别)类,它使用一个外部.gif图像文件,并在处理之后生成另一个图像文件。如果初始图像能够以某种方式嵌入到代码中,那就太好了。我在MSDN上读到过关于使用多个.rc文件的内容,整个事情看起来相当复杂

Class 在可重用MFC类中嵌入资源的正确方法是什么? 我正在编写一个C++(MFC特别)类,它使用一个外部.gif图像文件,并在处理之后生成另一个图像文件。如果初始图像能够以某种方式嵌入到代码中,那就太好了。我在MSDN上读到过关于使用多个.rc文件的内容,整个事情看起来相当复杂,class,mfc,resource-files,Class,Mfc,Resource Files,我想从以前经历过这种情况的人那里知道如何处理这个问题 编辑:对不起,我不清楚。我正在编写的类应该是独立的,因此我可以再次使用它。如果我将图像放入资源文件中,则如果在新项目中使用,则该类将不会编译。在解决方案资源管理器中转到资源视图,右键单击并单击添加资源,然后单击导入并添加gif文件。现在,您可以使用资源ID访问代码中的gif文件。仅将文件添加到资源不会将文件嵌入实际的资源文件中,而只是链接到该文件。如果打开.rc文件,您将看到它显示如下内容: IDB_GIF_MYIMAGE GIF

我想从以前经历过这种情况的人那里知道如何处理这个问题


编辑:对不起,我不清楚。我正在编写的类应该是独立的,因此我可以再次使用它。如果我将图像放入资源文件中,则如果在新项目中使用,则该类将不会编译。

在解决方案资源管理器中转到资源视图,右键单击并单击添加资源,然后单击导入并添加gif文件。现在,您可以使用
资源ID
访问代码中的gif文件。

仅将文件添加到资源不会将文件嵌入实际的资源文件中,而只是链接到该文件。如果打开.rc文件,您将看到它显示如下内容:

IDB_GIF_MYIMAGE     GIF     "artwork\\mygif.gif"
在编译过程中,资源将包含在EXE中,您可以使用资源id
IDB\u GIF\u MYIMAGE
引用EXE。您可以在其他项目中引用同一文件,而无需复制该文件。

要在不使用资源文件的情况下将图像(或任何其他类型的二进制数据)嵌入到类中,请使用bin2c实用程序,例如,您可以从此处下载:。在一个文件上运行它将产生一个基本上是静态数组的文件字节作为该数组的成员。将该数组填充到一个.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

这将阻止类编译,直到用户正确导入图像。或者,您可以只使用“γIFFS”返回到不使用默认图像的代码,如果没有提供默认图像。

< P>不能在类或类似C++容器中嵌入MFC资源。它们只能嵌入到DLL或EXE文件中——在生成的二进制文件的单独部分中。因为您希望类是可重用的,所以必须将其放入DLL中。因此,必须用关键字标记类

有两种解决办法

解决方案#1:

  • 创建MFC DLL项目(
    MFC扩展DLL
    )。称它为MyLibrary
  • 将所有独立类放在此DLL中
  • 嵌入所有必要的资源
  • 让您的类从DLL的
    HINSTANCE
    加载资源,如下所述
有几种方法可以检索DLL的
HINSTANCE
。如果你问我,最好的解决办法是在
DllMain
中获取它。如果选择
MFC扩展DLL
配置,这将自动完成:

static AFX_EXTENSION_MODULE MyLibDLL = { NULL, NULL }; // Make this variable global!
// Then access the hInstance as follows:
LoadResource(MyLibDLL.hModule, ...)
解决方案#2:

将资源存储为字节缓冲区。或者更好,将其转换为并存储为ASCII字符串。但别忘了别把这堆东西炸了!在项目设置中保持资源较小或增加堆栈大小。例如:

const char *encodedResource = "SGVsbG8gd29ybGQh";
char *data = decode(encodedResource);
foo(data);

请查看中提供的CRuntimeDialog类。它提供了一种从构成资源定义的字符串创建对话框的方法。

您希望在运行时或编译时将第二个生成的文件嵌入到.exe中吗?在编译时,您始终可以将gif导入资源文件并在代码中使用它。在运行时,您无法真正做到这一点,唯一的方法是从磁盘读取它。您使用什么来读取gif?@MarkRansom:我正在使用CImage::Load()函数是的,但新项目将有自己的.rc文件,除非手动插入,否则不会包含该资源。据我所知,没有杂注允许您通过在.h或.cpp文件中指定资源来包含该资源。因此,除非您愿意修改.rc文件或按路径(而不是嵌入资源)加载图像,否则您唯一的选择是将图像作为文本包含,这将是一个难以管理的噩梦。我知道这种方法。我要寻找的是一种更干净、更实用的嵌入图像的方法。字节数组映像的AFAIK处理不是很方便。你说的“更干净、更实用”是什么意思?如果这种方法不能满足您的要求呢?您在问题中声明您不想将图像放入资源中,因为当您在另一个项目中包含类时,您需要#在资源部分包含其他资源。但您确实希望使用资源编辑器编辑或查看图像。你不能两全其美——要么把图像放在一个单独的资源文件中,并将其包含到每个项目的资源部分,要么把图像放在代码中,在这种情况下,你将无法使用资源编辑器来查看它。请问你选择了哪种解决方案?