I'm using the IDesktopWallpaper::SetWallpaper
method from the windows crate. The second argument to this method is a PCWSTR
(pointer) to the full path of an image that's meant to be set as the wallpaper. The problem is that the PCWSTR
object is meant to be of type *const u16
not *const String
. How can I get a PCWSTR
object from a Path/String?
let path = "Path_to_image.jpg".to_string();
let ptr = &path as *const String;
let wallpaper = PCWSTR::from_raw(ptr);
// ^^^ expected raw pointer `*const u16`
// found raw pointer `*const String`
unsafe { desktop.SetWallpaper(None, wallpaper)};
CodePudding user response:
When it comes to strings, Rust and Windows couldn't possibly disagree more. There's always going to be conversions involved when using Rust on Windows, and the best you can hope for is a crate that does this for you.
The windows crate doesn't just provide Rust mappings for Windows' API surface, it also contains a tiny library that addresses common issues when programming Windows with Rust, amongst which is string handling. A lot of thought went into string handling, and the result may seem somewhat anticlimactic: All string constants can be represented as HSTRING
instances.
Consequently, HSTRING
is the pivot point for string conversions in Rust for Windows. Its implementation has a sleuth of From
trait implementations for Rust string types (all, I believe), with From
implementations of all other Windows string types for HSTRING
.
In this case, if path
is of type Path
you can simply construct an HSTRING
from it, and pass it by reference. Everything else just happens due to implicit From
trait invocations (namely From<&HSTRING> for PCWSTR
):
unsafe { desktop.SetWallpaper(None, &HSTRING::from(path.as_os_str())) };