winctx/window_loop/
icon_handle.rs1use std::io;
2
3use windows_sys::Win32::Foundation::TRUE;
4use windows_sys::Win32::UI::WindowsAndMessaging as winuser;
5use windows_sys::Win32::UI::WindowsAndMessaging::{DestroyIcon, HICON};
6
7#[derive(Clone)]
8pub(crate) struct IconHandle {
9 pub(super) hicon: HICON,
10}
11
12impl IconHandle {
13 pub(crate) fn from_buffer(buffer: &[u8], width: u32, height: u32) -> io::Result<Self> {
14 let offset = unsafe {
15 winuser::LookupIconIdFromDirectoryEx(
16 buffer.as_ptr(),
17 TRUE,
18 width as i32,
19 height as i32,
20 winuser::LR_DEFAULTCOLOR,
21 )
22 };
23
24 if offset == 0 {
25 return Err(io::Error::last_os_error());
26 }
27
28 let icon_data = &buffer[offset as usize..];
29
30 let hicon = unsafe {
31 winuser::CreateIconFromResourceEx(
32 icon_data.as_ptr(),
33 icon_data.len() as u32,
34 TRUE,
35 0x30000,
36 width as i32,
37 height as i32,
38 winuser::LR_DEFAULTCOLOR,
39 )
40 };
41
42 if hicon == 0 {
43 return Err(io::Error::last_os_error());
44 }
45
46 Ok(Self { hicon })
47 }
48}
49
50impl Drop for IconHandle {
51 fn drop(&mut self) {
52 unsafe {
54 DestroyIcon(self.hicon);
55 }
56 }
57}