Click to See Complete Forum and Search --> : EnumDisplayMonitors


Kdev
April 25th, 2001, 11:51 AM
I'm having trouble enumerating the display monitors. I have the following code in a module:

private Declare Function EnumDisplayMonitors Lib "user32.dll" _
(byval lHdc as Long, lpCRect as long, _
MonitorEnumProc as Long, byval LPARAM as Long) as Long


public Function EnumAllMonitorsProc( _
HMONITOR as Long, _
HDC as Long, _
LPRECT as Long, _
LPARAM as Long) as Long


MsgBox HMONITOR & vbNewLine & HDC & vbNewLine & _
LPRECT & vbNewLine & LPARAM

EnumAllMonitorsProc = true
End Function


And then In my form:
private Sub Command1_Click()
dim rc
rc = EnumDisplayMonitors(vbNull, vbNull, AddressOf EnumAllMonitorsProc, 0)
If rc = 0 then MsgBox LastSystemError
End Sub



The problem is that if, according to MSDN, EnumDisplayMonitors fails it should return 0 else it should return non-zero. When I press the command button the function is returning 0 and the LastSystemError function (taken from www.merrioncomputing.com thanks to ClearCode) returns "The operation completed successfully.". However, I know this not to be true. If anyone has experience with the EnumDisplayMonitors function please help. I had to write the declaration myself from the MSDN (c++ version).

-K

Ungi
September 4th, 2002, 03:00 AM
had been a long time since this thread was started but I think I found a little mistake. dont know if it is the solution of the problem but,....

public Function EnumAllMonitorsProc( _
HMONITOR as Long, _
HDC as Long, _
LPRECT as Long, _
LPARAM as Long) as Long

In the MSDN the Functionvalue is not long but boolean!!! Should be:

public Function EnumAllMonitorsProc( _
HMONITOR as Long, _
HDC as Long, _
LPRECT as Long, _
LPARAM as Long) as Boolean


hope it helps

Ungi
September 4th, 2002, 03:52 AM
i'm sorry but it doesn't work... I have the same problem as Kdev.

Does anybody have any idea how to solve the problem???

hopkinsedwarde
March 31st, 2006, 03:45 PM
I am starting in on multi-monitor support for a VB 6.0 app and found your posts, looks like this thread hasn't been updated in several years, but the originally posted code is not passing a valid device context handle for one thing, which you can get ahold of in VB (not nearly as easy to manage these issues as in VC++). I suspect there are smoother ways of doing this in the managed code libraries available in Dot Net and beyond but we're still using 6.0 so I'll hack around with this and post the results.

hopkinsedwarde
March 31st, 2006, 05:53 PM
The trick here is that you need to use the windows RECT type. If you don't care about the clipping rectangle, then you don't actually need to send this, according to the MSDN:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/monitor_82yb.asp

You can send NULL. However, NULL in VC++ is really a zero, and vbNull is a 1.

Plus, in the Win32 declaration you need to fool it by sending a long instead of a reference to the Windows RECT, which is what I expected originally. However, in the return function you do need to use the RECT object.

Working code follows.


In the calling form:

Private Sub cmdTest_Click()
Dim blnRetVal As Boolean

blnRetVal = EnumDisplayMonitors(0, 0, AddressOf EnumAllMonitorsProc, 0)

If Not blnRetVal Then
Call MsgBox(Str(Err.LastDllError))
End If
End Sub


In a global module (*.bas):

Public Type WindowsRect
lngLeft As Long
lngTop As Long
lngRight As Long
lngBottom As Long
End Type

Public Declare Function EnumDisplayMonitors Lib "user32.dll" ( _
ByVal lngHDC As Long, _
ByVal lngPointer As Long, _
ByVal lngProcAddress As Long, _
ByVal lngParam As Long) As Boolean

Public Function EnumAllMonitorsProc( _
ByVal lngHMon As Long, _
ByVal lngHDC As Long, _
ByRef objRect As WindowsRect, _
ByVal lngParam As Long) As Boolean

Dim strMessage As String


strMessage = ""
strMessage = strMessage & Str(lngHMon) & vbNewLine
strMessage = strMessage & Str(lngHDC) & vbNewLine
strMessage = strMessage & Str(objRect.lngLeft) & ", " & Str(objRect.lngTop) & ", " & Str(objRect.lngRight) & ", " & Str(objRect.lngBottom) & vbNewLine
strMessage = strMessage & Str(lngParam)

Call MsgBox(strMessage)

EnumAllMonitorsProc = True
End Function