Skip to content
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

How to use MONITORINFOEX with GetMonitorInfoA? #1837

Closed
SageSudo opened this issue Jun 21, 2022 · 4 comments
Closed

How to use MONITORINFOEX with GetMonitorInfoA? #1837

SageSudo opened this issue Jun 21, 2022 · 4 comments
Labels
question Further information is requested

Comments

@SageSudo
Copy link

Hi,

According to the Microsoft documentation for GetMonitorInfo, the function's second parameter can be either a MONITORINFO or MONITORINFOEX, however, in the windows-rs documentation for GetMonitorInfoA, the function only accepts MONITORINFO as a second parameter.

Is there something I have to do to make MONITORINFOEX work with GetMonitorInfoA?

This is how I've went about trying GetMonitorInfoA:

use windows::Win32::{
    Foundation::POINT,
    Graphics::Gdi::{
        GetMonitorInfoA, MonitorFromPoint, MONITORINFO, MONITORINFOEXA, MONITOR_DEFAULTTONULL,
    },
    UI::WindowsAndMessaging::GetCursorPos,
};

fn main() {
    unsafe {
        let mut point = POINT::default();
        GetCursorPos(&mut point);

        let hmonitor = MonitorFromPoint(point, MONITOR_DEFAULTTONULL);

        let mut monitor_info = MONITORINFO {
            cbSize: std::mem::size_of::<MONITORINFOEXA>() as u32,
            ..MONITORINFO::default()
        };

        let mut monitor_info_ex = MONITORINFOEXA {
            monitorInfo: monitor_info,
            ..MONITORINFOEXA::default()
        };

        GetMonitorInfoA(hmonitor, &mut monitor_info_ex); //<-- Not possible.
    }
}
@riverar
Copy link
Collaborator

riverar commented Jun 21, 2022

Hi @SageSudo, pass in monitor_info_ex.monitorInfo. It starts at the same offset as the extended structure and cleanly gets you around this funky API.

@riverar riverar added the question Further information is requested label Jun 21, 2022
@SageSudo
Copy link
Author

Hi @riverar, thank you for answering!

I did give that a try when I was experimenting with the function previously but I realized that the szDevice (display monitor name) field in MONITORINFOEXA won't get populated with the monitor name.

When I tried println!("monitor_info_ex.szDevice {:?}", monitor_info_ex.szDevice);, I get the below value regardless of monitor:

monitor_info_ex.szDevice [CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0), CHAR(0)]

Is that expected because I only passed in monitor_info_ex.monitorInfo or should I have received a value in the szDevice field?

@kennykerr
Copy link
Collaborator

That's likely because you didn't initialize the MONITORINFOEXA with its size. It is the cbSize field that tells the GetMonitorInfoA function which structure you actually passed in. Here's a complete example:

use windows::{Win32::Foundation::*, Win32::Graphics::Gdi::*};

fn main() {
    unsafe {
        EnumDisplayMonitors(None, std::ptr::null(), Some(callback), LPARAM(0));
    }
}

extern "system" fn callback(handle: HMONITOR, _: HDC, _: *mut RECT, _: LPARAM) -> BOOL {
    unsafe {
        let mut info = MONITORINFOEXA::default();
        info.monitorInfo.cbSize = std::mem::size_of::<MONITORINFOEXA>() as _;
        GetMonitorInfoA(handle, &mut info.monitorInfo);
        let slice = std::slice::from_raw_parts(info.szDevice.as_ptr() as _, info.szDevice.len());
        println!("{}", std::str::from_utf8_unchecked(slice));
        BOOL(1)
    }
}

And here's what I get:

\\.\DISPLAY1
\\.\DISPLAY2

Check the docs for GetMonitorInfoA for more information:

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmonitorinfoa

@SageSudo
Copy link
Author

Yes, I must have done something wrong, I rewrote what I had and followed both your suggestions and that worked.

Thank you for the example Kenny, and thank you both for the help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants