Home > Blog > Bare Minimum: Setting the Window Icon

Bare Minimum: Setting the Window Icon

The bare minimum needed to set the window icon with MSVC when building with the command line.

Andrew Jon Haman
July 5th, 2021

The Bare Minimum:

  1. With Visual Studio installed, open a terminal window and call vcvarsall.bat
  2. Create an .ico file from your .png using a third party tool.(yes, really).
  3. Create a new text file with the extension .rc, i.e. <your_rc_file.rc>
  4. In <your_rc_file.rc> put the line <YOUR_ICON_IDENTIFIER> ICON <your_ico_filename.ico>
  5. In your terminal window, call RC icon.rc to create a .res file
  6. Add that .res file after /link when you build, for example cl.exe main.cpp /link <your_res_filename.res>
  7. Call HICON icon = LoadIconA(hInstance, "<YOUR_ICON_IDENTIFIER>");
  8. Set necessary WNDCLASSEX fields to icon before passing to RegisterClassEx
    WNDCLASSEX window_class;
    window_class.hIcon = icon;
    window_class.hIconSm = icon;
    //fill out other window_class fields.
    RegisterClassEx(&window_class);
  9. Cry at the state of software.


1. Calling vcvarsall.bat

vcvarsall.bat is included when you install Visual Studio. Basically, it sets up the terminal environment for working with MSVC. What's important for our purposes is that it puts RC.exe and cl.exe into the path. Unless Microsoft has changed something since the writing of this post, it can be found in the Visual Studio install location.
For me, it is located at "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat"
If you prefer, you may call RC.exe directly using the full path, but good luck finding it. (Hint: It's not in the Visual Studio install folder)

2. Creating an .ico

Unfortunately, Microsoft does not provide a good way of generating .ico files. You can do it using Visual Studio but that's a pain. The easiest way I have found to create one is using an online .png to .ico converter such as hipdf or icoconvert. (If you know of an easier or less janky way then please let me know)

3-4. RC files

Because Microsoft hates you, RC files are scripts that specify how resources should be built. We then call RC.exe to compile those scripts into .res resource files, and then link those .res files into our program. In our case, it's pretty much what it looks like. We just declare <YOUR_ICON_IDENTIFIER> to be an ICON from the file <your_ico_filename.ico> If you for want to do more reading on RC files the MSDN has a page on them although it doesn't actually tell you how to use them.

8. Setting the Window Icon

If you want to move past the Bare Minimum, you may prefer to set seperate large and small icons, to increase readability. You may do this without too much work from what we have done here. Just, create seperate .ico files for each size, add seperate lines into your .rc file for each and then call LoadIconA() on each seperately. So your RC file would look something like this
IDI_MY_BIG_ICON ICON big_icon.ico
IDI_MY_SMALL_ICON ICON small_icon.ico
and then in your program you would have
HICON big_icon = LoadIconA(hInstance, "IDI_MY_BIG_ICON");
HICON small_icon = LoadIconA(hInstance, "IDI_MY_SMALL_ICON");

WNDCLASSEX window_class;
window_class.hIcon = big_icon;
window_class.hIconSm = small_icon;
//fill out other window_class fields.
RegisterClassEx(&window_class);
Another way to go about this would be to use WM_SETICON events, but there are already fine resources out there detailing that method so I won't go into it here.

9. The State of Software

Why do we need 3 files types and a whole extra programming language to tell Windows which bitmap to render? Please refer to the beginning of section 3-4. The logic of what we are trying to do here can essentially be expressed as a single function SetIcon("my_icon_file.png"); The fact that it is instead an 8 step process goes to demonstrate how important API design really is. Especially when that API effects every program written for your Operating System of 1.3 Billion users. If you want to read more about API design, Casey Muratori has some great articles on good and bad design, as well as a whole lecture on the subject.