Click here to Skip to main content
Email Password   helpLost your password?

Introduction

This is a very brief note on associating a bitmap image with a component or user control from a Managed C++ project. The C# technique is more straightforward and is already documented in the standard help. Doing this in C++ is initially a pain, because there are few (if any) sample projects around, that do this. It took me quite a while to find a post on one of the newsgroups that provided the solution. Once you know what to look for, you'll find the right posts, so the idea of this article is just to provide a quick hit for people searching on ToolboxBitmap.

Aim

Write a Managed C++ component (i.e. derived from System::ComponentModel::Component) or some variation of user control that has a customized toolbox bitmap associated with it. The bitmap should be embedded as a resource (not specified in a run-time distributed file).

Steps

  1. Write the component and design a 16*16 bitmap.

  2. Add the bitmap

    The bitmap must be added as an embedded resource. (Various posts on the newsgroups describe using .resx files - I couldn't get this to work).

    1. Make sure the 16*16 bitmap is in the project directory.
    2. Make sure the bitmap is named as follows:
      Namespace.ClassName.bmp

      The .NET framework relies on this naming convention to find your resource when displaying the bitmap on the toolbox.

    3. Add the bitmap to the project as follows:
      1. Go to the project settings property pages.
      2. Go to the Linker\Input settings page.
      3. Select "Embed Managed Resource File" and enter the name of your bitmap.
  3. Associate the bitmap with the class

    You need to add ToolboxBitmap attribute to your class. For example, if you have the following class:

    __gc public class Port : public System:: System::ComponentModel::Component

    ...add the attribute as follows:

    [ToolboxBitmap(__typeof(Port))]
    __gc public class Port : public System:: System::ComponentModel::Component

    You must also forward declare the class, otherwise the compiler will fail. E.g.:

    __gc public class Port;
    [ToolboxBitmap(__typeof(Port))]
    __gc public class Port : public System:: System::ComponentModel::Component

    The ToolboxBitmap attribute resides in the System::Drawing namespace, so you may need to add a using clause at the top of the file. E.g.:

    using namespace System::Drawing;

    That's it. You can now build the project.

  4. Adding to the toolbox

    Once the project is built, close the solution. Then, on the Toolbox right-click and select Add/Remove Items. On the .NET Framework Components page, select Browse and find your DLL assembly. Select it, and close the Customize Toolbox dialog. A greyed-out image of your component will appear on the toolbox list. If a greyed out 'cog' is shown, it means that the framework has failed to find your image (see diagnostics below). Otherwise, your component is ready for dragging-and-dropping.

  5. Diagnostics

    If you find that the icon does not show correctly on the toolbar, there is a quick way to determine if it is visible from your assembly.

    1. Run ILDASM (on my machine this is: C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\ildasm.exe).
    2. From the menu, open your assembly.
    3. Double-click the MANIFEST item - a new window will pop-up.
    4. You should now try to find your bitmap. For example, one of mine appears as:
      .mresource public CDS.ParallelPortDrv.Port.bmp
      {
      }
    5. You will hopefully be able to determine what the problem is, from here. For example, if no bitmap resource is listed, it means that the bitmap was not correctly embedded as a managed resource. If the bitmap exists, you should be able to verify that the naming convention is correct. Remember that, all namespaces must be used followed by the class name, followed by ".bmp".
You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
QuestionHow to use ToolboxBitmapAtributu in C#
chinhlovephuoc
21:07 15 Apr '09  
I created a project : WindowsApplication1 and a UserControl : UserControl1. When I use ToolboxBitmap to set image for control in Toolbox but It didn't display.
WindowsApplication1.Bitmap1.bmp : I set Build Action property = Embedded Resource

namespace WindowsApplication1
{
ToolboxBitmap(typeof(WindowsApplication1.UserControl1), "WindowsApplication1.Bitmap1.bmp")]
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
}
}
GeneralDesign-time and run-time separation
Edward Diener
15:54 31 Oct '04  
How can I have the ToolboxBitmap embedded in a design-time assembly and refer to it in a run-time assembly without referencing the design-time assembly in the run-time assembly ? I want my design-time assembly referencing my run-time assembly but not vice-versa. This will enable the end-programmer to distribute my run-time assembly for run-time execution without having to distribute my design-time assembly when it is not needed. Can one forward declare the class in the design-time assembly and apply the ToolboxBitmapAttribute to this forward declaration ?

Edward Diener
GeneralSimpler Method
Libertadrian
17:33 25 Sep '04  
D'Oh! There is no need to worry about mangling the filename, or adding the bitmap manually to the Linker/Input/Embed Manager Resource File project setting.

Instead, simply add a standard 16x16 resource bitmap to your project's .RC and refer to it in the source as it follows:

public __gc class MyControl;

[ToolboxBitmap(__typeof(MyControl), "IDB_MYCONTROL")]
public __gc class MyControl: public ...

Where "IDB_MYCONTROL" is the name given to the resource bitmap.

Works for me! Cool

Libertadrian

"Give me freedom, or give me death"
GeneralRe: Simpler Method
ossamaosos
5:51 11 Jul '05  
First I was excited when I found the solution in this article OMG . Then I got much more excited when read ur reply. Many thanx Cool
GeneralRe: Simpler Method
ossamaosos
6:02 11 Jul '05  
It didn't work!!! Confused
I wrote my previous reply before testing ur method!

Can u write ur method in more details
GeneralOne way to add a bitmap as an embedded resource.
George L. Jackson
9:05 13 Nov '03  
First, I create a console application, 'EXE.exe', to create the .resources file and a class library, 'AssemblyName.dll'. I make the class library dependent on the console application.

In the console application's project property page, I set 'Build Events/Post-Build Event/Command Line' to '$(OutDir)\$(ProjectName).exe "..\AssemblyName\AssemblyName.resources"'

EXE.exe:

...
using namespace System;
using namespace System::Resources;
using namespace System::Drawing;
...
String* args[] = Environment::GetCommandLineArgs[];
...
FileInfo* fi = new FileInfo(args[1]);
...
ResourceWriter* rw = new ResourceWriter(fi->FullName);
...
FileInfo* fiRsrc = new FileInfo(S"Path\\img.jpg");
if (fiRsrc->Exists) rw->AddResource(S"img_jpg", Image::FromFile(fiRsrc->FullName));

rw->AddResource(S"greeting", S"Hello");
...
rw->Close();

Compile the project. If everything is okay, it will create a .resources file in your class library's project directory. I usually add this .resources file to the class library's project since I use Visual SourceSafe. Next, I go to the class library's project property page and set 'Linker/Input/Embed Managed Resource File' to 'AssemblyName.resources'. Now you can access your embedded resources from MC++.

AssemblyName.dll:

...
using namespace System;
using namespace System::Reflection;
using namespace System::Resources;
using namespace System::Drawing;
...
ResourceManager* rmgr = new ResourceManager(S"AssemblyName", Assembly::GetExecutingAssembly());
Image* img_jpg = dynamic_cast<Image*>(rmgr->GetObject(S"img_jpg");
String* greeting = rgmr->GetString(S"greeting");
...

This is not painless but it works!
GeneralRe: One way to add a bitmap as an embedded resource.
Libertadrian
17:39 25 Sep '04  
Mmmhh.. That sounds like a bazooka for a mosquito!!! Laugh

"Give me freedom or give me death"
GeneralNoogle
Normski
5:27 7 Nov '03  
That's one scary picture dude! Wink

GeneralRe: Noogle
Noogle
10:57 7 Nov '03  
Sometimes the pain of programming just gets to me... Cry

MS didn't intend some things to be done from MC++.. keeps it interesting tho... Laugh


GeneralRe: Noogle
Normski
22:43 7 Nov '03  
Noogle wrote: MS didn't intend some things to be done from MC++..
Yep! and looks like MC++ is all set to change in the next coming of VS.net, I think I'll hold of MC++ programming until the get the architecture right.


I am that is



Last Updated 7 Nov 2003 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010