[try Beta version]
Not logged in

 
 
Obtain desktop dimensions while DPI scaling is enabled

Sep 16, 2023 at 4:32pm
Good day!

I am looking for a way to get physical desktop (primary monitor) resolution using Windows API.
So far I tried several approaches:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <windows.h>

std::pair<int, int> GetDesktopDimensions1() {
    int screenWidth  = GetSystemMetrics(SM_CXSCREEN);
    int screenHeight = GetSystemMetrics(SM_CYSCREEN);
    return { screenWidth, screenHeight };
}

std::pair<int, int> GetDesktopDimensions2() {
    HDC hdc = GetDC(nullptr);
    int screenWidth  = GetDeviceCaps(hdc, HORZRES);
    int screenHeight = GetDeviceCaps(hdc, VERTRES);
    ReleaseDC(nullptr, hdc);
    return { screenWidth, screenHeight };
}

std::pair<int, int> GetDesktopDimensions3() {
    RECT desktopRect;
    HWND hwndDesktop = GetDesktopWindow();
    GetWindowRect(hwndDesktop, &desktopRect);
    int screenWidth  = desktopRect.right  - desktopRect.left;
    int screenHeight = desktopRect.bottom - desktopRect.top;
    return { screenWidth, screenHeight };
}


The problem is they all return scaled dimensions. For example on 4k monitor with 200% Windows UI scale they all return 1920 x 1080. While I want 3840 x 2160.

I am also aware of "Properties" > "Compatibility" tab > "Override high DPI scaling behavior" which will change that behavior for particular app. But I want to know physical desktop dimensions regardless of this setting set or not by the user.

There are some methods in some game engines that do just that easily, but at some point I need to know these dimensions before I init some game engines stuff.
Last edited on Sep 16, 2023 at 4:35pm
Sep 16, 2023 at 6:00pm
Apparently, "the best option here (simple and backward compatible) is to use EnumDisplaySettings with ENUM_CURRENT_SETTINGS."
https://stackoverflow.com/a/41337181

I have not tried this myself.
Sep 16, 2023 at 10:49pm
https://stackoverflow.com/questions/70976583/get-real-screen-resolution-using-win32-api

DPI scaling makes getting the actual screen size a PITA the usual way with WinAPI functions.
Sep 17, 2023 at 12:18pm
Thank you for answers!

@Canado, that worked for me!
At least for my single-monitor config on Win 10.
The code:
1
2
3
4
5
6
7
8
9
10
#include <windows.h>
...
pair<int, int> GetPhysicalDesktopDimensions() {
    DEVMODE devMode;
    devMode.dmSize = sizeof(DEVMODE);
    EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &devMode);
    int screenWidth  = devMode.dmPelsWidth;
    int screenHeight = devMode.dmPelsHeight;
    return { screenWidth, screenHeight };
}


@George P
Maybe for several monitors I will need something like that...
But have not tried it, because of PITA part. Sorry (:

The solution is enough for me, so, [solved].
Sep 17, 2023 at 3:56pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <utility>
#include <iostream>

#include <windows.h>

#pragma comment (lib, "user32.lib")

std::pair<int, int> GetPhysicalDesktopDimensions() {
	if (DEVMODE devMode { .dmSize = sizeof(DEVMODE) }; EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &devMode))
		return { devMode.dmPelsWidth, devMode.dmPelsHeight };

	return {};
}


int main() {
	const auto [width, height] { GetPhysicalDesktopDimensions() };

	std::cout << width << '\t' << height << '\n';
}

Last edited on Sep 17, 2023 at 4:18pm
Sep 18, 2023 at 11:49pm
I am also aware of "Properties" > "Compatibility" tab > "Override high DPI scaling behavior" which will change that behavior for particular app. But I want to know physical desktop dimensions regardless of this setting set or not by the user.

Maybe you want to have a look at:
https://learn.microsoft.com/en-us/windows/win32/hidpi/setting-the-default-dpi-awareness-for-a-process
Topic archived. No new replies allowed.