【问题标题】:Why can't I load an image resource from my resx file?为什么我不能从我的 resx 文件中加载图像资源?
【发布时间】:2010-07-19 15:27:45
【问题描述】:

我有一个控件库,已将 .resx 文件添加到 (ImageResources.resx)。它包含两个我随后添加的 .png 图像。

在同一个库中,我有一个控件可以加载几个图像来进行一些自定义绘图,但我似乎无法加载资源:

void GTableLayoutPanel::SetBorderImagesFromManifest(String^ topLeftCornerImageName, String^ topImageName)
{
    // Grab the assembly this is being called from
    Assembly^ assembly = Assembly::GetExecutingAssembly();

    // Grab the images from the assembly
    Stream^ stream = assembly->GetManifestResourceStream(topLeftCornerImageName);
    Image^ topLeftImage = System::Drawing::Image::FromStream(stream);
    stream = assembly->GetManifestResourceStream(topImageName);
    Image^ topImage = System::Drawing::Image::FromStream(stream);

    // Update the internal store from the supplied images
    SetBorderImages(topLeftImage, topImage);
}

...给我报错,抱怨 stream 为 null,这表明我对 GetManifestResourceStream 的调用失败。

图像被称为group_box_top.pnggroup_box_top_left.png,我调用图像加载器如下:

SetBorderImagesFromManifest("group_box_top_left.png", "group_box_top.png");

我也试过了:

SetBorderImagesFromManifest("group_box_top_left", "group_box_top");

...因为文件出现在没有 .png 扩展名的 .resx 文件中,但这会产生相同的错误。

我在这里错过了一步吗?

[编辑]我尝试了最后一个链接中的建议,我得到:

MyControlsLib.ImageResources.resources

所以现在我尝试引用:

Stream^ strm1 = assembly->GetManifestResourceStream("MyControlsLib.ImageResources.resources.group_box_top_left");
Stream^ strm2 = assembly->GetManifestResourceStream("MyControlsLib.ImageResources.resources.group_box_top_left.png");
Stream^ strm3 = assembly->GetManifestResourceStream("MyControlsLib.ImageResources.group_box_top_left");
Stream^ strm4 = assembly->GetManifestResourceStream("MyControlsLib.ImageResources.group_box_top_left.png");

...所有这些都返回 nullptr :-/

【问题讨论】:

  • 不要尝试我的确切建议 - 我不确定您是否需要 ImageResources 部分,并且可能仍需要包含扩展名。使用关于获取姓名的问题中的代码来获取真实姓名并替换代码中的姓名。另外,我会评论人们的回答,因为我没有收到有关您的问题的任何通知。
  • 查看您的答案的评论..
  • 嗯,对,那么不确定 - 问题可能是限定名称,但我不确定这如何适用于 C++.NET

标签: .net resources c++-cli manifest resx


【解决方案1】:

我终于得到了 C++/CLI 解决方案的神奇组合。所以以防万一其他人有这个问题:

方法一(通过.resx文件)

  1. 添加图像文件(我使用的是 .png,但位图等也可以)。
  2. 添加资源文件:
    1. 转到解决方案资源管理器。
    2. 在您要添加到的项目中右键单击Resource Files
    3. 选择Add > New Item..
    4. 选择Visual C++ > Resource > Assembly Resource File (.resx)。我将我的命名为“ImageResources.resx”
  3. 添加图片:
    1. 在解决方案资源管理器中双击“ImageResources.resx”
    2. 点击Add Resource按钮并选择Add Existing File...
    3. 选择要嵌入的图像。我添加了group_box_top.pnggroup_box_top_left.png,它们在.resx 文件中显示为group_box_topgroup_box_top_left

然后,您可以使用以下命令从清单中获取图像:

// Grab the assembly this is being called from
Assembly^ assembly = Assembly::GetExecutingAssembly();
AssemblyName^ assemblyName = assembly->GetName();

// Grab the images from the assembly
ResourceManager^ rm = gcnew ResourceManager(assemblyName->Name+".ImageResources", assembly);
Bitmap^ topLeftImage = (Bitmap^)rm->GetObject("group_box_top_left");
Bitmap^ topImage = (Bitmap^)rm->GetObject("group_box_top");

请注意,传递给ResourceManager 构造函数的ImageResources 字符串必须与您的.resx 文件的名称匹配。

方法2(通过链接器)

  1. 添加文件:
    1. 右键单击您的项目
    2. 转到Linker -> Input
    3. 将要嵌入的文件添加到Embed Managed Resource File 属性。我在这里添加了PingSend.wav

要访问文件,只需执行以下操作:

System::Reflection::Assembly^ assembly = Assembly::GetExecutingAssembly();
System::Media::Sonudplayer^ pingPlayer = gcnew System::Media::SoundPlayer(assembly->GetManifestResourceStream("PingSend.wav"));

..在这种情况下,加载准备播放的音频文件。

【讨论】:

    【解决方案2】:

    我认为资源项的路径可能需要完全限定:

    GetManifestResourceStream("MyNamespace.ImageResources.group_box_top_left")
    

    此链接显示了一个 C# 示例(抱歉),请注意在创建流时它在参数中包含命名空间:

    http://support.microsoft.com/kb/319292

    这还涉及如何找到资源的完全限定路径:

    How can I discover the "path" of an embedded resource?

    【讨论】:

    • 确实使用了您链接的问题中的代码,根据我的编辑它给了我MyControlsLib.ImageResources.resources..
    • +1:感谢您的建议。它们都没有奏效,但它至少让我走上了正确的道路。
    【解决方案3】:
    System::Reflection::Assembly^ assembly = System::Reflection::Assembly::GetExecutingAssembly();
    
    Resources::ResourceManager^ rm = gcnew Resources::ResourceManager("namespaceName" + ".ResourceFileName", assembly);
    
    this->button->Image = cli::safe_cast<Image^>(rm->GetObject("image1"));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-18
      • 1970-01-01
      • 2011-04-09
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      相关资源
      最近更新 更多