Home > Net >  How to get a "PCWSTR" object from a Path or String?
How to get a "PCWSTR" object from a Path or String?

Time:10-24

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())) };
  • Related