开发者

How to get the Monitor Screen Resolution from a hWnd?

How to get the monitor screen resolution from a hWnd?

I am using a hWnd because the window could be located on any one of multiple monitors.

i.e. the hWnd top/left coordinate is on a Monitor that has a Screen Resolution of 开发者_如何学Go800 x 600.

I program in a language called PL/B and it allows calling Windows API.

What Window APIs can be used?


Here's a C++ code example that works for me:

HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
MONITORINFO info;
info.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(monitor, &info);
int monitor_width = info.rcMonitor.right - info.rcMonitor.left;
int monitor_height = info.rcMonitor.bottom - info.rcMonitor.top;


The user32 function MonitorFromWindow allows you to pass in an hwnd, and returns a handle to the monitor it's on (or a default - see the linked MSDN article for details). With that you can call GetMonitorInfo to retrieve a MONITORINFO struct which contains a RECT detailing its resolution.

See the Multiple Screens Reference section of MSDN for more details.

I'd add example code but I don't know the language you referenced, and I don't know how useful C# example code would be to you. If you think it'll help, let me know and I'll code up something real quick.


There is GetSystemMetrics too, check it out on msdn


Here's some C# code that gets the resolution (in DPI) via P/Invoke:

public static void GetWindowDpi(IntPtr hwnd, out int dpiX, out int dpiY)
{
    var handle = MonitorFromWindow(hwnd, MonitorFlag.MONITOR_DEFAULTTOPRIMARY);

    GetDpiForMonitor(handle, MonitorDpiType.MDT_EFFECTIVE_DPI, out dpiX, out dpiY);
}

/// <summary>
/// Determines the function's return value if the window does not intersect any display monitor.
/// </summary>
[SuppressMessage("ReSharper", "IdentifierTypo")]
[SuppressMessage("ReSharper", "UnusedMember.Local")]
private enum MonitorFlag : uint
{
    /// <summary>Returns NULL.</summary>
    MONITOR_DEFAULTTONULL = 0,
    /// <summary>Returns a handle to the primary display monitor.</summary>
    MONITOR_DEFAULTTOPRIMARY = 1,
    /// <summary>Returns a handle to the display monitor that is nearest to the window.</summary>
    MONITOR_DEFAULTTONEAREST = 2
}

[DllImport("user32.dll")]
private static extern IntPtr MonitorFromWindow(IntPtr hwnd, MonitorFlag flag);

[SuppressMessage("ReSharper", "IdentifierTypo")]
[SuppressMessage("ReSharper", "UnusedMember.Local")]
private enum MonitorDpiType
{
    /// <summary>
    /// The effective DPI.
    /// This value should be used when determining the correct scale factor for scaling UI elements.
    /// This incorporates the scale factor set by the user for this specific display.
    /// </summary>
    MDT_EFFECTIVE_DPI = 0,
    /// <summary>
    /// The angular DPI.
    /// This DPI ensures rendering at a compliant angular resolution on the screen.
    /// This does not include the scale factor set by the user for this specific display.
    /// </summary>
    MDT_ANGULAR_DPI = 1,
    /// <summary>
    /// The raw DPI.
    /// This value is the linear DPI of the screen as measured on the screen itself.
    /// Use this value when you want to read the pixel density and not the recommended scaling setting.
    /// This does not include the scale factor set by the user for this specific display and is not guaranteed to be a supported DPI value.
    /// </summary>
    MDT_RAW_DPI = 2
}

[DllImport("user32.dll")]
private static extern bool GetDpiForMonitor(IntPtr hwnd, MonitorDpiType dpiType, out int dpiX, out int dpiY);


For Monitors with hight resolution 2K 4K > 1920px

void GetDesktopResolution(int* horizontal, int* vertical)
{

    HDC hScreenDC = GetDC(GetDesktopWindow());
    int width = GetDeviceCaps(hScreenDC, HORZRES);
    int height = GetDeviceCaps(hScreenDC, VERTRES);
    ReleaseDC(GetDesktopWindow(), hScreenDC);

    RECT desktop;
    const HWND hDesktop = GetDesktopWindow();
    GetWindowRect(hDesktop, &desktop);
    
    if (width > 2000)
    {
        const POINT ptZero = { 0, 0 };
        HMONITOR mon = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY);

        DEVICE_SCALE_FACTOR f;// vers < win 8 = GetScaleFactorForDevice(DEVICE_PRIMARY);
        GetScaleFactorForMonitor(mon,&f);
        if (f > 110)
        {
            *horizontal = width * ((f+10) / 100.0);
            *vertical = height * ((f+10) / 100.0);
        }
        else
        {
            *horizontal = width;
            *vertical = height;
        }
    }
    else
    {
        *horizontal = desktop.right;
        *vertical = desktop.bottom;
    }
}


RECT windowsize;    // get the height and width of the screen
GetClientRect(hwnd, &windowsize);

int srcheight = windowsize.bottom;
int srcwidth = windowsize.right;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜