locked
How to use app.ico from app.rc? RRS feed

  • Question

  • How would I pull the icon listed in my app.rc and use it as an Icon object? This is what I have now..

     

    Code Snippet

    System::Windows::Forms::NotifyIcon nIcon;

    nIcon.Icon = gcnew System::Drawing::Icon("app.ico");

     

    With "app.ico" being the icon file in my project's folder. However, if I wanted to distribute my program, this requires the user to have "app.ico" in the same folder as the executable and gives a nasty error message when my program looks for it and it's not there. I would like to just use the icon listed in app.rc and keep things a little more tidy (imo).

    This is the part of app.rc that I'm referring to...

    Code Snippet

    /////////////////////////////////////////////////////////////////////////////

    //

    // Icon

    //

    // Icon with lowest ID value placed first to ensure application icon

    // remains consistent on all systems.

    1 ICON "app.ico"

     

     

    How can I use this since its already in my program?

    Monday, June 11, 2007 5:03 PM

Answers

  • Ok, I found my answer. I had to use Assembly::GetManifestResourceStream() and Icon(Stream) constructor. Here's my code...

     

    Code Snippet

    this->nIcon.Icon = gcnew System::Drawing::Icon(System::Reflection::Assembly::GetExecutingAssembly()->GetManifestResourceStream("app.ico"));

     

    The trick is that app.ico needs to be an embedded resource.

    To embed a file, go to Project->[Project Name] Properties->Linker->Input->Embed Managed Resource File

    In that box, just type in the filename you need to embed. To make sure my file was embedded, I just wrote all of my resource names to a file... 

    Code Snippet

    for each(System::String ^name in System::Reflection::Assembly::GetExecutingAssembly()->GetManifestResourceNames()){

    System::IO::File::AppendAllText("names.txt", name + System::Environment::NewLine);

    }

     

    It lets you see what you can use for the Assembly::GetManifestResourceStream() method.

    Tuesday, June 12, 2007 10:59 PM

All replies

  • Took me about 10 seconds to find this page. And I don't even speak .NET.
    Monday, June 11, 2007 5:25 PM
  • Maybe I should try again...

     

    Is there a way to reference my own icon without having to look in the current directory? Since there's already a reference to "app.ico" in app.rc, can I just use that instead of giving the Icon constructor a path? Because if I use...

     

    Code Snippet

    System::Windows::Forms::NotifyIcon nIcon;

    nIcon.Icon = gcnew System::Drawing::Icon("app.ico");

     

    The constructor looks in the current directory for app.ico which forces me to bundle my program with app.ico and the program to crash if app.ico isn't found in the same directory as the executable. I'd like to avoid that and just simply use app.rc in some kind of way. I just don't know how to do that.

     

    Monday, June 11, 2007 8:04 PM
  • Maybe you want the type/resource name Icon constructor?
    Monday, June 11, 2007 9:07 PM
  • That may be just what I need, but I can't get it to work. The Icon(Type, String) constructors needs a Type, but I don't know which Type to give it. app.ico isn't tied to any single class in my project, so any combination of WallpaperChanger::AnyClass::typeid doesn't work (all of my classes are under my WallpaperChanger namespace). It throws an exception..

     

    ArgumentException was unhandled

    Resource 'app.ico' cannot be found in class 'WallpaperChanger.AnyClass'.

     

    Where AnyClass is any class I try from my WallpaperChanger namespace.
    Tuesday, June 12, 2007 4:24 PM
  • Did you try the exact syntax on the page (well, with your own icon name, of course)?
    Tuesday, June 12, 2007 5:01 PM
  • Yes. Here is my code...

     

    Code Snippet

    this->nIcon.Icon = gcnew System::Drawing::Icon(WallpaperChanger::SettingsForm::typeid, "app.ico");

     

    And I get the exception that I pasted earlier. No class that I try works.

    Tuesday, June 12, 2007 6:55 PM
  • Ok, I found my answer. I had to use Assembly::GetManifestResourceStream() and Icon(Stream) constructor. Here's my code...

     

    Code Snippet

    this->nIcon.Icon = gcnew System::Drawing::Icon(System::Reflection::Assembly::GetExecutingAssembly()->GetManifestResourceStream("app.ico"));

     

    The trick is that app.ico needs to be an embedded resource.

    To embed a file, go to Project->[Project Name] Properties->Linker->Input->Embed Managed Resource File

    In that box, just type in the filename you need to embed. To make sure my file was embedded, I just wrote all of my resource names to a file... 

    Code Snippet

    for each(System::String ^name in System::Reflection::Assembly::GetExecutingAssembly()->GetManifestResourceNames()){

    System::IO::File::AppendAllText("names.txt", name + System::Environment::NewLine);

    }

     

    It lets you see what you can use for the Assembly::GetManifestResourceStream() method.

    Tuesday, June 12, 2007 10:59 PM
  • That isn't the syntax on the page; that code uses "typeof(Control)".
    Wednesday, June 13, 2007 6:43 AM
  •  Sdi wrote:
    That isn't the syntax on the page; that code uses "typeof(Control)".

    typeof() is C# syntax. typeid() is C++ syntax. However, since I'm using managed objects, I must use Namespace::Class::typeid. So, my example is correct usage, I'm just looking in the wrong place for the wrong thing.

    Control in the case of the C# example is System::Windows::Forms::Control. The Control Type doesn't have my app.ico that I'm looking for - the example is useless.

    Although, I am curious as to what icons I pull from a Control and other types. The dotdotdot.ico example isn't working for me.
    Wednesday, June 13, 2007 2:38 PM