-
Notifications
You must be signed in to change notification settings - Fork 519
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
InitPropVariantFromString missing #976
Comments
Hey @valarauca, per Microsoft Docs,
It performs some setup work, then passes that on to So while the tools are all there to properly initialize windows property structures, I think we could probably do better and provide some helpers. Or perhaps an example. Tagging @kennykerr for additional thoughts. |
Related: #656 To unblock you, perhaps consider initializing a propvariant like so: let mut str: Vec<u16> = "hello world".encode_utf16().collect();
let prop = PROPVARIANT {
Anonymous: PROPVARIANT_0 {
Anonymous: PROPVARIANT_0_0_abi {
vt: VT_LPWSTR.0 as u16,
wReserved1: 0,
wReserved2: 0,
wReserved3: 0,
Anonymous: PROPVARIANT_0_0_0_abi {
pwszVal: PWSTR(str.as_mut_ptr()),
},
},
},
}; |
Yes, the metadata intentionally excludes functions with bodies as they aren't portable in the general sense. While support for unions and nested structs should improve, specialized APIs that rely heavily on macros - like VARIANT does - will likely always need hand-written libraries to provide the kind of idiomatic experience Rust developers are expecting. |
Closing this issue in favor of #656, thanks! If you feel this is in error, re-open / let us know. |
Hi @riverar As mentioned InitPropVariantFromString not a function as such that can be called from Rust. I've tried your workaround above but types such as PROPVARIANT_0_0_abi are missing? Do you have an example somewhere that shows this in action? My C++ equivalent looks like the following
Thanks |
Hey @andy-westacott, here's an updated sample. (docs) use std::mem::ManuallyDrop;
use windows::{
core::PWSTR,
Win32::System::Com::{
StructuredStorage::{PROPVARIANT, PROPVARIANT_0, PROPVARIANT_0_0, PROPVARIANT_0_0_0},
VT_LPWSTR,
},
};
fn main() -> windows::core::Result<()> {
let mut str: Vec<u16> = "hello world\0".encode_utf16().collect();
let value = PROPVARIANT_0_0 {
vt: VT_LPWSTR,
Anonymous: PROPVARIANT_0_0_0 {
pwszVal: PWSTR(str.as_mut_ptr()),
},
..Default::default()
};
let mut prop = PROPVARIANT {
Anonymous: PROPVARIANT_0 {
Anonymous: ManuallyDrop::new(value),
},
};
// ...
unsafe {
ManuallyDrop::drop(&mut prop.Anonymous.Anonymous);
}
Ok(())
} |
Related to #539 |
@riverar ah thats great. many thanks. A little related to this. What's the correct way of calling SHGetPropertyStoreForWindow in Rust and receiving an IPropertyStore? I've found several examples that have led me to something like the following. Which seem to panic when I actually call SetValue so I'm assuming the pointer back from SHGetPropertyStoreForWindow is invalid?
|
That's problematic because the Win32 metadata is missing the Until that is fixed, the following workaround will work: let mut object: Option<IPropertyStore> = None;
SHGetPropertyStoreForWindow(handle, &IPropertyStore::IID, &mut object as *mut _ as _)?;
let object = object.unwrap();
// use object Once the metadata is fixed, you'll be able to write: let object: IPropertyStore = SHGetPropertyStoreForWindow(handle)?;
// use object |
Ah perfect. Thats works great now. Thank you. Thought I was going a little nuts ;) |
Kenny beat me to it, but here's a working sample. (Use his approach above for [dependencies.windows]
version = "0.48.0"
features = [
"Win32_Foundation",
"Win32_System_Com_StructuredStorage",
"Win32_UI_Shell_PropertiesSystem",
"Win32_Storage_EnhancedStorage",
"Win32_UI_WindowsAndMessaging"
] use windows::{
core::{ComInterface, Interface},
w,
Win32::{
Foundation::HWND,
Storage::EnhancedStorage::PKEY_AppUserModel_ID,
System::Com::VT_LPWSTR,
UI::{
Shell::PropertiesSystem::{IPropertyStore, SHGetPropertyStoreForWindow},
WindowsAndMessaging::FindWindowW,
},
},
};
fn main() -> windows::core::Result<()> {
unsafe {
let hwnd = FindWindowW(None, w!("Microsoft Store"));
assert_ne!(hwnd, HWND(0));
let mut ptr: *mut std::ffi::c_void = std::ptr::null_mut();
SHGetPropertyStoreForWindow(hwnd, &IPropertyStore::IID, &mut ptr)?;
let store = IPropertyStore::from_raw(ptr);
let value = store.GetValue(&PKEY_AppUserModel_ID)?;
assert_eq!(value.Anonymous.Anonymous.vt, VT_LPWSTR);
println!(
"AUMID: {}",
value.Anonymous.Anonymous.Anonymous.pwszVal.to_string()?
);
}
Ok(())
} |
The function
InitPropVariantFromString
appears missing.I receive the following error when I include it in my
build.rs
It does not appear in the docs search.
The following exist
InitPropVariantFromStringAsVector
,InitPropVariantFromStringVector
, andInitPropVariantFromStrRet
.The text was updated successfully, but these errors were encountered: