6

I've read a lot about how to add an icon to an application built with Visual Studio, but I have no idea how to do this with Eclipse Galileo / C / MinGW.

Can anyone write a description, or give me a link ta a description ?

Marcus Tik
  • 1,709
  • 6
  • 20
  • 30

4 Answers4

15

In Windows, the icons as well as some other elements (cursors, bitmaps, ...) have to be specified in a resource file, which once compiled will be linked to the program.

First an example on how to add an icon to a Windows program which will illustrate it's use within Eclipse. Here is a simple program that just creates a window, look at the time we fill the WNDCLASSEX, the icon of the application is referenced there:

resources.h - this file may be used to assign a value to a resource identifier, and so use the value instead:

#define AppIcon 101

The next file is the resources file, you may create it manually or from within Eclipse as well, to create it in Eclipse, right click the directory you want it to be (in this case is src) and select New -> File. There write the name you want and click Finish. To edit it from within Eclipse right click it and select Open with -> Text Editor.

resources.rc - the icon will be specified here:

#include "resources.h"

// The icon path I used will be needed by Eclipse.
// If you want to use back-slashes you have to scape them (\\ instead of \):
AppIcon ICON "../src/icon.ico"

demoicon.c - the file containing the code of the program:

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

const char *ClassName = "DemoIcon";

// Declaration of the window procedure, to be used in the WNDCLASSEX struct:
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nShowCmd) {

    WNDCLASSEX wc;
    HWND hWnd;
    MSG msg;

    // Filling the structure:
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = 0;
    wc.lpfnWndProc = WindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    // Remember this just loads 32x32, use LoadImage() instead for other dimensions (16x16, 48x48, ...):
    wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(AppIcon));
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = ClassName;
    // Here we'll use LoadImage, as we need a 16x16 mini icon:
    wc.hIconSm = LoadImage(hInstance,MAKEINTRESOURCE(AppIcon),IMAGE_ICON,16,16, LR_DEFAULTCOLOR);

    // Registering the class:
    if(!RegisterClassEx(&wc)) {
        MessageBox(NULL,
                   "Could not register window.",
                   "Error",
                   MB_ICONEXCLAMATION | MB_OK);
        return -1;
    }

    // Create the window using the "MainWindow" class:
    hWnd = CreateWindowEx(WS_EX_WINDOWEDGE,
                          ClassName,
                          "Demo Icon",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT,
                          CW_USEDEFAULT,
                          200,
                          150,
                          NULL,
                          NULL,
                          hInstance,
                          NULL);

    // If the window was not created show error and exit:
    if(hWnd == NULL) {
        MessageBox(NULL,
                   "Could not create window.",
                   "Error",
                   MB_ICONEXCLAMATION | MB_OK);
        return -1;
    }

    // Set the windows show state, to show it:
    ShowWindow(hWnd, nShowCmd);
    // Draw the window:
    UpdateWindow(hWnd);

    // Retrieve messages from the message queue:
    while(GetMessage(&msg, NULL, 0, 0) > 0) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

// Implementation of the window procedure, will handle the messages:
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {

    switch(uMsg) {
        case WM_CLOSE:
            DestroyWindow(hWnd);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }

    return 0;
}

Now, in your Eclipse project source directory make sure you have all the files (in the example the 3 files mentioned before and the icon file).

After that go to Project -> Properties.
There, go to C/C++ Build -> Settings -> Build Steps tab.
There you'll see Pre-build steps -> Command. The command you fill in there will be executed before the compilation starts, so you'll tell it to compile the resource file. As you are using MinGW the resource compiler is windres:

windres ../src/resources.rc -o ../Resources/resources.o

As you can see I'll be placing the compiled resource file in a directory called Resources, you may leave it where you want (and so the name of the file, it doesn't have to be named resources.rc).

Now go to the Tool Settings tab.
There, go to MinGW C Linker -> Miscellaneous, and in other objects add the object file created before, in this case you should add:

Resources/resources.o

As this is a Windows app, add the option -mwindows to the linker flags at the top of the same tab.

Done, when building your project Eclipse will compile the resource file first and then link the generated object as any other object file of your project.

I hope it's clear enough to read through this.

Xandy
  • 1,369
  • 1
  • 12
  • 12
  • Hi ! I've one more question: How can you create a *.rc file in Eclipse ? This Filetype is not listed and when I create one it's just a plain text file for eclipse. So should I create a *.rc file anyway ? – Marcus Tik Sep 12 '09 at 07:50
  • I am sorry that I have unchecked your answer. It looked so good, that I've checked it as OK before I actually tried the solution (Well normaly I don't do this, but I knew from reading the solution that it would take a long time for me to try it). As you can see from my first comment I'm having troubles with the rc filetype - it seems that in Eclipse this filetype doesn't exist. – Marcus Tik Sep 12 '09 at 09:09
  • 1
    Ok, sorry about that, I should have written that too. To create a resource file in Eclipse you may do the following: Right click the "src" directory of your project (for example) and select "New->File", in the next dialog box insert a name for it (for example icon.rc). To edit that file from within Eclipse right click the file and select "Open with->Text Editor", it should open it as if it was another source file. I don't use Eclipse regularly, but I'm afraid that you won't have syntax highlighting for the resource files as the're not recognized. I'll edit the answer to add this, thanks! – Xandy Sep 12 '09 at 09:59
  • You may find more info on resource files in the site of GoRC (http://www.jorgon.freeserve.co.uk/ResourceFrame.htm), which is another resource compiler or in MDSN (http://msdn.microsoft.com/en-us/library/ms648045(VS.85).aspx). I've added an example of LoadImage(), check the WNDCLASSEX structure. – Xandy Sep 12 '09 at 10:23
  • As a workaround, you may add an icon at the post-build stage as described here: http://www.heaventools.com/command-line_resource_editor.htm – Wylder Dec 21 '09 at 22:17
  • Thanks for this answer. It helped me a lot. It was concise and accurate. I really appreciate the help! – jwir3 May 05 '11 at 21:56
1

Eclipse isn't set to look at resource files. BUG. So they also have steps to add it to processing. Here are the steps for June. [http://wiki.eclipse.org/CDT/User/FAQ#How_to_handle_Resource-Script-Files_.27.2A.rc.27_with_CDT.3F][1]

How to handle Resource-Script-Files '*.rc' with CDT? Currently handling of windres.exe with CDT is not possible. You can not add the .rc file to the project to be compiled and linked with automatically. This is already raised as a bug in bugzilla.

One way is to create a Pre-Build Step. Under menue Project | Properties | C/C++-Build | Settings | Build Steps | Pre-Build Steps fill in the command-line: windres --use-temp-file -i..\MyProject.rc -o..\MyProject_rc\MyProject_rc.o Make the object known to the linker. Under menue Project | Properties | C/C++-Build | Settings Tool Settings | MinGW C++ Linker | Miscellaneous | Other Objects click the icon 'Add', fill in the line: "C:\MyWorkspace\MyProject\MyProject_rc\MyProject_rc.o" 'MyWorkspace' and 'MyProject' replace with whatever is fitting for your purpose.

You have to add the folder .\MyProject_rc before you build.

The path to windres.exe must be known to eclipse.

The Andyman
  • 71
  • 1
  • 4
0

The way I did it was by creating a file

icon.rc

#define AppIcon 101
AppIcon ICON "../icon.ico"

Then invoke windres via command prompt with

windres my.rc -O coff -o my.res

It'll compile several files for you -- keep the one called icon.res and rename it as libicon.a. Finally include it in your program by adding it as a library under

Project -> Properties -> Build -> Settings -> C++ Linker -> Libraries

(make sure you tell Eclipse where to find the file using the library paths section underneath).

Hope this helps!

zx485
  • 28,498
  • 28
  • 50
  • 59
Inigo Selwood
  • 822
  • 9
  • 20
-1

I zip up all of the icons I want to use within the project first. Then Rename the .zip to a .jar

Create a resource folder if you havent got one already (I use "lib") Then place the jar file inside the resource folder.

Then one simple addition to the project properties:

by right clicking and Configure "Java Build Path" - select the Libraries tab. Click on the Add JARs button and add the icons.jar to the libraries - then save.

Now its easy to allocate the desired image icon inside the Window Builder editor for example as the jar containing your icons appears within the Image Selection mode chooser within the Classpath resource list. Everything works as it should and compiles fine.

Martin Sansone - MiOEE
  • 4,281
  • 1
  • 29
  • 31