Windows: add IconExtWindows::from_resource_name (#4137)
This commit is contained in:
parent
0c89ea7386
commit
46879429ed
3 changed files with 88 additions and 2 deletions
|
|
@ -71,6 +71,7 @@ changelog entry.
|
|||
- Added `Window::safe_area`, which describes the area of the surface that is unobstructed.
|
||||
- On X11, Wayland, Windows and macOS, improved scancode conversions for more obscure key codes.
|
||||
- Add ability to make non-activating window on macOS using `NSPanel` with `NSWindowStyleMask::NonactivatingPanel`.
|
||||
- On Windows, add `IconExtWindows::from_resource_name`.
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
|
|||
|
|
@ -660,6 +660,17 @@ impl DeviceIdExtWindows for DeviceId {
|
|||
}
|
||||
|
||||
/// Additional methods on `Icon` that are specific to Windows.
|
||||
///
|
||||
/// Windows icons can be created from files, or from the [`embedded resources`](https://learn.microsoft.com/en-us/windows/win32/menurc/about-resource-files).
|
||||
///
|
||||
/// The `ICON` resource definition statement use the following syntax:
|
||||
/// ```rc
|
||||
/// nameID ICON filename
|
||||
/// ```
|
||||
/// `nameID` is a unique name or a 16-bit unsigned integer value identifying the resource,
|
||||
/// `filename` is the name of the file that contains the resource.
|
||||
///
|
||||
/// More information about the `ICON` resource can be found at [`Microsoft Learn`](https://learn.microsoft.com/en-us/windows/win32/menurc/icon-resource) portal.
|
||||
pub trait IconExtWindows: Sized {
|
||||
/// Create an icon from a file path.
|
||||
///
|
||||
|
|
@ -671,7 +682,12 @@ pub trait IconExtWindows: Sized {
|
|||
fn from_path<P: AsRef<Path>>(path: P, size: Option<PhysicalSize<u32>>)
|
||||
-> Result<Self, BadIcon>;
|
||||
|
||||
/// Create an icon from a resource embedded in this executable or library.
|
||||
/// Create an icon from a resource embedded in this executable or library by its ordinal id.
|
||||
///
|
||||
/// The valid `ordinal` values range from 1 to [`u16::MAX`] (inclusive). The value `0` is an
|
||||
/// invalid ordinal id, but it can be used with [`from_resource_name`] as `"0"`.
|
||||
///
|
||||
/// [`from_resource_name`]: IconExtWindows::from_resource_name
|
||||
///
|
||||
/// Specify `size` to load a specific icon size from the file, or `None` to load the default
|
||||
/// icon size from the file.
|
||||
|
|
@ -679,6 +695,55 @@ pub trait IconExtWindows: Sized {
|
|||
/// In cases where the specified size does not exist in the file, Windows may perform scaling
|
||||
/// to get an icon of the desired size.
|
||||
fn from_resource(ordinal: u16, size: Option<PhysicalSize<u32>>) -> Result<Self, BadIcon>;
|
||||
|
||||
/// Create an icon from a resource embedded in this executable or library by its name.
|
||||
///
|
||||
/// Specify `size` to load a specific icon size from the file, or `None` to load the default
|
||||
/// icon size from the file.
|
||||
///
|
||||
/// In cases where the specified size does not exist in the file, Windows may perform scaling
|
||||
/// to get an icon of the desired size.
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// Consider the following resource definition statements:
|
||||
/// ```rc
|
||||
/// app ICON "app.ico"
|
||||
/// 1 ICON "a.ico"
|
||||
/// 0027 ICON "custom.ico"
|
||||
/// 0 ICON "alt.ico"
|
||||
/// ```
|
||||
///
|
||||
/// Due to some internal implementation details of the resource embedding/loading process on
|
||||
/// Windows platform, strings that can be interpreted as 16-bit unsigned integers (`"1"`,
|
||||
/// `"002"`, etc.) cannot be used as valid resource names, and instead should be passed into
|
||||
/// [`from_resource`]:
|
||||
///
|
||||
/// [`from_resource`]: IconExtWindows::from_resource
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use winit::platform::windows::IconExtWindows;
|
||||
/// use winit::window::Icon;
|
||||
///
|
||||
/// assert!(Icon::from_resource_name("app", None).is_ok());
|
||||
/// assert!(Icon::from_resource(1, None).is_ok());
|
||||
/// assert!(Icon::from_resource(27, None).is_ok());
|
||||
/// assert!(Icon::from_resource_name("27", None).is_err());
|
||||
/// assert!(Icon::from_resource_name("0027", None).is_err());
|
||||
/// ```
|
||||
///
|
||||
/// While `0` cannot be used as an ordinal id (see [`from_resource`]), it can be used as a
|
||||
/// name:
|
||||
///
|
||||
/// [`from_resource`]: IconExtWindows::from_resource
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # use winit::platform::windows::IconExtWindows;
|
||||
/// # use winit::window::Icon;
|
||||
/// assert!(Icon::from_resource_name("0", None).is_ok());
|
||||
/// assert!(Icon::from_resource(0, None).is_err());
|
||||
/// ```
|
||||
fn from_resource_name(name: &str, size: Option<PhysicalSize<u32>>) -> Result<Self, BadIcon>;
|
||||
}
|
||||
|
||||
impl IconExtWindows for Icon {
|
||||
|
|
@ -694,4 +759,9 @@ impl IconExtWindows for Icon {
|
|||
let win_icon = crate::platform_impl::WinIcon::from_resource(ordinal, size)?;
|
||||
Ok(Icon { inner: win_icon })
|
||||
}
|
||||
|
||||
fn from_resource_name(name: &str, size: Option<PhysicalSize<u32>>) -> Result<Self, BadIcon> {
|
||||
let win_icon = crate::platform_impl::WinIcon::from_resource_name(name, size)?;
|
||||
Ok(Icon { inner: win_icon })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,13 +112,28 @@ impl WinIcon {
|
|||
pub fn from_resource(
|
||||
resource_id: u16,
|
||||
size: Option<PhysicalSize<u32>>,
|
||||
) -> Result<Self, BadIcon> {
|
||||
Self::from_resource_ptr(resource_id as PCWSTR, size)
|
||||
}
|
||||
|
||||
pub fn from_resource_name(
|
||||
resource_name: &str,
|
||||
size: Option<PhysicalSize<u32>>,
|
||||
) -> Result<Self, BadIcon> {
|
||||
let wide_name = util::encode_wide(resource_name);
|
||||
Self::from_resource_ptr(wide_name.as_ptr(), size)
|
||||
}
|
||||
|
||||
fn from_resource_ptr(
|
||||
resource: PCWSTR,
|
||||
size: Option<PhysicalSize<u32>>,
|
||||
) -> Result<Self, BadIcon> {
|
||||
// width / height of 0 along with LR_DEFAULTSIZE tells windows to load the default icon size
|
||||
let (width, height) = size.map(Into::into).unwrap_or((0, 0));
|
||||
let handle = unsafe {
|
||||
LoadImageW(
|
||||
util::get_instance_handle(),
|
||||
resource_id as PCWSTR,
|
||||
resource,
|
||||
IMAGE_ICON,
|
||||
width,
|
||||
height,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue