1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use std::path::{Path, PathBuf};
use winapi::shared::minwindef::{MAX_PATH, TRUE, UINT};
use winapi::um::winnt::{HRESULT, PVOID, WCHAR};
use winapi::um::winuser::{
SystemParametersInfoW, SPIF_SENDCHANGE, SPIF_UPDATEINIFILE, SPI_GETDESKWALLPAPER,
SPI_SETDESKWALLPAPER,
};
use widestring::{U16CStr, U16CString};
mod error;
pub use error::Error;
pub type Result<T> = std::result::Result<T, Error>;
pub fn set<T: AsRef<Path>>(full_path: T) -> Result<()> {
let full_path: U16CString = U16CString::from_os_str(full_path.as_ref())?;
let ret = unsafe {
SystemParametersInfoW(
SPI_SETDESKWALLPAPER,
0,
full_path.as_ptr() as PVOID,
SPIF_SENDCHANGE | SPIF_UPDATEINIFILE,
)
};
check_result(ret)?;
Ok(())
}
pub fn get() -> Result<PathBuf> {
let mut full_path_buf = [0 as WCHAR; MAX_PATH];
let ret = unsafe {
SystemParametersInfoW(
SPI_GETDESKWALLPAPER,
full_path_buf.len() as UINT,
full_path_buf.as_mut_ptr() as PVOID,
0,
)
};
check_result(ret)?;
let full_path: &U16CStr = U16CStr::from_slice_with_nul(&full_path_buf)?;
Ok(full_path.to_os_string().into())
}
fn check_result(result: HRESULT) -> Result<()> {
match result {
TRUE => Ok(()),
_ => Err(std::io::Error::from_raw_os_error(result))?,
}
}