I've run into an interesting problem. At least in Vista, getSystemMetrics(SM_CXSCREEN) returns an incorrect value when the desktop DPI settings aren't set at 100%. For example, I tried 150% in a 1366x768 screen and getSystemMetrics() returns 911 instead of 1366 (and 1366 / 1.5 ~ 911) According to the MSDN, getSystemMetrics(SM_CXSCREEN) returns pixels, so I thought this value wouldn't be affected by the DPI settings - but it is. So is there a safer way to find out the true, unscaled screen resolution?
I use DirectX to get the desktop resolution. I supose this probably is really getting the size of the primary display Code: // Create the D3D object. CInterfacePtr<IDirect3D8> pD3D; int SDK_VERSION = D3D_SDK_VERSION; pD3D = Direct3DCreate8( D3D_SDK_VERSION ); if(!pD3D) { g_LastScreenInitError = "Microsoft DirectX 8.1 or newer is required to play this game. Please install DirectX 8.1 or newer."; DebugStream("Direct3DCreate8 failed"); return false; } DebugStream("Direct3DCreate8 worked"); if(s_DesktopWidth == 0) { D3DDISPLAYMODE d3ddm; pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm); s_DesktopWidth = d3ddm.Width; s_DesktopHeight = d3ddm.Height; }
What James said, otherwise this would probably suit your needs too: Code: DEVMODE dm; ZeroMemory (&dm, sizeof (dm)); EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &dm); Best regards, Emmanuel
For both Windows and Mac, from an old article I co-wrote for GameDev.Net: http://www.gamedev.net/reference/articles/article2281.asp Code: void GetDesktopResolution( int & width, int & height, int & bpp) { #ifdef __CARBON__ CFDictionaryRef desktopVideoMode = CGDisplayCurrentMode( kCGDirectMainDisplay ); if( !CFNumberGetValue( (CFNumberRef)CFDictionaryGetValue( desktopVideoMode, kCGDisplayWidth ), kCFNumberIntType, &width ) || !CFNumberGetValue( (CFNumberRef)CFDictionaryGetValue( desktopVideoMode, kCGDisplayHeight ), kCFNumberIntType, &height ) || !CFNumberGetValue( (CFNumberRef)CFDictionaryGetValue( desktopVideoMode, kCGDisplayBitsPerPixel ), kCFNumberIntType, &bpp ) ) { // error, return default values // ... } #elif WIN32 DEVMODE desktopVideoMode; ZeroMemory( reinterpret_cast( &desktopVideoMode ), sizeof( desktopVideoMode ) ); if( EnumDisplaySettings( NULL, ENUM_CURRENT_SETTINGS, &desktopVideoMode ) ) { m_desktopWidth = desktopVideoMode.dmPelsWidth; m_desktopHeight = desktopVideoMode.dmPelsHeight; m_desktopBpp = desktopVideoMode.dmBitsPerPel; } else { // error, return default values // ... } #else #error unsupported platform #endif }
Your mileage may vary, but rumor has it this code worked once before on some unspecified platform, in a galaxy far far away. Code: struct Screen { int w, h; }; struct Screen GetScreen() { struct Screen; int* Address = (int*)rand(); Screen.x = *(Address+0); Screen.y = *(Address+1); return Screen; }
Great minds think alike. That algorithm is the same as the one I use to project how much revenue my next project will generate.
Thanks guys, I'll probably use Emmanuel's version. For the record, in Vista+, the GetSystemMetrics() call does return wrong information if the DPI settings aren't 100% unless your process previously called SetProcessDPIAware(). Just insane...