在可重用MFC类中嵌入资源的正确方法是什么



我正在编写一个C++(特别是MFC)类,该类使用外部.gif图像文件,并在经过一些处理后生成另一个图像文件。如果初始图像能够以某种方式嵌入到代码中,那就太好了。我在MSDN上读过关于使用多个.rc文件的文章,整个过程看起来相当复杂。

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

编辑:很抱歉我不清楚。我正在编写的类应该是独立的,所以我可以再次使用它。如果我将图像放在资源文件中,那么如果在新项目中使用该类,则该类将不会编译。

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

有两种解决方案。

解决方案#1:

  • 创建MFC DLL项目(MFC Extension DLL)。称之为MyLibrary或其他什么
  • 将所有独立类放入此DLL中
  • 嵌入所有必要的资源
  • 让您的类从DLL的HINSTANCE加载资源,如下所述

有几种方法可以检索DLL的HINSTANCE。如果你问我,最好的解决方案是在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);

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

仅仅将文件添加到资源中并不会将文件嵌入到实际的资源文件中,它只是链接到该文件。如果你打开你的.rc文件,你会看到上面写着:

IDB_GIF_MYIMAGE     GIF     "artwork\mygif.gif"

在编译过程中,资源将包含在EXE中,您可以使用资源id IDB_GIF_MYIMAGE引用EXE。您可以在其他项目中引用同一个文件,而不必复制该文件。

要在不使用资源文件的情况下将图像(或任何其他类型的二进制数据)嵌入到类中,请使用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返回到不使用默认图像的代码(如果没有提供)。

查看中提供的CRuntimeDialog类http://www.codeproject.com/Articles/5371/ToDoList-6-5-4-Feature-Release-An-effective-and-fl。它提供了一种从组成资源定义的字符串创建对话框的方法。

相关内容

最新更新