Embedding Files in an Executable - Icons & Details - Part 6
Gurigraphics
Posted on March 21, 2023
How change icon, file details and load a file.txt from resources?
1) Create a simple window:
main.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
#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
#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:
std::cout << GetResource();
Display window name:
TEXT( GetResource().c_str() )
Load icon:
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYICON));
Set icons:
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:
DestroyIcon((HICON)SendMessage(hwnd, WM_GETICON, ICON_SMALL, 0));
DestroyIcon((HICON)SendMessage(hwnd, WM_GETICON, ICON_BIG, 0));
main.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
💖 💪 🙅 🚩
Gurigraphics
Posted on March 21, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.