Sign in to follow this  
Followers 0

_DesktopDimensions() - Details about the primary and secondary monitors.

21 posts in this topic

Posted (edited)

I was looking at Trac on AutoIt and decided just to create this quick function which displays the number of monitors connected as well as the total width/height of all monitors. I know this is available elsewhere but felt I would contribute anyway. Thanks.

Function:

; #FUNCTION# ====================================================================================================================
; Name ..........: _DesktopDimensions
; Description ...: Returns an array containing information about the primary and virtual monitors.
; Syntax ........: _DesktopDimensions()
; Return values .: Success - Returns a 6-element array containing the following information:
;				   $aArray[0] = Total number of monitors.
;				   $aArray[1] = Width of the primary monitor.
;				   $aArray[2] = Height of the primary monitor.
;				   $aArray[3] = Total width of the desktop including the width of multiple monitors. Note: If no secondary monitor this will be the same as $aArray[2].
;				   $aArray[4] = Total height of the desktop including the height of multiple monitors. Note: If no secondary monitor this will be the same as $aArray[3].
; Author ........: guinness
; Remarks .......: WinAPI.au3 must be included i.e. #include <WinAPI.au3>
; Related .......: @DesktopWidth, @DesktopHeight, _WinAPI_GetSystemMetrics
; Example .......: Yes
; ===============================================================================================================================
Func _DesktopDimensions()
	Local $aReturn = [_WinAPI_GetSystemMetrics($SM_CMONITORS), _ ; Number of monitors.
			_WinAPI_GetSystemMetrics($SM_CXSCREEN), _ ; Width or Primary monitor.
			_WinAPI_GetSystemMetrics($SM_CYSCREEN), _ ; Height or Primary monitor.
			_WinAPI_GetSystemMetrics($SM_CXVIRTUALSCREEN), _ ; Width of the Virtual screen.
			_WinAPI_GetSystemMetrics($SM_CYVIRTUALSCREEN)] ; Height of the Virtual screen.
	Return $aReturn
EndFunc   ;==>_DesktopDimensions
Example use of Function:

#include <WinAPI.au3>
#include <WindowsConstants.au3>

Local $aScreenResolution = _DesktopDimensions()
MsgBox($MB_SYSTEMMODAL, '', 'Example of _DesktopDimensions:' & @CRLF & _
		'Number of monitors = ' & $aScreenResolution[0] & @CRLF & _
		'Primary Width = ' & $aScreenResolution[1] & @CRLF & _
		'Primary Height = ' & $aScreenResolution[2] & @CRLF & _
		'Secondary Width = ' & $aScreenResolution[3] & @CRLF & _
		'Secondary Height = ' & $aScreenResolution[4] & @CRLF)
Edited by guinness

Share this post


Link to post
Share on other sites



Posted

It would be good if you could give information on the sizes and positions of any secondary monitors.

Share this post


Link to post
Share on other sites

Posted

I tried SM_XVIRTUALSCREEN & SM_YVIRTUALSCREEN but this didn't work when I tested it. Just returned 0, 0.

Share this post


Link to post
Share on other sites

Posted

Very useful, thanks!

João Carlos.

Share this post


Link to post
Share on other sites

Posted

I tried SM_XVIRTUALSCREEN & SM_YVIRTUALSCREEN but this didn't work when I tested it. Just returned 0, 0.

0,0 could be correct. I think you need to investigate EnumDisplayMonitors.

Share this post


Link to post
Share on other sites

Posted (edited)

0,0 could be correct. I think you need to investigate EnumDisplayMonitors.

I started to look at that yesterday but I got a little sidetracked.Thanks for reminding me.

Edit: This isn't a quick 5 minute function as I first thought so I will need some more time to study the best approach of using EnumDisplayMonitors.

Edited by guinness

Share this post


Link to post
Share on other sites

Posted (edited)

Edit: This isn't a quick 5 minute function as I first thought so I will need some more time to study the best approach of using EnumDisplayMonitors.

Here is example for EnumDisplayMonitors

EDIT: But this post is rather old so there may be some incompatibility with latest Autoit version or datatypes.

EDIT2: I saw some scripts using WMI with Win32_DesktopMonitor also.

Edited by Zedna

Share this post


Link to post
Share on other sites

Posted

Thanks Zedna. The first link I tried just to get an idea and it did give me an insight into the function.

I will delve more into Win32_DesktopMonitor later on today as it was something I did come across and looking at MSDN is something which is easy to implement.

Share this post


Link to post
Share on other sites

Posted (edited)

Example using WMI: (Thanks to Zedna & martin for pointing out alternatives.)

#include <Array.au3>

Local $aScreenResolution

$aScreenResolution = _GetActiveMonitors()
For $A = 1 To $aScreenResolution[0][0]
	ConsoleWrite("Monitor " & $A & ":" & @CRLF & _
			"Width = " & $aScreenResolution[$A][0] & @CRLF & _
			"Height = " & $aScreenResolution[$A][1] & @CRLF & @CRLF)
Next

Func _GetActiveMonitors()
	Local $aError[2][2] = [[1, 2],[@DesktopWidth, @DesktopHeight]], $aReturn[1][2] = [[0, 2]], $iDimension = 0, $oColItems, $oWMIService

	$oWMIService = ObjGet("winmgmts:.rootCIMV2")
	$oColItems = $oWMIService.ExecQuery("SELECT * FROM Win32_DesktopMonitor Where Availability='3'", "WQL", 0x30)

	If IsObj($oColItems) Then
		For $oObjItem In $oColItems
			If ($aReturn[0][0] + 1) >= $iDimension Then
				$iDimension = ($aReturn[0][0] + 1) * 2
				ReDim $aReturn[$iDimension][$aReturn[0][1]]
			EndIf
			$aReturn[0][0] += 1
			$aReturn[$aReturn[0][0]][0] = $oObjItem.ScreenHeight
			$aReturn[$aReturn[0][0]][1] = $oObjItem.ScreenWidth
		Next
		ReDim $aReturn[$aReturn[0][0] + 1][$aReturn[0][1]]
		$aReturn[0][1] = ""
		Return $aReturn
	EndIf
	Return SetError(1, 0, $aError)
EndFunc   ;==>_GetActiveMonitors
Edited by guinness

Share this post


Link to post
Share on other sites

Posted (edited)

I tried also the WMI variant but it shows me only one monitor although I've two of them in my office. Desktop is extented to both of them.

I found a link in MSDN and trying to get it run properly but there is something wrong with it.

#include <array.au3>
#include <winapi.au3>

Global Const $MONITOR_DEFAULTTONULL = 0x00000000
Global Const $MONITOR_DEFAULTTOPRIMARY = 0x00000001
Global Const $MONITOR_DEFAULTTONEAREST = 0x00000002
Global Const $MONITORINFOF_PRIMARY = 0x00000001

Global Const $RECT = "LONG left;LONG top;LONG right;LONG bottom"

;http://msdn.microsoft.com/en-us/library/windows/desktop/dd145065(v=vs.85).aspx
Global Const $MONITORINFO = "DWORD cbSize;LONG rcMonitor[4];LONG rcWork[4];DWORD dwFlags"

;~ Global $struct_rcMonitor =  DllStructCreate($RECT)
;~ Global $struct_rcWork =  DllStructCreate($RECT)
Global $struct_MONITORINFO = DllStructCreate($MONITORINFO)

;~ DllStructSetData($struct_rcMonitor, "rcMonitor", DllStructGetPtr($struct_rcMonitor))
;~ DllStructSetData($struct_rcWork, "rcWork", DllStructGetPtr($struct_rcWork))
DllStructSetData($struct_MONITORINFO, "dwFlags", $MONITORINFOF_PRIMARY)
DllStructSetData($struct_MONITORINFO, "cbSize", DllStructGetSize($struct_MONITORINFO))

Global $ptrMONITORINFO  = DllStructGetPtr($struct_MONITORINFO)

ConsoleWrite(GetMonitorInfo(_WinAPI_GetDC(0), $ptrMONITORINFO) & @LF)

Func GetMonitorInfo($hMonitor, $pLPMI) ;http://msdn.microsoft.com/en-us/library/windows/desktop/dd144901(v=vs.85).aspx
	Local $aRes = DllCall ("user32.dll", 	"int", "GetMonitorInfo", "hwnd", $hMonitor, "ptr", $pLPMI)
	Return $aRes[0]
EndFunc

Further I don't know whether this will get the information which is needed.

Newbie on this section...

Br,

UEZ

MultiMon.h

//=============================================================================
//
// multimon.h -- Stub module that fakes multiple monitor apis on Win32 OSes
//			   without them.
//
// By using this header your code will get back default values from
// GetSystemMetrics() for new metrics, and the new multimonitor APIs
// will act like only one display is present on a Win32 OS without
// multimonitor APIs.
//
// Exactly one source must include this with COMPILE_MULTIMON_STUBS defined.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//=============================================================================

#ifdef __cplusplus
extern "C" {			// Assume C declarations for C++
#endif // __cplusplus

//
// If we are building with Win95/NT4 headers, we need to declare
// the multimonitor-related metrics and APIs ourselves.
//
#ifndef SM_CMONITORS

#define SM_XVIRTUALSCREEN	   76
#define SM_YVIRTUALSCREEN	   77
#define SM_CXVIRTUALSCREEN	  78
#define SM_CYVIRTUALSCREEN	  79
#define SM_CMONITORS			80
#define SM_SAMEDISPLAYFORMAT	81

// HMONITOR is already declared if WINVER >= 0x0500 in windef.h
// This is for components built with an older version number.
//
#if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500)
DECLARE_HANDLE(HMONITOR);
#define HMONITOR_DECLARED
#endif

#define MONITOR_DEFAULTTONULL	   0x00000000
#define MONITOR_DEFAULTTOPRIMARY	0x00000001
#define MONITOR_DEFAULTTONEAREST	0x00000002

#define MONITORINFOF_PRIMARY		0x00000001

typedef struct tagMONITORINFO
{
	DWORD   cbSize;
	RECT	rcMonitor;
	RECT	rcWork;
	DWORD   dwFlags;
} MONITORINFO, *LPMONITORINFO;

#ifndef CCHDEVICENAME
#define CCHDEVICENAME 32
#endif

#ifdef __cplusplus
typedef struct tagMONITORINFOEXA : public tagMONITORINFO
{
	CHAR		szDevice[CCHDEVICENAME];
} MONITORINFOEXA, *LPMONITORINFOEXA;
typedef struct tagMONITORINFOEXW : public tagMONITORINFO
{
	WCHAR	   szDevice[CCHDEVICENAME];
} MONITORINFOEXW, *LPMONITORINFOEXW;
#ifdef UNICODE
typedef MONITORINFOEXW MONITORINFOEX;
typedef LPMONITORINFOEXW LPMONITORINFOEX;
#else
typedef MONITORINFOEXA MONITORINFOEX;
typedef LPMONITORINFOEXA LPMONITORINFOEX;
#endif // UNICODE
#else // ndef __cplusplus
typedef struct tagMONITORINFOEXA
{
	MONITORINFO;
	CHAR		szDevice[CCHDEVICENAME];
} MONITORINFOEXA, *LPMONITORINFOEXA;
typedef struct tagMONITORINFOEXW
{
	MONITORINFO;
	WCHAR	   szDevice[CCHDEVICENAME];
} MONITORINFOEXW, *LPMONITORINFOEXW;
#ifdef UNICODE
typedef MONITORINFOEXW MONITORINFOEX;
typedef LPMONITORINFOEXW LPMONITORINFOEX;
#else
typedef MONITORINFOEXA MONITORINFOEX;
typedef LPMONITORINFOEXA LPMONITORINFOEX;
#endif // UNICODE
#endif

typedef BOOL (CALLBACK* MONITORENUMPROC)(HMONITOR, HDC, LPRECT, LPARAM);

#ifndef DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
typedef struct _DISPLAY_DEVICEA {
	DWORD  cb;
	CHAR   DeviceName[32];
	CHAR   DeviceString[128];
	DWORD  StateFlags;
	CHAR   DeviceID[128];
	CHAR   DeviceKey[128];
} DISPLAY_DEVICEA, *PDISPLAY_DEVICEA, *LPDISPLAY_DEVICEA;
typedef struct _DISPLAY_DEVICEW {
	DWORD  cb;
	WCHAR  DeviceName[32];
	WCHAR  DeviceString[128];
	DWORD  StateFlags;
	WCHAR  DeviceID[128];
	WCHAR  DeviceKey[128];
} DISPLAY_DEVICEW, *PDISPLAY_DEVICEW, *LPDISPLAY_DEVICEW;
#ifdef UNICODE
typedef DISPLAY_DEVICEW DISPLAY_DEVICE;
typedef PDISPLAY_DEVICEW PDISPLAY_DEVICE;
typedef LPDISPLAY_DEVICEW LPDISPLAY_DEVICE;
#else
typedef DISPLAY_DEVICEA DISPLAY_DEVICE;
typedef PDISPLAY_DEVICEA PDISPLAY_DEVICE;
typedef LPDISPLAY_DEVICEA LPDISPLAY_DEVICE;
#endif // UNICODE

#define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001
#define DISPLAY_DEVICE_MULTI_DRIVER		0x00000002
#define DISPLAY_DEVICE_PRIMARY_DEVICE	  0x00000004
#define DISPLAY_DEVICE_MIRRORING_DRIVER	0x00000008
#define DISPLAY_DEVICE_VGA_COMPATIBLE	  0x00000010
#endif

#endif  // SM_CMONITORS

#undef GetMonitorInfo
#undef GetSystemMetrics
#undef MonitorFromWindow
#undef MonitorFromRect
#undef MonitorFromPoint
#undef EnumDisplayMonitors
#undef EnumDisplayDevices

//
// Define COMPILE_MULTIMON_STUBS to compile the stubs;
// otherwise, you get the declarations.
//
#ifdef COMPILE_MULTIMON_STUBS

//-----------------------------------------------------------------------------
//
// Implement the API stubs.
//
//-----------------------------------------------------------------------------

#ifndef _MULTIMON_USE_SECURE_CRT
#if defined(__GOT_SECURE_LIB__) && __GOT_SECURE_LIB__ >= 200402L
#define _MULTIMON_USE_SECURE_CRT 1
#else
#define _MULTIMON_USE_SECURE_CRT 0
#endif
#endif

#ifndef MULTIMON_FNS_DEFINED

int	  (WINAPI* g_pfnGetSystemMetrics)(int) = NULL;
HMONITOR (WINAPI* g_pfnMonitorFromWindow)(HWND, DWORD) = NULL;
HMONITOR (WINAPI* g_pfnMonitorFromRect)(LPCRECT, DWORD) = NULL;
HMONITOR (WINAPI* g_pfnMonitorFromPoint)(POINT, DWORD) = NULL;
BOOL	 (WINAPI* g_pfnGetMonitorInfo)(HMONITOR, LPMONITORINFO) = NULL;
BOOL	 (WINAPI* g_pfnEnumDisplayMonitors)(HDC, LPCRECT, MONITORENUMPROC, LPARAM) = NULL;
BOOL	 (WINAPI* g_pfnEnumDisplayDevices)(PVOID, DWORD, PDISPLAY_DEVICE,DWORD) = NULL;
BOOL	 g_fMultiMonInitDone = FALSE;
BOOL	 g_fMultimonPlatformNT = FALSE;

#endif

BOOL IsPlatformNT()
{
	OSVERSIONINFOA osvi = {0};
	osvi.dwOSVersionInfoSize = sizeof(osvi);
	GetVersionExA((OSVERSIONINFOA*)&osvi);
	return (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId);	
}

BOOL InitMultipleMonitorStubs(void)
{
	HMODULE hUser32;
	if (g_fMultiMonInitDone)
	{
		return g_pfnGetMonitorInfo != NULL;
	}

	g_fMultimonPlatformNT = IsPlatformNT();
	hUser32 = GetModuleHandle(TEXT("USER32"));
	if (hUser32 &&
		(*(FARPROC*)&g_pfnGetSystemMetrics	= GetProcAddress(hUser32,"GetSystemMetrics")) != NULL &&
		(*(FARPROC*)&g_pfnMonitorFromWindow   = GetProcAddress(hUser32,"MonitorFromWindow")) != NULL &&
		(*(FARPROC*)&g_pfnMonitorFromRect	 = GetProcAddress(hUser32,"MonitorFromRect")) != NULL &&
		(*(FARPROC*)&g_pfnMonitorFromPoint	= GetProcAddress(hUser32,"MonitorFromPoint")) != NULL &&
		(*(FARPROC*)&g_pfnEnumDisplayMonitors = GetProcAddress(hUser32,"EnumDisplayMonitors")) != NULL &&
#ifdef UNICODE
		(*(FARPROC*)&g_pfnEnumDisplayDevices  = GetProcAddress(hUser32,"EnumDisplayDevicesW")) != NULL &&
		(*(FARPROC*)&g_pfnGetMonitorInfo	  = g_fMultimonPlatformNT ? GetProcAddress(hUser32,"GetMonitorInfoW") :
												GetProcAddress(hUser32,"GetMonitorInfoA")) != NULL
#else
		(*(FARPROC*)&g_pfnGetMonitorInfo	  = GetProcAddress(hUser32,"GetMonitorInfoA")) != NULL &&
		(*(FARPROC*)&g_pfnEnumDisplayDevices  = GetProcAddress(hUser32,"EnumDisplayDevicesA")) != NULL
#endif
	) {
		g_fMultiMonInitDone = TRUE;
		return TRUE;
	}
	else
	{
		g_pfnGetSystemMetrics	= NULL;
		g_pfnMonitorFromWindow   = NULL;
		g_pfnMonitorFromRect	 = NULL;
		g_pfnMonitorFromPoint	= NULL;
		g_pfnGetMonitorInfo	  = NULL;
		g_pfnEnumDisplayMonitors = NULL;
		g_pfnEnumDisplayDevices  = NULL;

		g_fMultiMonInitDone = TRUE;
		return FALSE;
	}
}

//-----------------------------------------------------------------------------
//
// fake implementations of Monitor APIs that work with the primary display
// no special parameter validation is made since these run in client code
//
//-----------------------------------------------------------------------------

int WINAPI
xGetSystemMetrics(int nIndex)
{
	if (InitMultipleMonitorStubs())
		return g_pfnGetSystemMetrics(nIndex);

	switch (nIndex)
	{
	case SM_CMONITORS:
	case SM_SAMEDISPLAYFORMAT:
		return 1;

	case SM_XVIRTUALSCREEN:
	case SM_YVIRTUALSCREEN:
		return 0;

	case SM_CXVIRTUALSCREEN:
		nIndex = SM_CXSCREEN;
		break;

	case SM_CYVIRTUALSCREEN:
		nIndex = SM_CYSCREEN;
		break;
	}

	return GetSystemMetrics(nIndex);
}

#define xPRIMARY_MONITOR ((HMONITOR)0x12340042)

HMONITOR WINAPI
xMonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags)
{
	if (InitMultipleMonitorStubs())
		return g_pfnMonitorFromPoint(ptScreenCoords, dwFlags);

	if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
		((ptScreenCoords.x >= 0) &&
		(ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
		(ptScreenCoords.y >= 0) &&
		(ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
	{
		return xPRIMARY_MONITOR;
	}

	return NULL;
}

HMONITOR WINAPI
xMonitorFromRect(LPCRECT lprcScreenCoords, DWORD dwFlags)
{
	if (InitMultipleMonitorStubs())
		return g_pfnMonitorFromRect(lprcScreenCoords, dwFlags);

	if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
		((lprcScreenCoords->right > 0) &&
		(lprcScreenCoords->bottom > 0) &&
		(lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
		(lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
	{
		return xPRIMARY_MONITOR;
	}

	return NULL;
}

HMONITOR WINAPI
xMonitorFromWindow(HWND hWnd, DWORD dwFlags)
{
	WINDOWPLACEMENT wp;

	if (InitMultipleMonitorStubs())
		return g_pfnMonitorFromWindow(hWnd, dwFlags);

	if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
		return xPRIMARY_MONITOR;

	if (IsIconic(hWnd) ?
			GetWindowPlacement(hWnd, &wp) :
			GetWindowRect(hWnd, &wp.rcNormalPosition)) {

		return xMonitorFromRect(&wp.rcNormalPosition, dwFlags);
	}

	return NULL;
}

BOOL WINAPI
xGetMonitorInfo(HMONITOR hMonitor, __inout LPMONITORINFO lpMonitorInfo)
{
	RECT rcWork;

	if (InitMultipleMonitorStubs())
	{
		BOOL f = g_pfnGetMonitorInfo(hMonitor, lpMonitorInfo);
#ifdef UNICODE
		if (f && !g_fMultimonPlatformNT && (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX)))
		{
			MultiByteToWideChar(CP_ACP, 0,
				(LPSTR)((MONITORINFOEX*)lpMonitorInfo)->szDevice, -1,
				((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
		}
#endif
		return f;
	}

	if ((hMonitor == xPRIMARY_MONITOR) &&
		lpMonitorInfo &&
		(lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
		SystemParametersInfoA(SPI_GETWORKAREA, 0, &rcWork, 0))
	{
		lpMonitorInfo->rcMonitor.left = 0;
		lpMonitorInfo->rcMonitor.top  = 0;
		lpMonitorInfo->rcMonitor.right  = GetSystemMetrics(SM_CXSCREEN);
		lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
		lpMonitorInfo->rcWork = rcWork;
		lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;

		if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX))
		{
#ifdef UNICODE
			MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, ((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
#else // UNICODE
#if _MULTIMON_USE_SECURE_CRT
			strncpy_s(((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)), TEXT("DISPLAY"), (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)) - 1);
#else
			lstrcpyn(((MONITORINFOEX*)lpMonitorInfo)->szDevice, TEXT("DISPLAY"), (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
#endif // _MULTIMON_USE_SECURE_CRT
#endif // UNICODE
		}

		return TRUE;
	}

	return FALSE;
}

BOOL WINAPI
xEnumDisplayMonitors(
		HDC			 hdcOptionalForPainting,
		LPCRECT		 lprcEnumMonitorsThatIntersect,
		MONITORENUMPROC lpfnEnumProc,
		LPARAM		  dwData)
{
	RECT rcLimit;

	if (InitMultipleMonitorStubs()) {
		return g_pfnEnumDisplayMonitors(
				hdcOptionalForPainting,
				lprcEnumMonitorsThatIntersect,
				lpfnEnumProc,
				dwData);
	}

	if (!lpfnEnumProc)
		return FALSE;

	rcLimit.left   = 0;
	rcLimit.top	= 0;
	rcLimit.right  = GetSystemMetrics(SM_CXSCREEN);
	rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);

	if (hdcOptionalForPainting)
	{
		RECT	rcClip;
		POINT   ptOrg;

		switch (GetClipBox(hdcOptionalForPainting, &rcClip))
		{
		default:
			if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
				return FALSE;

			OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y);
			if (IntersectRect(&rcLimit, &rcLimit, &rcClip) &&
				(!lprcEnumMonitorsThatIntersect ||
					 IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {

				break;
			}
			//fall thru
		case NULLREGION:
			 return TRUE;
		case ERROR:
			 return FALSE;
		}
	} else {
		if (	lprcEnumMonitorsThatIntersect &&
				!IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {

			return TRUE;
		}
	}

	return lpfnEnumProc(
			xPRIMARY_MONITOR,
			hdcOptionalForPainting,
			&rcLimit,
			dwData);
}

BOOL WINAPI
xEnumDisplayDevices(
	PVOID Unused,
	DWORD iDevNum,
	__inout PDISPLAY_DEVICE lpDisplayDevice,
	DWORD dwFlags)
{
	if (InitMultipleMonitorStubs())
		return g_pfnEnumDisplayDevices(Unused, iDevNum, lpDisplayDevice, dwFlags);

	if (Unused != NULL)
		return FALSE;

	if (iDevNum != 0)
		return FALSE;

	if (lpDisplayDevice == NULL || lpDisplayDevice->cb < sizeof(DISPLAY_DEVICE))
		return FALSE;

#ifdef UNICODE
	MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, lpDisplayDevice->DeviceName, (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)));
	MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, lpDisplayDevice->DeviceString, (sizeof(lpDisplayDevice->DeviceString)/sizeof(TCHAR)));
#else // UNICODE
#if _MULTIMON_USE_SECURE_CRT
	strncpy_s((LPTSTR)lpDisplayDevice->DeviceName, (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)), TEXT("DISPLAY"), (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)) - 1);
	strncpy_s((LPTSTR)lpDisplayDevice->DeviceString, (sizeof(lpDisplayDevice->DeviceString)/sizeof(TCHAR)), TEXT("DISPLAY"), (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)) - 1);
#else
	lstrcpyn((LPTSTR)lpDisplayDevice->DeviceName,   TEXT("DISPLAY"), (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)));
	lstrcpyn((LPTSTR)lpDisplayDevice->DeviceString, TEXT("DISPLAY"), (sizeof(lpDisplayDevice->DeviceString)/sizeof(TCHAR)));
#endif // _MULTIMON_USE_SECURE_CRT
#endif // UNICODE

	lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE;

	return TRUE;
}

#undef xPRIMARY_MONITOR
#undef COMPILE_MULTIMON_STUBS

#else   // COMPILE_MULTIMON_STUBS

extern int  WINAPI xGetSystemMetrics(int);
extern HMONITOR WINAPI xMonitorFromWindow(HWND, DWORD);
extern HMONITOR WINAPI xMonitorFromRect(LPCRECT, DWORD);
extern HMONITOR WINAPI xMonitorFromPoint(POINT, DWORD);
extern BOOL WINAPI xGetMonitorInfo(HMONITOR, LPMONITORINFO);
extern BOOL WINAPI xEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
extern BOOL WINAPI xEnumDisplayDevices(PVOID, DWORD, PDISPLAY_DEVICE, DWORD);

#endif  // COMPILE_MULTIMON_STUBS

//
// build defines that replace the regular APIs with our versions
//
#define GetSystemMetrics	xGetSystemMetrics
#define MonitorFromWindow   xMonitorFromWindow
#define MonitorFromRect	 xMonitorFromRect
#define MonitorFromPoint	xMonitorFromPoint
#define GetMonitorInfo	  xGetMonitorInfo
#define EnumDisplayMonitors xEnumDisplayMonitors
#define EnumDisplayDevices  xEnumDisplayDevices

#ifdef __cplusplus
}
#endif  // __cplusplus
</winapi.au3></array.au3> Edited by UEZ

Share this post


Link to post
Share on other sites

Posted

Newbie on this section...

Thanks UEZ, honestly you and me both.

Share this post


Link to post
Share on other sites

Posted

This also contains tons of useful infos.

Share this post


Link to post
Share on other sites

Posted

Thanks KaFu. I will have a look tomorrow and see if it works.

Share this post


Link to post
Share on other sites

Posted (edited)

@UEZ,

Your dllstructcreate will fail because "RECT" is not a known data type.Try using "long rcMonitor[4];" instead and comment out the lines

;DllStructSetData($MONITORINFO, "rcMonitor", DllStructGetPtr($struct_rcMonitor))

;DllStructSetData($MONITORINFO, "rcWork", DllStructGetPtr($struct_rcWork))

Also structs should not have a semicolon at the end of all the elements I don't think.

and then you have used $MONITORINFO when you meant to use $struct_MONITORINFO in one place.

The last problem I can see is you need to use "hwnd" instead of "handle" in the call to GetMonitorInfo.

(I think trancexx has a udf somewhere which lets you add a struct inside a struct.)

Edited by martin

Share this post


Link to post
Share on other sites

Posted

@martin: thanks for the information but it seems still not to work properly!

I have to work more on the WinAPI stuff to get more knowledge how to utilize the information from MSDN properly in AutoIt.

Update the code from above.

Br,

UEZ

Share this post


Link to post
Share on other sites

Posted

@martin: thanks for the information but it seems still not to work properly!

I have to work more on the WinAPI stuff to get more knowledge how to utilize the information from MSDN properly in AutoIt.

Br,

UEZ

Wideboydixon showed maybe it will help.

Share this post


Link to post
Share on other sites

Posted

Regarding issues with calling GetMonitorInfo - let me save you the trouble. I pulled the below functions from one of the UDF's I was using to enhanced my Full-Screen Crash Recovery thing.. there's more to it than this (multi-monitor info, power-toggling) but I hadn't thought to release it as a UDF..

#include <WinAPI.au3>
; ===================================================================================================================
; Func _GraphicsCreateDC($sDriver="DISPLAY",$sDevice=0,$pInitData=0)
;
; Function to create a Device Context. With default parameters, it will create a DC covering ALL monitors, rather
;    than getting only the default monitor with GetDC(0)
;    *NOTE: When done with the DC, must use DeleteDC on the returned DC (whereas GetDC uses ReleaseDC)
;
; Author: Ascend4nt
; ===================================================================================================================

Func _GraphicsCreateDC($sDriver="DISPLAY",$sDevice=0,$pInitData=0)
    If Not IsString($sDriver) Then Return SetError(1,0,False)
    Local $aRet,$sDeviceType
    If $sDevice="" Or Not IsString($sDevice) Then
        $sDeviceType="ptr"
        $sDevice=0
    Else
        $sDeviceType="wstr"
    EndIf
    $aRet=DllCall('gdi32.dll',"handle","CreateDCW","wstr",$sDriver,$sDeviceType,$sDevice,"ptr",0,"ptr",$pInitData)
    If @error Then Return SetError(2,@error,0)
    If $aRet[0]=0 Then Return SetError(3,0,0)
    Return $aRet[0]
EndFunc

; ==========================================================================================================================
; Func _MonitorGetInfo($hMonitor,$hMonitorDC=0)
;
; Gets information about a monitor (given a monitor handle).
;
; $hMonitor = Handle to Monitor
; $hMonitorDC = Optional Monitor DC
;
; Returns:
;    Success: 10-element array, with @error=0:
;        $array[0]  = Monitor  upper-left corner X coordinate (this rect is same as full-screen size)
;        $array[1]  = Monitor  upper-left corner Y coordinate
;        $array[2]  = Monitor lower-right corner X coordinate
;        $array[3]  = Monitor lower-right corner Y coordinate
;        $array[4]  = Monitor Work Area  upper-left corner X coordinate (this rect is same as maximized size)
;        $array[5]  = Monitor Work Area  upper-left corner Y coordinate
;        $array[6]  = Monitor Work Area lower-right corner X coordinate
;        $array[7]  = Monitor Work Area lower-right corner Y coordinate
;        $array[8]  = Primary monitor boolean (0 = not, 1 = is)
;        $array[9]  = Monitor Or Display Device Name (usually '.DISPLAY#' where # starts at 1)
;        $array[10] = Bits Per Pixel
;        $array[11] = Vertical Refresh Rate
;    Failure: '' with @error set:
;        @error = 1 = invalid parameter
;        @error = 2 = DLLCall() error, with @extended set to DLLCall() error code (see AutoIt Help)
;        @error = 3 = API call failed
;
; Author: Ascend4nt
; ==========================================================================================================================

Func _MonitorGetInfo($hMonitor,$hMonitorDC=0)
    If Not IsPtr($hMonitor) Or $hMonitor=0 Then Return SetError(1,0,'')
    ; cbSize, rcMonitor (virtual rect of monitor), rcWork (maximized state of window [minus taskbar, sidebar etc]), dwFlags
    Local $aRet,$stMonInfoEx=DllStructCreate('dword;long[8];dword;wchar[32]'),$bMonDCCreated=0
    DllStructSetData($stMonInfoEx,1,DllStructGetSize($stMonInfoEx))        ; set cbSize
    $aRet=DllCall('user32.dll','bool','GetMonitorInfoW','handle',$hMonitor,'ptr',DllStructGetPtr($stMonInfoEx))
    If @error Then Return SetError(2,0,'')
    If Not $aRet[0] Then Return SetError(3,0,'')
    Dim $aRet[12]
    ; Both RECT's
    For $i=0 To 7
        $aRet[$i]=DllStructGetData($stMonInfoEx,2,$i+1)
    Next
    ; 0 or 1 for Primary Monitor [MONITORINFOF_PRIMARY = 1]
    $aRet[8]=DllStructGetData($stMonInfoEx,3)
    ; Device String of type '.DISPLAY1' etc
    $aRet[9]=DllStructGetData($stMonInfoEx,4)
    If $hMonitorDC=0 Then
        $hMonitorDC=_GraphicsCreateDC($aRet[9],$aRet[9])
        $bMonDCCreated=1
    EndIf
    $aRet[10]=_WinAPI_GetDeviceCaps($hMonitorDC,12)    ; Bits-Per-Pixel
    $aRet[11]=_WinAPI_GetDeviceCaps($hMonitorDC,116)    ; Vertical Refresh Rate (Hz)
    If $bMonDCCreated Then _WinAPI_DeleteDC($hMonitorDC)
;~     ConsoleWrite("BitsPerPixel="&$aRet[10]&", Refresh Rate="&$aRet[11]&" Hz"&@CRLF)
    Return $aRet
EndFunc

; ==========================================================================================================================
; Func _MonitorFromWindow($hWnd,$iFlags=2)
;
; Gets monitor handle based on Window handle
;
; $iFlags: 0-2:  (if window doesn't 'intersect' any monitor [i.e. - its off-screen])
;    MONITOR_DEFAULTTONULL (0)
;    MONITOR_DEFAULTTOPRIMARY (1)
;    MONITOR_DEFAULTTONEAREST (2)
;
; Author: Ascend4nt
; ==========================================================================================================================

Func _MonitorFromWindow($hWnd,$iFlags=2)
    If Not IsHWnd($hWnd) Or $iFlags<0 Or $iFlags>2 Then Return SetError(1,0,0)
    Local $aRet=DllCall('user32.dll','handle','MonitorFromWindow','hwnd',$hWnd,'dword',$iFlags)
    If @error Then Return SetError(2,@error,0)
    If $aRet[0]=0 Then Return SetError(3,0,0)
    Return $aRet[0]
EndFunc

; TEST CODE

#include <Array.au3>
$hWnd=WinGetHandle('[CLASS:Shell_TrayWnd]')
$hMonitor=_MonitorFromWindow($hWnd)
$aMonInfo=_MonitorGetInfo($hMonitor)

$aMonInfo[8]="Primary? = "&$aMonInfo[8]&" (0=no,1=yes)"
$aMonInfo[10]&=" bpp"
$aMonInfo[11]="Refresh Rate: "&$aMonInfo[11]&" Hz"

_ArrayDisplay($aMonInfo,"Start Menu Bar ("&$hWnd&")")

Share this post


Link to post
Share on other sites

Posted

@Ascend4nt: nice function!

Br,

UEZ

Share this post


Link to post
Share on other sites

Posted

Thanks Ascend4nt. I will test tomorrow.

Share this post


Link to post
Share on other sites

Posted

Tidied up the example by removing the usage of magic numbers.

Share this post


Link to post
Share on other sites

Posted

Updated the example and function to working with v3.3.12.0 syntax.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Recently Browsing   0 members

    No registered users viewing this page.