Home > Net >  Not sure how to use IDesktopWallpaper
Not sure how to use IDesktopWallpaper

Time:10-24

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",
]
  • Related