I have a controls library which I've added a .resx file to (ImageResources.resx). It contains two .png images which I subsequently added.
In that same library I have a control which loads a couple of images to do some custom drawing, but I don't seem to be able to load the resources:
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);
}
...gives me errors complaining that stream
is null which suggests my call to GetManifestResourceStream
is failing.
The images are called group_box_top.png
and group_box_top_left.png
and I'm calling the image loader as follows:
SetBorderImagesFromManifest("group_box_top_left.png", "group_box_top.png");
I've also tried:
SetBorderImagesFromManifest("group_box_top_left", "group_box_top");
...because the files appear in the .resx file without the .png extensions, but this gives the same error.
Have I missed a step here?
[Edit] I tried the suggestion in that final link and I get:
MyControlsLib.ImageResources.resources
So now I've tried referencing:
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");
...all of which return nullptr :-/
I finally got the magic combination for a C++/CLI solution. So just in case anyone else has this issue:
Resource Files
in the project you're adding toAdd
> New Item..
Visual C++
> Resource
> Assembly Resource File (.resx)
. I nameed mine "ImageResources.resx"Add Resource
button and select Add Existing File...
group_box_top.png
and group_box_top_left.png
which appear in the .resx file as group_box_top
and group_box_top_left
.You can then grab the images from the manifest with:
// 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");
Note that the ImageResources
string passed into the ResourceManager
constructor must match the name of your .resx file.
Linker
-> Input
Embed Managed Resource File
property. I added PingSend.wav
here.To get access to the files simply do:
System::Reflection::Assembly^ assembly = Assembly::GetExecutingAssembly();
System::Media::Sonudplayer^ pingPlayer = gcnew System::Media::SoundPlayer(assembly->GetManifestResourceStream("PingSend.wav"));
..which in this case, loads the audio file ready to play back.