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
St开发者_运维百科ream^ 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:
Method 1 (via .resx file)
- Add the image files (I used .pngs, but bitmaps etc. work too).
- Add a resource file:
- Go to Solution Explorer.
- Right-click on
Resource Files
in the project you're adding to - Select
Add
>New Item..
- Choose
Visual C++
>Resource
>Assembly Resource File (.resx)
. I nameed mine "ImageResources.resx"
- Add the images:
- Double click on "ImageResources.resx" in Solution Explorer
- Click on the
Add Resource
button and selectAdd Existing File...
- Select the images you want to embed. I added
group_box_top.png
andgroup_box_top_left.png
which appear in the .resx file asgroup_box_top
andgroup_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.
Method 2 (via linker)
- Add the files:
- Right-click on your project
- Go to
Linker
->Input
- Add the files you want to embed to the
Embed Managed Resource File
property. I addedPingSend.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.
I think the path to the resource item might need to be fully qualified:
GetManifestResourceStream("MyNamespace.ImageResources.group_box_top_left")
This link shows a C# example (sorry), notice when creating the stream it has the namespace in the arguments:
http://support.microsoft.com/kb/319292
This also goes onto how to find the fully qualified path to a resource:
How can I discover the "path" of an embedded resource?
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"));
精彩评论