Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Determining Windows resolution at runtime

Credits go to Jakub Wasilewski for helping out!
This thread is locked; no one can reply to it. rss feed Print
Determining Windows resolution at runtime
23yrold3yrold
Member #1,134
March 2001
avatar

I've been trying to figure out a way to run a program so it displays on a second monitor. Works fine, by making that window a popup with the dimensions of the second monitor, an x coordinate equal to the first monitor's horizontal resolution, and a y coordinate of 0. Problem being these values need to be hardcoded and if some dingus changes the monitor's resolution, things mess up.

Making notes in readme's that the resolution must be such and such is fine, but I'm trying to make these programs idiot-proof, plus I don't like making multiple builds with different hard-coded variables. Anyone know of some sort of Win32 method for getting the monitor resolutions dynamically at runtime so I can always position the window at the desktop's right edge, and at the second monitor's resolution?

I may have asked this before, but it bothers me that I can't find a way to do it. :P Be real nice if the program was all automated and stuff ...

--
Software Development == Church Development
Step 1. Build it.
Step 2. Pray.

Jakub Wasilewski
Member #3,653
June 2003
avatar

You can call EnumDisplayDevices repeatedly (with a device of NULL) to get to your monitors. This will yield a number of DISPLAY_DEVICE structs, you'll have to check which of them correspond to monitors.

Then, you can EnumDisplaySettings with the DISPLAY_DEVICE.DeviceName and iModeNum=ENUM_CURRENT_SETTINGS to get actual information about the current resolution.

This is based on a rusty and incomplete knowledge of WinAPI, but with MSDN you might be able to make something out of it ;).

---------------------------
[ ChristmasHack! | My games ] :::: One CSS to style them all, One Javascript to script them, / One HTML to bring them all and in the browser bind them / In the Land of Fantasy where Standards mean something.

23yrold3yrold
Member #1,134
March 2001
avatar

You're more or less mentioning the structures and stuff that cropped up the last time I looked into this, but I was unable to translate it into actual code ...

--
Software Development == Church Development
Step 1. Build it.
Step 2. Pray.

Jakub Wasilewski
Member #3,653
June 2003
avatar

Let's see:

1#include <windows.h>
2#include <iostream>
3 
4using namespace std;
5 
6int main()
7{
8 DISPLAY_DEVICE adapter;
9 adapter.cb = sizeof(DISPLAY_DEVICE);
10
11 int i = 0;
12
13 while (EnumDisplayDevices(NULL, i++, &adapter, 0))
14 {
15 DEVMODE mode;
16 mode.dmSize = sizeof(DEVMODE);
17 mode.dmDriverExtra = 0;
18
19 cout << "Adapter " << i << ": " << adapter.DeviceName << endl;
20 if (EnumDisplaySettings(adapter.DeviceName, ENUM_CURRENT_SETTINGS, &mode))
21 cout << "\tresolution: " << mode.dmPelsWidth << "x" << mode.dmPelsHeight << endl;
22 else
23 cout << "Unable to get settings for device." << endl;
24 }
25
26 return 0;
27}

On my system, it shows this:

Adapter 1: \\.\DISPLAY1
        resolution: 1280x960
Adapter 2: \\.\DISPLAYV1
Unable to get settings for device.
Adapter 3: \\.\DISPLAYV2
Unable to get settings for device.

I think that on a multi-monitor system there will be at least two DISPLAYs. I'm not sure what those V1 and V2 are, but I think it's safe to ignore any adapters for which you are not able to retrieve settings.

EDIT: By the way, what is it for?

---------------------------
[ ChristmasHack! | My games ] :::: One CSS to style them all, One Javascript to script them, / One HTML to bring them all and in the browser bind them / In the Land of Fantasy where Standards mean something.

23yrold3yrold
Member #1,134
March 2001
avatar

Well, I run it and it detects my main resolution easily enough, so I'll call it win. I can't get my Windows settings to accept a secondary; keeps seeming to disable it, so I can't test here if it works for getting that second resolution. This is still a small victory though, so I assume the code works as intended and I grant you cookies. Now to look it over and see how it works. ;D

And it's for the kids I teach at church. We're kinda media driven and my supervisor is always asking me to write a program for this and that. It needs to go to the second monitor on the computer to display up front for the kids, and I've torn out a fair share of hair getting it working in a satisfactory manner. Think I may finally have it.

--
Software Development == Church Development
Step 1. Build it.
Step 2. Pray.

MiquelFire
Member #3,110
January 2003
avatar

Note, the second monitor may have it's right edge at 0, so it's left side is some negative value (depends on it's horizontal resolution).

---
Febreze (and other air fresheners actually) is just below perfumes/colognes, and that's just below dead skunks in terms of smells that offend my nose.
MiquelFire.red
If anyone is of the opinion that there is no systemic racism in America, they're either blind, stupid, or racist too. ~Edgar Reynaldo

Jakub Wasilewski
Member #3,653
June 2003
avatar

Well, this is a little late, but here is a simpler and better solution, using the proper function:

1#include <windows.h>
2#include <iostream>
3 
4using namespace std;
5 
6BOOL callback(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM data)
7{
8 static int no = 1;
9
10 cout << "Monitor " << no << ":\n";
11 cout << "\tTop-left corner at: " << rect->left << "," << rect->top << "\n";
12 cout << "\tResolution: " << (rect->right - rect->left) << "x" << (rect->bottom - rect->top) << "\n\n";
13
14 no++;
15 
16 return true;
17}
18 
19int main()
20{
21 EnumDisplayMonitors(NULL, NULL, (MONITORENUMPROC)callback, 0);
22}

I knew it was EnumDisplaySomethings, I just picked the wrong one the first time around ;). This way you get both coordinates for the monitor, so you always know where exactly to display the window. The callback is called repeatedly as long as there are monitors left, and as long as you return true from it.

Perhaps someone from the forums with multiple monitors at hand could test it?

---------------------------
[ ChristmasHack! | My games ] :::: One CSS to style them all, One Javascript to script them, / One HTML to bring them all and in the browser bind them / In the Land of Fantasy where Standards mean something.

Matthew Leverton
Supreme Loser
January 1999
avatar

Quote:

Monitor 1:
Top-left corner at: 0,0
Resolution: 1280x1024

Monitor 2:
Top-left corner at: 1280,256
Resolution: 1024x768

Monitor 3:
Top-left corner at: -1280,0
Resolution: 1280x1024

Works for me.

MiquelFire
Member #3,110
January 2003
avatar

Quote:

Monitor 1:
Top-left corner at: 0,0
Resolution: 1280x1024

Monitor 2:
Top-left corner at: -1280,0
Resolution: 1280x1024

Works here as well.

---
Febreze (and other air fresheners actually) is just below perfumes/colognes, and that's just below dead skunks in terms of smells that offend my nose.
MiquelFire.red
If anyone is of the opinion that there is no systemic racism in America, they're either blind, stupid, or racist too. ~Edgar Reynaldo

BAF
Member #2,981
December 2002
avatar

Quote:

Monitor 1:
Top-left corner at: 0,0
Resolution: 1680x1050

Works fine for one monitor.

23yrold3yrold
Member #1,134
March 2001
avatar

Sounds awesome. I'll put it to good use; thanks again.

--
Software Development == Church Development
Step 1. Build it.
Step 2. Pray.

Go to: