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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#![allow(non_snake_case)]

use crate::co;
use crate::decl::*;
use crate::guard::*;
use crate::ole::privs::*;
use crate::oleaut::ffi;
use crate::prelude::*;

/// [`OleLoadPicture`](https://learn.microsoft.com/en-us/windows/win32/api/olectl/nf-olectl-oleloadpicture)
/// function.
///
/// # Examples
///
/// Parsing an image from raw data:
///
/// ```no_run
/// use winsafe::{self as w, prelude::*};
///
/// let stream: w::IStream; // initialized somewhere
/// # let stream = unsafe { w::IStream::null() };
///
/// let picture = w::OleLoadPicture(&stream, None, true)?;
/// # w::HrResult::Ok(())
/// ```
///
/// # Related functions
///
/// * [`OleLoadPicturePath`](crate::OleLoadPicturePath)
#[must_use]
pub fn OleLoadPicture(
	stream: &impl ole_IStream,
	size: Option<u32>,
	keep_original_format: bool,
) -> HrResult<IPicture>
{
	let mut queried = unsafe { IPicture::null() };
	ok_to_hrresult(
		unsafe {
			ffi::OleLoadPicture(
				stream.ptr() as _,
				size.unwrap_or_default() as _,
				!keep_original_format as _, // note: reversed
				&IPicture::IID as *const _ as _,
				queried.as_mut(),
			)
		},
	).map(|_| queried)
}

/// [`OleLoadPicturePath`](https://learn.microsoft.com/en-us/windows/win32/api/olectl/nf-olectl-oleloadpicturepath)
/// function.
///
/// The picture must be in BMP (bitmap), JPEG, WMF (metafile), ICO (icon), or
/// GIF format.
///
/// # Related functions
///
/// * [`OleLoadPicture`](crate::OleLoadPicture)
#[must_use]
pub fn OleLoadPicturePath(
	path: &str,
	transparent_color: Option<COLORREF>,
) -> HrResult<IPicture>
{
	let mut queried = unsafe { IPicture::null() };
	ok_to_hrresult(
		unsafe {
			ffi::OleLoadPicturePath(
				WString::from_str(path).as_ptr(),
				std::ptr::null_mut(),
				0,
				transparent_color.map_or(0, |c| c.into()),
				&IPicture::IID as *const _ as _,
				queried.as_mut(),
			)
		},
	).map(|_| queried)
}

/// [`PSGetNameFromPropertyKey`](https://learn.microsoft.com/en-us/windows/win32/api/propsys/nf-propsys-psgetnamefrompropertykey)
/// function.
#[must_use]
pub fn PSGetNameFromPropertyKey(prop_key: &PROPERTYKEY) -> HrResult<String> {
	let mut pstr = std::ptr::null_mut::<u16>();
	ok_to_hrresult(
		unsafe {
			ffi::PSGetNameFromPropertyKey(
				prop_key as *const _ as _,
				&mut pstr,
			)
		},
	).map(|_| {
		let name = unsafe { WString::from_wchars_nullt(pstr) };
		let _ = unsafe { CoTaskMemFreeGuard::new(pstr as _, 0) };
		name.to_string()
	})
}

/// [`SystemTimeToVariantTime`](https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-systemtimetovarianttime)
/// function.
///
/// Note that this function resolves the time to one second; milliseconds are
/// ignored.
///
/// # Related functions
///
/// * [`VariantTimeToSystemTime`](crate::VariantTimeToSystemTime)
#[must_use]
pub fn SystemTimeToVariantTime(st: &SYSTEMTIME) -> SysResult<f64> {
	let mut double = f64::default();
	match unsafe {
		ffi::SystemTimeToVariantTime(st as *const _ as _, &mut double)
	} {
		0 => Err(co::ERROR::INVALID_PARAMETER),
		_ => Ok(double),
	}
}

/// [`VariantTimeToSystemTime`](https://learn.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-varianttimetosystemtime)
/// function.
///
/// # Related functions
///
/// * [`SystemTimeToVariantTime`](crate::SystemTimeToVariantTime)
#[must_use]
pub fn VariantTimeToSystemTime(var_time: f64) -> SysResult<SYSTEMTIME> {
	let mut st = SYSTEMTIME::default();
	match unsafe {
		ffi::VariantTimeToSystemTime(var_time, &mut st as *mut _ as _)
	} {
		0 => Err(co::ERROR::INVALID_PARAMETER),
		_ => Ok(st),
	}
}