| 1 | module builder |
| 2 | |
| 3 | #include <windows.h> |
| 4 | |
| 5 | fn C.BeginUpdateResourceW(pfilename &u16, delete_existing_resources int) voidptr |
| 6 | fn C.UpdateResourceW(update_handle voidptr, type_ voidptr, name voidptr, language u16, data voidptr, data_size u32) int |
| 7 | fn C.EndUpdateResourceW(update_handle voidptr, discard int) int |
| 8 | fn C.GetLastError() u32 |
| 9 | |
| 10 | fn (mut b Builder) apply_windows_icon_to_executable() ! { |
| 11 | if b.pref.icon_path == '' { |
| 12 | return |
| 13 | } |
| 14 | icon_path := b.prepare_windows_icon_ico_path()! |
| 15 | images := parse_ico_file(icon_path)! |
| 16 | if images.len == 0 { |
| 17 | return error('icon file `${icon_path}` does not contain any icon images') |
| 18 | } |
| 19 | exe_path := b.pref.out_name.replace('/', '\\') |
| 20 | update_handle := C.BeginUpdateResourceW(exe_path.to_wide(), 0) |
| 21 | if isnil(update_handle) { |
| 22 | return error('failed to open `${exe_path}` for icon updates (Windows error ${C.GetLastError()})') |
| 23 | } |
| 24 | group_resource := build_group_icon_resource(images) |
| 25 | if C.UpdateResourceW(update_handle, windows_resource_id(14), |
| 26 | windows_resource_id(windows_icon_group_resource_id), 0, &u8(group_resource.data), |
| 27 | u32(group_resource.len)) == 0 { |
| 28 | C.EndUpdateResourceW(update_handle, 1) |
| 29 | return error('failed to write the icon group resource to `${exe_path}` (Windows error ${C.GetLastError()})') |
| 30 | } |
| 31 | for i, image in images { |
| 32 | if C.UpdateResourceW(update_handle, windows_resource_id(3), windows_resource_id(i + 1), 0, |
| 33 | &u8(image.image_data.data), image.bytes_in_res) == 0 { |
| 34 | C.EndUpdateResourceW(update_handle, 1) |
| 35 | return error('failed to write icon image ${i + 1} to `${exe_path}` (Windows error ${C.GetLastError()})') |
| 36 | } |
| 37 | } |
| 38 | if C.EndUpdateResourceW(update_handle, 0) == 0 { |
| 39 | return error('failed to finalize icon updates for `${exe_path}` (Windows error ${C.GetLastError()})') |
| 40 | } |
| 41 | } |
| 42 | |
| 43 | fn windows_resource_id(id int) voidptr { |
| 44 | return voidptr(usize(id)) |
| 45 | } |
| 46 | |