use crate::bindings::Windows::Win32::{
Controls::*, MenusAndResources::*, SystemServices::*, WindowsAndMessaging::*,
};
use std::path::{Path, PathBuf};
#[inline]
fn make_int_resource(id: u16) -> PWSTR {
PWSTR(id as _)
}
#[derive(Clone, Debug)]
pub enum Icon {
Resource(u16),
File(PathBuf),
}
impl Icon {
pub fn from_path(path: impl AsRef<Path>) -> Icon {
Icon::File(path.as_ref().to_path_buf())
}
}
fn load_icon_impl(hinst: HINSTANCE, icon: &Icon, cx: i32, cy: i32) -> HICON {
let icon = unsafe {
match icon {
Icon::Resource(id) => LoadImageW(
hinst,
make_int_resource(*id),
CopyImage_type::IMAGE_ICON,
cx,
cy,
ImageListLoadImage_uFlags::LR_SHARED,
),
Icon::File(path) => {
let wpath = path
.to_string_lossy()
.encode_utf16()
.chain(Some(0))
.collect::<Vec<_>>();
LoadImageW(
HINSTANCE(0),
PWSTR(wpath.as_ptr() as _),
CopyImage_type::IMAGE_ICON,
cx,
cy,
ImageListLoadImage_uFlags(
ImageListLoadImage_uFlags::LR_SHARED.0
| ImageListLoadImage_uFlags::LR_LOADFROMFILE.0,
),
)
}
}
};
if icon == HANDLE(0) {
panic!("cannot load the icon");
}
HICON(icon.0)
}
pub(crate) fn load_icon(icon: &Icon, hinst: HINSTANCE) -> HICON {
unsafe {
load_icon_impl(
hinst,
icon,
GetSystemMetrics(GetSystemMetrics_nIndexFlags::SM_CXICON),
GetSystemMetrics(GetSystemMetrics_nIndexFlags::SM_CYICON),
)
}
}
pub(crate) fn load_small_icon(icon: &Icon, hinst: HINSTANCE) -> HICON {
unsafe {
load_icon_impl(
hinst,
icon,
GetSystemMetrics(GetSystemMetrics_nIndexFlags::SM_CXSMICON),
GetSystemMetrics(GetSystemMetrics_nIndexFlags::SM_CYSMICON),
)
}
}