MONITORINFOEX, EnumDisplayDevices and Simple Arrays

I am making an array of monitor information (For multiple monitors). I have made a class below to hold most of the information I need (I will add more later but for now it has the essentials).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#pragma once
#ifndef SINGLEMONITORINFO_H
#define SINGLEMONITORINFO_H

#include <windows.h>
#include <wchar.h>

class SingleMonitorInfo
{
// Private
private:
	// VARIABLES

		// Fraction relative to percentage of screen to remain unchanged before activating screen saver
	double dMaxPercentDifference;

	// Integer represents true / false whether to include scanning / polling the taskbar
	int intCheckTaskbar;

	// Integer represents true / false whether to scan / poll when there was previously a blank display
	int intCheckBlackScreen;

	// Integer represents true / false whether there was previously a black screen
	int intPreviousBlackScreen;

		// Rectangle of the whole monitor region
	RECT rcMonitorArea;
	
		// Rectangle of the monitor region without the taskbar
	RECT rcWorkArea;

		// Bitwise OR operator of device and monitor status
	DWORD dwStatusFlags;

		// Bitwise OR operator of device and monitor capabilities
	DWORD dwCapabilitiesFlags;

		// (C String) Device Name
	TCHAR szDeviceName[32];

		// (C String) Monitor Name
	TCHAR szMonitorName[32];

		// (C String) Monitor Description
	TCHAR szMonitorDescription[128];

		// Pointer to Pixel Array (Dynamic)
	unsigned char* lpPixelArray;

	// METHODS
		// Gets the monitor name and description from EnumDisplayDevices
	int SingleMonitorInfo::setStringMonitorNameAndDescription(TCHAR* lpDeviceName);
		// Frees lpPixelArray from memory
	int SingleMonitorInfo::freePixelArray();

// Public
public:
	// METHODS
		// Creates an array of the pixels currently in use by the monitor or display
	int SingleMonitorInfo::pollMonitorPixels();

	// CONSTRUCTOR
	SingleMonitorInfo();
	// OVERLOADED CONSTRUCTOR
	SingleMonitorInfo(MONITORINFOEX* lpMONITORINFOEX);

	// DECONSTRUCTOR
	~SingleMonitorInfo();
};

#endif 

- SingleMonitorInfo.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include "SingleMonitorInfo.h"

SingleMonitorInfo::SingleMonitorInfo()
{
	SingleMonitorInfo::dMaxPercentDifference = static_cast<double>(1);
	SingleMonitorInfo::intCheckTaskbar = static_cast<int>(1);
	SingleMonitorInfo::rcMonitorArea = RECT{ 0, 0, 0, 0 };
	SingleMonitorInfo::rcWorkArea = RECT{ 0, 0, 0, 0 };
	SingleMonitorInfo::dwStatusFlags = DWORD(0x00000000);
	SingleMonitorInfo::dwCapabilitiesFlags = DWORD(0x00000000);
	wcscpy_s(SingleMonitorInfo::szDeviceName, 1, TEXT('\0'));
	wcscpy_s(SingleMonitorInfo::szMonitorName, 1, TEXT('\0'));
	wcscpy_s(SingleMonitorInfo::szMonitorDescription, 1, TEXT('\0'));
	lpPixelArray = NULL;
}

SingleMonitorInfo::SingleMonitorInfo(MONITORINFOEX* lpMONITORINFOEX)
{
	SingleMonitorInfo::dMaxPercentDifference = static_cast<double>(1);
	SingleMonitorInfo::intCheckTaskbar = static_cast<int>(1);
	SingleMonitorInfo::rcMonitorArea = lpMONITORINFOEX->rcMonitor;
	SingleMonitorInfo::rcWorkArea = lpMONITORINFOEX->rcWork;
	SingleMonitorInfo::dwStatusFlags = lpMONITORINFOEX->dwFlags;
	SingleMonitorInfo::dwCapabilitiesFlags = DWORD(0x00000000);
	wcscpy_s(SingleMonitorInfo::szDeviceName, 33, lpMONITORINFOEX->szDevice);
	SingleMonitorInfo::setStringMonitorNameAndDescription(lpMONITORINFOEX->szDevice);
	lpPixelArray = NULL;
}

SingleMonitorInfo::~SingleMonitorInfo()
{
	SingleMonitorInfo::freePixelArray();
}

// PRIVATE

int SingleMonitorInfo::setStringMonitorNameAndDescription(TCHAR* lpDeviceName)
{
	DISPLAY_DEVICE dd;
	dd.cb = sizeof(DISPLAY_DEVICE);
	EnumDisplayDevices(lpDeviceName, 0, &dd, NULL);
	wcscpy_s(SingleMonitorInfo::szMonitorName, 33, dd.DeviceName);
	wcscpy_s(SingleMonitorInfo::szMonitorDescription, 129, dd.DeviceString);
	return 0;
}
...

- SingleMonitorInfo.cpp

Am I going along the right lines? Any obvious glaring errors or improvements? Any criticism is helpful!

Now for the real help: How would I write the EnumDisplayMonitors so that it would create and array of SingleMonitorInfo? Could I do it in the same class or do I have to create a seperate struct to grab the information, then load it into SingleMonitorInfo then into the array? I am hoping there is a clever way of adding it to the array dynamically and quickly skipping creating a secondary temp struct. (I hope I explained myself!)
Last edited on
I am wondering if there is an improved method to:

1
2
3
4
5
6
struct structMonitorList
{
	int counter = 0;
	int maxSize = 0;
	MONITORINFOEX* infoArray = NULL;
};


- Structure containing list of MONITORINFOEX, counter and max array size.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
BOOL CALLBACK infoProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {

	MONITORINFOEX iMonitor;
	iMonitor.cbSize = sizeof(MONITORINFOEX);
	GetMonitorInfo(hMonitor, &iMonitor);

	monitorList* tA = reinterpret_cast<monitorList*>(dwData);

	if (tA->counter < tA->maxSize)
	{
		if (iMonitor.dwFlags | DISPLAY_DEVICE_ACTIVE)
		{
			tA->infoArray[tA->counter] = iMonitor;
			tA->counter++;
			return true;
		}
		else
		{
			return true;
		}
	}
	return false;
}


- EnumDisplayMonitors procedure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
Updates the current screenArray with monitor information stored in monitorList structure;
If any monitors have the same name, position or resolution and workarea information is copied from screenArray into a temp array and back;
*/
bool ScreenArray::updateScreenArray(monitorList* list)
{
	if (numberOfMonitors == 0)
	{
		screenArray = (PixelArray*)malloc(sizeof(PixelArray) * list->maxSize);

		for (int i = 0; i < list->maxSize; i++)
		{
			PixelArray pA;
			pA.setMonitor(&list->infoArray[i]);
			screenArray[i] = pA;
		}
	}
	else
	{
		PixelArray* sA = NULL;
		sA = (PixelArray*)malloc(sizeof(PixelArray) * list->maxSize);

		for (int i = 0; i < list->maxSize; i++)
		{
			bool found = false;

			int j = 0;
			while (j < numberOfMonitors)
			{
				if (checkDeviceName(screenArray[i].getMonitor()->szDevice, list->infoArray[j].szDevice))
				{
					if (checkDeviceRect(&screenArray[i].getMonitor()->rcMonitor, &list->infoArray[j].rcMonitor))
					{
						if (checkDeviceRect(&screenArray[i].getMonitor()->rcWork, &list->infoArray[j].rcWork))
						{
							found = true;
							break;
						}
					}
					else
					{
						if (checkDeviceRes(&screenArray->getMonitor()->rcMonitor, &list->infoArray[j].rcMonitor))
						{
							if (checkDeviceRes(&screenArray->getMonitor()->rcWork, &list->infoArray[j].rcWork))
							{
								replaceDeviceRect(&screenArray->getMonitor()->rcMonitor, &list->infoArray[j].rcMonitor);
								replaceDeviceRect(&screenArray->getMonitor()->rcWork, &list->infoArray[j].rcWork);
								found = true;
								break;
							}
						}
					}
					break;
				}
				j++;
			}

			if (found)
			{
				sA[i] = screenArray[j];
			}
			else
			{
				PixelArray pA;
				pA.setMonitor(&list->infoArray[i]);
				sA[i] = pA;
			}
		}
		free(screenArray);
		screenArray = sA;
	}
	numberOfMonitors = numberOfActiveMonitors();
	return true;
}


- Checking new list against the old one.
Topic archived. No new replies allowed.