Embedding Files in an Executable - Icons & Details - Part 6
Tags: cpp, programming, desktop
Published: 2023-03-21 13:20:28


How change icon, file details and load a file.txt from resources?

**1) Create a simple window:**

main.cpp
```cpp 
#include <windows.h>
#include <iostream>

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
 
    WNDCLASS wc = {0};
    wc.lpfnWndProc   = WndProc;
    wc.hInstance     = hInstance;
    wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
    wc.lpszClassName = TEXT("MyWindowClass");
      
    if (!RegisterClass(&wc))
        return 1;
    
    HWND hwnd = CreateWindow(
        TEXT("MyWindowClass"),
        TEXT( "My window" ),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
        NULL, NULL, hInstance, NULL);

    ShowWindow(hwnd, nCmdShow);
    
    MSG msg = {0};
    while (GetMessage(&msg, NULL, 0, 0)){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }   

    return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg){
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
            
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }    
    return 0;
}
 

```

**2) Compile**

```
g++ main.cpp -o main.exe && main
```

**4) Download 1 or 2 files: favicon.ico**

https://favicon.io/emoji-favicons/


**5) Create a file: data.txt**

```
My window name
```

**6) Create resource.h**
```cpp
#define IDI_MYICON  101
#define TEXTFILE   256
#define IDR_DATA1  255

void LoadFileInResource(int name, int type, DWORD& size, const wchar_t*& data){
    HMODULE handle = ::GetModuleHandleW(NULL);
    HRSRC rc = ::FindResourceW(handle, MAKEINTRESOURCEW(name), MAKEINTRESOURCEW(type));
    HGLOBAL rcData = ::LoadResource(handle, rc);
    size = ::SizeofResource(handle, rc);
    data = static_cast<const wchar_t*>(::LockResource(rcData));
}

std::string GetResource(){
    DWORD size = 0;
    const char* data = NULL;
    LoadFileInResource(IDR_DATA1, TEXTFILE, size, reinterpret_cast<const wchar_t*&>(data));  
    std::string content(data, size);
    return content;
}
```

**7) Create resource.rc**

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

IDI_MYICON ICON "favicon.ico"
IDR_DATA1 TEXTFILE "data.txt"

VS_VERSION_INFO     VERSIONINFO
FILEVERSION       1,0,0,1
PRODUCTVERSION    1,0,0,1
FILEFLAGSMASK 0x3fL

#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x4L
 FILETYPE 0x2L
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "CompanyName", "CompanyName"
            VALUE "LegalCopyright", "(c) CompanyName. All Rights reserved."
            VALUE "ProductName", "ProductName35"
            VALUE "ProductVersion", "1,0,0,1"
            VALUE "FileDescription", "ProductName"
            VALUE "InternalName", "ProductName"
            VALUE "OriginalFilename", "main.exe"
            VALUE "ShellIntegrationVersion", "2"
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x0416, 1200
    END
END
```

**8) Generate resource.res**

In Windows
```
windres.exe -i "resource.rc" --input-format=rc -o "resource.res" -O coff
```

In Linux/WSL2
```
x86_64-w64-mingw32-windres resource.rc -O coff -o resource.o -I/usr/share/mingw-w64/include
```


**9) Adding icons in window:**

Print in console data.txt content:
```cpp
std::cout << GetResource();
```
Display window name:
```cpp
TEXT( GetResource().c_str() )
```
Load icon:
```cpp
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYICON));
```
Set icons:
```cpp
SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)::LoadIcon(::GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON)));
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)::LoadIcon(::GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON)));
```
Destroy icons:
```cpp
DestroyIcon((HICON)SendMessage(hwnd, WM_GETICON, ICON_SMALL, 0));
DestroyIcon((HICON)SendMessage(hwnd, WM_GETICON, ICON_BIG, 0));
```

main.cpp
```cpp
#include <windows.h>
#include <iostream>
#include "resource.h"

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){

    std::cout << GetResource();
 
    WNDCLASS wc = {0};
    wc.lpfnWndProc   = WndProc;
    wc.hInstance     = hInstance;
    wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
    wc.lpszClassName = TEXT("MyWindowClass");
    wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYICON));
      
    if (!RegisterClass(&wc))
        return 1;
    
    HWND hwnd = CreateWindow(
        TEXT("MyWindowClass"),
        TEXT( GetResource().c_str() ),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
        NULL, NULL, hInstance, NULL);

    // Set icon
    SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)::LoadIcon(::GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON)));
    SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)::LoadIcon(::GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON)));

    ShowWindow(hwnd, nCmdShow);
    
    MSG msg = {0};
    while (GetMessage(&msg, NULL, 0, 0)){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }   

    // Free icon
    DestroyIcon((HICON)SendMessage(hwnd, WM_GETICON, ICON_SMALL, 0));
    DestroyIcon((HICON)SendMessage(hwnd, WM_GETICON, ICON_BIG, 0));

    return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg){
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
            
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }    
    return 0;
}
 
```

**10) Compile**

In Windows
```
g++ main.cpp -o main.exe resource.res
```

In Linux/WSL2
```
x86_64-w64-mingw32-g++ main.cpp resource.o -o main.exe -static-libgcc -static-libstdc++ -I/usr/share/mingw-w64/include
```