In the documentation there is a struct 'IDesktopWallpaper' with a method named 'GetWallpaper'. The method takes a reference to 'self' but there is no constructor method for 'IDesktopWallpaper'.
use windows::{
core::*,
Win32::UI::Shell::IDesktopWallpaper,
};
fn main() -> Result<()> {
unsafe {
// ?????
IDesktopWallpaper::GetWallpaper(&self, monitorid);
}
Ok(())
}
What am I supposed to do in order to get my desired outcome?
CodePudding user response:
COM generally uses factory methods to construct COM objects. The "standard" factory method for classic COM is CoCreateInstance
. It needs a class ID that identifies the specific implementation (in case there are multiple) and an interface ID that names the requested interface.
The windows crate exposes class IDs differently from the Windows SDK: The latter frequently uses CLSID_
-prefixes, wheres the former doesn't. DesktopWallpaper
in the windows crate is the same GUID as CLSID_DesktopWallpaper
in the Windows SDK.
Another difference is that CoCreateInstance
in the windows crate is generic over its returned interface type (as opposed to taking the address of a type-erased void*
in the Windows SDK). Clients will need to explicitly name the interface type they are requesting.
The following code initializes COM (required), instantiates a COM object, and returns an IDesktopWallpaper
interface for further use:
use windows::{
core::Result,
Win32::{
System::Com::{CoCreateInstance, CoInitialize, CLSCTX_ALL},
UI::Shell::{DesktopWallpaper, IDesktopWallpaper},
},
};
fn main() -> Result<()> {
// Initialize COM
unsafe { CoInitialize(None) }?;
// Create a DesktkopWallpaper object and return its IDesktopWallpaper interface
let wallpaper: IDesktopWallpaper =
unsafe { CoCreateInstance(&DesktopWallpaper, None, CLSCTX_ALL) }?;
// Use the COM object
unsafe { wallpaper.GetWallpaper(...) };
Ok(())
}
You'll need to have the following in your Cargo.toml file:
[dependencies.windows]
version = "0.42.0"
features = [
"Win32_UI_Shell",
"Win32_System_Com",
]