-
Notifications
You must be signed in to change notification settings - Fork 29
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
[user] EnumDisplayDevices result #36
Comments
As far as I could investigate, the enumeration ends when I changed the implementation to reflect this. Please let me know if this worked for you. |
Wow that was quick :D. I am not too familiar with winapi error handling stuff, but if I adjusted my code like mentioned in the example: /// Returns a list of all displays.
pub fn discover_displays() -> Result<DisplaySet> {
let mut result = Vec::<Display>::new();
let mut dev_num: u32 = 0;
let mut display_device = DISPLAY_DEVICE::default();
loop {
let has_more = EnumDisplayDevices(
None,
dev_num,
&mut display_device,
EDD::GET_DEVICE_INTERFACE_NAME,
)?;
if has_more {
result.push(Display::from_winsafe(dev_num, &display_device)?);
dev_num += 1;
} else {
break;
}
}
Ok(DisplaySet { displays: result })
} Then the fn returns early with the following Err: "[0x00cb 203] The system could not find the environment option that was entered.". The following works fine: let has_more = EnumDisplayDevices(
...
); // no `?`
if has_more.is_ok() { // `is_ok()` instead
result.push(Display::from_winsafe(dev_num, &display_device)?);
dev_num += 1;
} else {
break;
} This might have to do with the fact that I have one display that is |
Indeed, it seems that a display with {
use winsafe as w;
let mut dev_num: u32 = 0;
let mut display_device = w::DISPLAY_DEVICE::default();
loop {
let (is_good, is_active) = match w::EnumDisplayDevices(
None,
dev_num,
&mut display_device,
w::co::EDD::GET_DEVICE_INTERFACE_NAME,
) {
Ok(r) => (r, true), // active
Err(e) => match e {
w::co::ERROR::ENVVAR_NOT_FOUND => (true, false), // inactive
_ => panic!("Actual error!"),
}
};
if is_good {
// result.push(Display::from_winsafe(dev_num, &display_device)?);
println!("{}, active: {}", display_device.DeviceName(), is_active);
dev_num += 1;
} else {
break;
}
}
} |
When I run your code, I get an infinite loop, because But it should stop after there is no display anymore right? I have three active displays and one inactive. This means it should iterate five times, and since the fifth display does not exist an error ("The system could not find the environment option that was entered.") will be thrown and the code should break. This is not the case with the code you just posted. |
This is very unsettling... please run the code below and post back the results: {
use winsafe as w;
for n in 0..8 {
let mut dide = w::DISPLAY_DEVICE::default();
let ret = w::EnumDisplayDevices(
None, n, &mut dide, w::co::EDD::GET_DEVICE_INTERFACE_NAME);
match ret {
Ok(b) => println!("{} Ok {}", n, b),
Err(e) => println!("{} Err {}", n, e),
}
}
} |
Results in an infinite loop with the following output
|
It's just a Are you running this code inside something else? |
Agh sorry. Wanted to get back to you ASAP and got sloppy: I had another loop {} around this from code before. This code actually doesn't loop. Output is just:
The code snippet you posted earlier (before the last one) still leads to endless looping. |
What about this example in the docs? Does it still loop? |
No, it does not loop on the latest commit. However, an error is thrown:
The error occurs on the following line: |
This means that when the loop ends, However... on my computer, it returns code I'm on Windows 10 x64, what's yours? |
Win 10 Pro x64 |
OK, so I completely removed the internal error checking, and the zero is always considered the "done" state now. Let me know if this works for you. |
Output now is:
So it works! We could also handle just 127 as well as 203 as codes for |
Yeah, I just did this. This kind of undocumented behavior is really hard to work with. Thank you very much for your help. |
@michidk I changed this function to return an iterator, so the loop work is done internally. If you're still interested, I'd be glad to hear if it works for you. New docs with example can be found here. |
The EnumDisplayDevices function returns a WinResult. I don't see where
Ok(true)
is ever set. It also seems like it is not required because we also return a result.Also, the current example in the docs of that function is a bit weird. The function is supposed to be called until the first error because that means that we finished iterating over all displays:
will never be the case, because the
?
will return the error.The text was updated successfully, but these errors were encountered: