How to get the screen resolution

Discussion in 'Game Development (Technical)' started by ggambett, Apr 13, 2010.

  1. ggambett

    Moderator Original Member Indie Author

    Joined:
    Jul 26, 2004
    Messages:
    1,982
    Likes Received:
    6
    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?
     
  2. James C. Smith

    Moderator Original Member

    Joined:
    Aug 21, 2004
    Messages:
    1,768
    Likes Received:
    0
    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;
    	}
    
     
  3. Emmanuel

    Moderator Original Member

    Joined:
    Nov 23, 2004
    Messages:
    859
    Likes Received:
    0
    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
     
  4. Julio Gorge

    Original Member

    Joined:
    Nov 26, 2005
    Messages:
    152
    Likes Received:
    0
    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
    }
    
    
     
  5. PoV

    PoV
    Indie Author

    Joined:
    Jul 27, 2004
    Messages:
    2,132
    Likes Received:
    0
    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;
    }
     
  6. James C. Smith

    Moderator Original Member

    Joined:
    Aug 21, 2004
    Messages:
    1,768
    Likes Received:
    0
    Great minds think alike. That algorithm is the same as the one I use to project how much revenue my next project will generate.
     
  7. ggambett

    Moderator Original Member Indie Author

    Joined:
    Jul 26, 2004
    Messages:
    1,982
    Likes Received:
    6
    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...
     

Share This Page

  • About Indie Gamer

    When the original Dexterity Forums closed in 2004, Indie Gamer was born and a diverse community has grown out of a passion for creating great games. Here you will find over 10 years of in-depth discussion on game design, the business of game development, and marketing/sales. Indie Gamer also provides a friendly place to meet up with other Developers, Artists, Composers and Writers.
  • Buy us a beer!

    Indie Gamer is delicately held together by a single poor bastard who thankfully gets help from various community volunteers. If you frequent this site or have found value in something you've learned here, help keep the site running by donating a few dollars (for beer of course)!

    Sure, I'll Buy You a Beer