views:

344

answers:

1

I have a C++/CLI GUI application and I want to display an image as a visual aid for the user to see what step in a procedure they're at. This image will need to be changed each time the user selects the new step.

Currently I'm using a picture box and have an image loaded from the disk at run time. So there are a few things I need to know here:

  1. Is a picture box the best thing to use for this purpose or is there another control that would better suit?
  2. How do embed the images in the executable and load them from there instead of a file that exists on disk.
  3. How do I load a new image (I'm guessing that this will be fairly obvois if I can crack point 2)?

I've seen a few answers which relate to C# but I've not seen anything which looks like it translates to doing things in a C++/CLI app. Any suggestions would be very welcome.

A: 

Well it may not be the best solution, but the following works.

Create a new Windows Forms Application

Add these libraries to your linker settings (Project Proerties -> Link -> Input -> Additional Dependencies):

User32.lib Gdi32.lib

Add these headers:

#include <windows.h>
#include "resource.h"

Add these namespaces:

using namespace System::Reflection;
using namespace System::Runtime::InteropServices;

Add a pair of bitmaps to your resources and call them IDB_BITMAP1 and IDB_BITMAP2.

Add a picture box called m_pictureBox1.

Add a button and double-click the button to add an on-click handler:

System::Void button1_Click(System::Object^  sender, System::EventArgs^  e)
{
    // Remove any previously stored images
    if(m_pictureBox1->Image != nullptr)
    {
        delete m_pictureBox1->Image;
    }

    // Pick a new bitmap
    static int resource = IDB_BITMAP1;
    if( resource == IDB_BITMAP2)
    {
        resource = IDB_BITMAP1;
    }
    else
    {
        resource = IDB_BITMAP2;
    }

    // Get the primary module
    Module^ mod = Assembly::GetExecutingAssembly()->GetModules()[0];

    // Get the instance handle 
    IntPtr hinst = Marshal::GetHINSTANCE(mod);

    // Get the bitmap as unmanaged
    HANDLE hbi = LoadImage((HINSTANCE) hinst.ToPointer(),MAKEINTRESOURCE(resource),IMAGE_BITMAP,0,0,LR_DEFAULTCOLOR); 

    // import the unmanaged bitmap into the managed side 
    Bitmap^ bi = Bitmap::FromHbitmap(IntPtr(hbi));

    // insert the bitmap into the picture box
    m_pictureBox1->Image = bi;

    // Free up the unmanaged bitmap
    DeleteObject(hbi);

    // Free up the instance and module
    delete hinst;
    delete mod;
}

..et voila the bitmaps are stored neatly in you app and each time you click the button the images will swap.

Jon Cage