Results 1 to 31 of 31

Thread: Test if second Monitor switched on

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2011
    Posts
    498

    Test if second Monitor switched on

    I have an app that was opened and moved to show on the 2nd monitor at work.
    We sometimes work from home and only have one monitor.
    Today I had to go into the settings to reset the Left property of the form to Zero
    so that the form would be visible on Monitor 1.

    I am looking for a way at program startup that can check if the 2nd monitor is active, if not then
    reset Left to Zero automatically so it can be seen on the a single monitor.

    Pls note that we are connecting via remote desktop.

    can anyone help.

    tks
    Last edited by Shaggy Hiker; Dec 4th, 2021 at 07:43 PM.

  2. #2
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Test if second Monitor switched on

    Form1.frm:

    Code:
    Option Explicit
    
    Private Const WIN32_NULL As Long = 0
    
    Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
    
    Private Declare Function GetWindowRect Lib "user32" ( _
        ByVal hWnd As Long, _
        ByRef RECT As RECT) As Long
    
    Private Enum MFR_FLAGS
        MONITOR_DEFAULTTONULL = &H0&
        MONITOR_DEFAULTTOPRIMARY = &H1&
        MONITOR_DEFAULTTONEAREST = &H2&
    End Enum
    
    Private Declare Function MonitorFromRect Lib "user32" ( _
        ByRef RECT As RECT, _
        ByVal dwFlags As MFR_FLAGS) As Long
    
    Private Sub cmdIsForm2OnScreen_Click()
        Dim RECT As RECT
    
        If GetWindowRect(Form2.hWnd, RECT) Then
            If MonitorFromRect(RECT, MONITOR_DEFAULTTONULL) = WIN32_NULL Then
                MsgBox "No, it is offscreen"
            Else
                MsgBox "Yes"
            End If
        Else
            MsgBox "GetWindowRect error " & CStr(Err.LastDllError)
        End If
    End Sub
    
    Private Sub cmdMoveForm2ToPrimary_Click()
        Form2.Move 0, 0
    End Sub
    
    Private Sub cmdShowForm2_Click()
        Form2.Show vbModeless, Me
    End Sub
    Form2.frm:

    Code:
    Option Explicit
    
    Private Sub cmdMoveOffScreen_Click()
        Move -2 * Width, -2 * Height 'Or somewhere else not on any monitor.
    End Sub

  3. #3
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: Test if second Monitor switched on

    In a BAS module:

    Code:
    
    Option Explicit
    Public Type RECT
        Left   As Long
        Top    As Long
        Right  As Long ' This is +1 (right - left = width)
        Bottom As Long ' This is +1 (bottom - top = height)
    End Type
    Private Declare Function EnumDisplayMonitors Lib "user32" (ByVal hDC As Long, lprcClip As Any, ByVal lpfnEnum As Long, dwData As Long) As Long
    
    
    Public Function MonitorCount() As Long
        ' This does NOT count disabled monitors.
        EnumDisplayMonitors 0&, ByVal 0&, AddressOf MonitorCountEnum, MonitorCount
    End Function
    
    Private Function MonitorCountEnum(ByVal hMonitor As Long, ByVal hdcMonitor As Long, uRect As RECT, dwData As Long) As Long
        dwData = dwData + 1
        MonitorCountEnum = 1 ' Count them all.
    End Function
    
    
    
    Quick test in Form1:
    Code:
    
    Private Sub Form_Load()
        Debug.Print MonitorCount
    End Sub
    
    

    Ahhh, Dil beat me to the "Submit Reply" button, but mine's less code.
    Last edited by Elroy; Dec 2nd, 2021 at 04:11 PM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  4. #4
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Test if second Monitor switched on

    I fail to see how a count of monitors helps much. What if there are 3 monitors? Or 2 but arranged differently from the program's startup assumptions about Form positioning?

    Better to test whether the Form in question is displayed on any monitor, and if not move it where it will be visible. Then the user can drag it wherever after that.

  5. #5
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: Test if second Monitor switched on

    I thought we were just testing to see if we had one monitor or two.

    Ahhh, I see. Yeah, that sometimes happens to me too, but I typically do my development on my primary monitor, regardless of where that's positioned among the monitors.

    However, in my primary application, I do have certain forms that "remember" where they were last. But, they also must check to make sure they're visible.

    Let me get that code too. Ahhhh, here's some code on how I do it:

    Code:
    
        Top = GetSetting(App.Title, "Settings", "TekscanControllerTop", -15&)
        Left = GetSetting(App.Title, "Settings", "TekscanControllerLeft", -15&)
        If Not FormIsFullyOnMonitor(Me) Then CenterOnPrimaryMonitor Me
    
    
    k_zeon, if you think that FormIsFullyOnMonitor procedure or the CenterOnPrimaryMonitor procedure will help you, let me know.

    Otherwise, to do it in the IDE would take an Add-In. I've never found the need, as setting the Left property on the Properties Window to zero is easy enough.
    Last edited by Elroy; Dec 2nd, 2021 at 04:23 PM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  6. #6
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Test if second Monitor switched on

    Silly wabbit, thread titles are for obfuscation.

  7. #7

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2011
    Posts
    498

    Re: Test if second Monitor switched on

    Quote Originally Posted by Elroy View Post
    I thought we were just testing to see if we had one monitor or two.

    Ahhh, I see. Yeah, that sometimes happens to me too, but I typically do my development on my primary monitor, regardless of where that's positioned among the monitors.

    However, in my primary application, I do have certain forms that "remember" where they were last. But, they also must check to make sure they're visible.

    Let me get that code too. Ahhhh, here's some code on how I do it:

    Code:
    
        Top = GetSetting(App.Title, "Settings", "TekscanControllerTop", -15&)
        Left = GetSetting(App.Title, "Settings", "TekscanControllerLeft", -15&)
        If Not FormIsFullyOnMonitor(Me) Then CenterOnPrimaryMonitor Me
    
    
    k_zeon, if you think that FormIsFullyOnMonitor procedure or the CenterOnPrimaryMonitor procedure will help you, let me know.

    Otherwise, to do it in the IDE would take an Add-In. I've never found the need, as setting the Left property on the Properties Window to zero is easy enough.
    Hi Elroy.
    Just after i posted , i did find code that checks to see if on visible screen ,if not then it puts it there.
    I found it on this website a function called EnsureFormIsInsideMonitor me
    Code:
    https://www.vbforums.com/showthread.php?697863-VB-Appliation-on-Extended-Monitors&highlight=EnsureFormIsInsideMonitor
    I have not tested yet as i dont have a second monitor attached to my development machine, but i will have tomo.
    I am hoping that if i exit my app in screen 2 and save its form positions.
    If i then switch off screen 2 and then re run my app, it should then show on monitor 1.

    I would be very interested in your ' If Not FormIsFullyOnMonitor(Me) Then CenterOnPrimaryMonitor Me ' functions.

    tks

  8. #8

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2011
    Posts
    498

    Re: Test if second Monitor switched on

    Quote Originally Posted by dilettante View Post
    Form1.frm:

    Code:
    Option Explicit
    
    Private Const WIN32_NULL As Long = 0
    
    Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
    
    Private Declare Function GetWindowRect Lib "user32" ( _
        ByVal hWnd As Long, _
        ByRef RECT As RECT) As Long
    
    Private Enum MFR_FLAGS
        MONITOR_DEFAULTTONULL = &H0&
        MONITOR_DEFAULTTOPRIMARY = &H1&
        MONITOR_DEFAULTTONEAREST = &H2&
    End Enum
    
    Private Declare Function MonitorFromRect Lib "user32" ( _
        ByRef RECT As RECT, _
        ByVal dwFlags As MFR_FLAGS) As Long
    
    Private Sub cmdIsForm2OnScreen_Click()
        Dim RECT As RECT
    
        If GetWindowRect(Form2.hWnd, RECT) Then
            If MonitorFromRect(RECT, MONITOR_DEFAULTTONULL) = WIN32_NULL Then
                MsgBox "No, it is offscreen"
            Else
                MsgBox "Yes"
            End If
        Else
            MsgBox "GetWindowRect error " & CStr(Err.LastDllError)
        End If
    End Sub
    
    Private Sub cmdMoveForm2ToPrimary_Click()
        Form2.Move 0, 0
    End Sub
    
    Private Sub cmdShowForm2_Click()
        Form2.Show vbModeless, Me
    End Sub
    Form2.frm:

    Code:
    Option Explicit
    
    Private Sub cmdMoveOffScreen_Click()
        Move -2 * Width, -2 * Height 'Or somewhere else not on any monitor.
    End Sub
    tks dilettante. will try this tomo

  9. #9
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: Test if second Monitor switched on

    It's a bit of code, and it must go into a BAS module. I stripped it out of a much larger module that does all kinds of things with monitors.

    But here's the fully functioning code for FormIsFullyOnMonitor and CenterOnPrimaryMonitor:

    Code:
    
    Option Explicit
    '
    Public Type RECT
        Left   As Long
        Top    As Long
        Right  As Long ' This is +1 (right - left = width)
        Bottom As Long ' This is +1 (bottom - top = height)
    End Type
    Private Type MONITORINFO
        cbSize As Long
        rcMonitor As RECT
        rcWork As RECT
        dwFlags As Long
    End Type
    '
    Public Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long
    Public Declare Function MoveWindow Lib "user32" (ByVal hWnd As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, Optional ByVal bRepaint As Long = 1&) As Long
    '
    Private Declare Function GetMonitorInfo Lib "user32.dll" Alias "GetMonitorInfoA" (ByVal hMonitor As Long, ByRef lpmi As MONITORINFO) As Long
    Private Declare Function MonitorFromWindow Lib "user32.dll" (ByVal hWnd As Long, ByVal dwFlags As Long) As Long
    Private Declare Function EnumDisplayMonitors Lib "user32" (ByVal hDC As Long, lprcClip As Any, ByVal lpfnEnum As Long, dwData As Long) As Long
    '
    
    
    Public Function FormIsFullyOnMonitor(frm As Form) As Boolean
        ' This tells us whether or not a form is FULLY visible on its monitor.
        '
        Dim hMonitor As Long
        Dim r1 As RECT
        Dim r2 As RECT
        Dim uMonInfo As MONITORINFO
        '
        hMonitor = hMonitorForForm(frm)
        GetWindowRect frm.hWnd, r1
        uMonInfo.cbSize = LenB(uMonInfo)
        GetMonitorInfo hMonitor, uMonInfo
        r2 = uMonInfo.rcWork
        '
        FormIsFullyOnMonitor = (r1.Top >= r2.Top) And (r1.Left >= r2.Left) And (r1.Bottom <= r2.Bottom) And (r1.Right <= r2.Right)
    End Function
    
    Public Sub CenterOnPrimaryMonitor(frm As Form, _
                                      Optional bUseWorkingArea As Boolean = True, _
                                      Optional iWidthDivisor As Long = 2&, _
                                      Optional iHeightDivisor As Long = 3&)
        ' Works with new Win10 scaling.
        '
        ' This will work anytime after (or within) Form_Load.
        Dim hMonitor As Long
        hMonitor = hPrimaryMonitor
        CenterFormOnMonitor frm, hPrimaryMonitor, True, iWidthDivisor, iHeightDivisor
        If frm.Top < 0 Then frm.Top = 0
    End Sub
    
    Public Function hMonitorForForm(frm As Form) As Long
        ' The monitor that the window is MOSTLY on.
        Const MONITOR_DEFAULTTONULL = &H0
        hMonitorForForm = MonitorFromWindow(frm.hWnd, MONITOR_DEFAULTTONULL)
    End Function
    
    Public Function hPrimaryMonitor() As Long
        ' This is the primary monitor.
        EnumDisplayMonitors 0&, ByVal 0&, AddressOf PrimaryMonitorHandleEnum, hPrimaryMonitor
    End Function
    
    Public Sub CenterFormOnMonitor(frm As Form, _
                                   Optional ByVal hMonitor As Long = True, _
                                   Optional bUseWorkingArea As Boolean, _
                                   Optional iWidthDivisor As Long = 2&, _
                                   Optional iHeightDivisor As Long = 3&)
        ' This works with new Win10 scaling.
        Dim lLeft As Long
        Dim lTop As Long
        '
        If MonitorWidthPx(hMonitor) = 0 Then
            hMonitor = hPrimaryMonitor
            If hMonitor = 0 Then Exit Sub       ' Something wrong.
        End If
        If bUseWorkingArea Then
            lLeft = (MonitorWidthPx(hMonitor, True) - WindowWidthInPixels(frm.hWnd)) \ iWidthDivisor
            lTop = (MonitorHeightPx(hMonitor, True) - WindowHeightInPixels(frm.hWnd)) \ iHeightDivisor
        Else
            lLeft = (MonitorWidthPx(hMonitor, False) - WindowWidthInPixels(frm.hWnd)) \ iWidthDivisor
            lTop = (MonitorHeightPx(hMonitor, False) - WindowHeightInPixels(frm.hWnd)) \ iHeightDivisor
        End If
        PositionFormOnMonitor frm, hMonitor, lLeft, lTop
    End Sub
    
    Public Sub PositionFormOnMonitor(frm As Form, _
                                     hMonitor As Long, _
                                     ByVal lLeftPixel As Long, _
                                     ByVal lTopPixel As Long)
        ' This can be used to position windows on other programs so long as you have the hWnd.
        Dim lHeight As Long
        Dim lWidth As Long
        '
        lHeight = WindowHeightInPixels(frm.hWnd)
        lWidth = WindowWidthInPixels(frm.hWnd)
        '
        lLeftPixel = lLeftPixel + MonitorLeftPx(hMonitor)
        lTopPixel = lTopPixel + MonitorTopPx(hMonitor)
        '
        MoveWindow frm.hWnd, lLeftPixel, lTopPixel, lWidth, lHeight
    End Sub
    
    Public Function MonitorWidthPx(hMonitor As Long, Optional bUseWorkingArea As Boolean) As Long
        Dim uMonInfo As MONITORINFO
        '
        uMonInfo.cbSize = LenB(uMonInfo)
        If GetMonitorInfo(hMonitor, uMonInfo) = 0 Then Exit Function
        '
        If bUseWorkingArea Then ' The "Work" verions exclude the taskbar.
            MonitorWidthPx = uMonInfo.rcWork.Right - uMonInfo.rcWork.Left
        Else
            MonitorWidthPx = uMonInfo.rcMonitor.Right - uMonInfo.rcMonitor.Left
        End If
    End Function
    
    Public Function MonitorHeightPx(hMonitor As Long, Optional bUseWorkingArea As Boolean) As Long
        Dim uMonInfo As MONITORINFO
        uMonInfo.cbSize = LenB(uMonInfo)
        If GetMonitorInfo(hMonitor, uMonInfo) = 0 Then Exit Function
        '
        If bUseWorkingArea Then ' The "Work" verions exclude the taskbar.
            MonitorHeightPx = uMonInfo.rcWork.Bottom - uMonInfo.rcWork.Top
        Else
            MonitorHeightPx = uMonInfo.rcMonitor.Bottom - uMonInfo.rcMonitor.Top
        End If
    End Function
    
    Public Function MonitorLeftPx(hMonitor As Long, Optional bUseWorkingArea As Boolean) As Long
        Dim uMonInfo As MONITORINFO
        uMonInfo.cbSize = LenB(uMonInfo)
        If GetMonitorInfo(hMonitor, uMonInfo) = 0 Then Exit Function
        '
        If bUseWorkingArea Then ' The "Work" verions exclude the taskbar.
            MonitorLeftPx = uMonInfo.rcWork.Left
        Else
            MonitorLeftPx = uMonInfo.rcMonitor.Left
        End If
    End Function
    
    Public Function MonitorTopPx(hMonitor As Long, Optional bUseWorkingArea As Boolean) As Long
        Dim uMonInfo As MONITORINFO
        uMonInfo.cbSize = LenB(uMonInfo)
        If GetMonitorInfo(hMonitor, uMonInfo) = 0 Then Exit Function
        '
        If bUseWorkingArea Then ' The "Work" verions exclude the taskbar.
            MonitorTopPx = uMonInfo.rcWork.Top
        Else
            MonitorTopPx = uMonInfo.rcMonitor.Top
        End If
    End Function
    
    Public Function WindowHeightInPixels(hWndOfInterest As Long) As Long
        Dim r As RECT
        GetWindowRect hWndOfInterest, r
        WindowHeightInPixels = r.Bottom - r.Top
    End Function
    
    Public Function WindowWidthInPixels(hWndOfInterest As Long) As Long
        Dim r As RECT
        GetWindowRect hWndOfInterest, r
        WindowWidthInPixels = r.Right - r.Left
    End Function
    
    
    
    
    
    Private Function PrimaryMonitorHandleEnum(ByVal hMonitor As Long, ByVal hdcMonitor As Long, uRect As RECT, dwData As Long) As Long
        Const MONITORINFOF_PRIMARY = &H1
        Dim uMonInfo As MONITORINFO
        uMonInfo.cbSize = LenB(uMonInfo)
        GetMonitorInfo hMonitor, uMonInfo
        If uMonInfo.dwFlags = MONITORINFOF_PRIMARY Then
            dwData = hMonitor
            PrimaryMonitorHandleEnum = 0 ' Found it.
        Else
            PrimaryMonitorHandleEnum = 1 ' Keep looking.
        End If
    End Function
    
    
    
    
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  10. #10
    Frenzied Member
    Join Date
    Mar 2008
    Posts
    1,210

    Re: [RESOLVED] Test if second Monitor switched on

    >I have not tested yet as i dont have a second monitor attached to my development machine, but i will have tomo.

    So how's it going?

  11. #11

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2011
    Posts
    498

    Re: [RESOLVED] Test if second Monitor switched on

    Quote Originally Posted by Magic Ink View Post
    >I have not tested yet as i dont have a second monitor attached to my development machine, but i will have tomo.

    So how's it going?
    I'm glad you asked. Not so good. I have tried all options i have been given and none seem to work as expected.

    Elroy & dilettante , i tried the codes above and the ones i mentioned and neither do what i need. can you help

    I have a system setup with 2 monitors. Monitor 1 is Primary, Monitor 2 is Secondary
    I run an app ie just a single form. As it loads it positions itself based on where it was last. ie on the 2nd monitor.
    I close the app. Switch off monitor 2.
    If i now re run the app, it shows in the task bar, but not on Monitor 1. Its still showing on Monitor 2 even though its not switched on.

    I need to find a way that if monitor 2 is not on, then it defaults to monitor 1.

    Just tried this and its does not appear to do that. I have been googling for a few hours and not sure there is an api to check the power state of a monitor.
    If i could do a check at startup like If Monitor2 = off then put form on Monitor1

    any help

    tks
    Last edited by k_zeon; Dec 3rd, 2021 at 05:16 PM.

  12. #12
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: [RESOLVED] Test if second Monitor switched on

    Ok, we're talking about a compiled EXE?

    If that's the case, my code in post #5 (with the support code in post #9) should do it.

    If we're talking about designer forms in the IDE, that'll take an Add-In.

    k_zeon, maybe post an example of what's not working for you.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  13. #13
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: [RESOLVED] Test if second Monitor switched on

    Ok, another problem. If you just turn a monitor off, Windows doesn't seem to be smart enough to get rid of that monitor from the desktop. At a minimum, you need to logoff and log back on. Is that what we're talking about?
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  14. #14

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2011
    Posts
    498

    Re: [RESOLVED] Test if second Monitor switched on

    Quote Originally Posted by Elroy View Post
    Ok, we're talking about a compiled EXE?

    If that's the case, my code in post #5 (with the support code in post #9) should do it.

    If we're talking about designer forms in the IDE, that'll take an Add-In.

    k_zeon, maybe post an example of what's not working for you.
    Hi Elroy

    i have tested your example on a system that has 2 monitors.
    I can drag my exe form from Monitor 1 to Monitor 2
    I can then close the app.exe . Re Open and it opens on Monitor 2. All good so far.
    If i close my exe form and then manually power of Monitor 2 and the reopen my exe it will show on the taskbar of Monitor 1
    but its not shown on Monitor 1, its shown on Monitor 2 even though Monitor 2 is off. I need to switch Monitor 2 back on and drag the form exe back to Monitor 1

    I have a project that i can zip up but not sure where to post it.?

    tks

  15. #15

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2011
    Posts
    498

    Re: [RESOLVED] Test if second Monitor switched on

    Quote Originally Posted by Elroy View Post
    Ok, another problem. If you just turn a monitor off, Windows doesn't seem to be smart enough to get rid of that monitor from the desktop. At a minimum, you need to logoff and log back on. Is that what we're talking about?

    yes correct.

  16. #16

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2011
    Posts
    498

    Re: [RESOLVED] Test if second Monitor switched on

    Quote Originally Posted by Elroy View Post
    Ok, another problem. If you just turn a monitor off, Windows doesn't seem to be smart enough to get rid of that monitor from the desktop. At a minimum, you need to logoff and log back on. Is that what we're talking about?
    I did some research and dont think the is an API to detect the powerstate of monitors. Maybe wrong ?

  17. #17
    Frenzied Member
    Join Date
    Mar 2008
    Posts
    1,210

    Re: [RESOLVED] Test if second Monitor switched on

    With reference to my code from https://www.vbforums.com/showthread....sInsideMonitor which you referenced in post #7 there is a rem in there which states '' * disconnected means unplugged; a monitor which is switched off remains 'connected' as long as it is plugged-in via e.g. its VGA lead." I never found a way or API to overcome that short coming.
    I seem to remember that the 'problem' persists after a reboot and the computer continues to 'use' the physically connected but unwanted monitor even when it is turned off, the monitor has to be physically disconnected to correct the situation. It could be that the situation (Windows OS) has changed since it was a hot topic for me back in the early 20teens, eg. Windows now allows DPI to be set on a per monitor basis.

  18. #18

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2011
    Posts
    498

    Re: [RESOLVED] Test if second Monitor switched on

    So, does anyone know if what i am after can be done. Some obscure API that can get the powerstate of a specific monitor. tks

  19. #19

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2011
    Posts
    498

    Re: [RESOLVED] Test if second Monitor switched on

    I found this posted. Does anyone know how to use this in VB6 if at all possible. tks

    Code:
    https://www.generacodice.com/en/articolo/45110/Is-there-any-way-to-detect-the-monitor-state-in-Windows-(on-or-off)
    This is a really old post but if it can help someone, I have found a solution to detect a screen being available or not : the Connecting and Configuring Displays (CCD) API of Windows.

    It's part of User32.ddl and the interesting functions are GetDisplayConfigBufferSizes and QueryDisplayConfig. It give us all informations that can be viewed in the Configuration Panel of windows.

    In particular the PathInfo contains a TargetInfo property that have a targetAvailable flag. This flag seems to be correctly updated on all the configurations I have tried so far.

    This allow you to know the state of every screens connected to the PC and set their configurations.
    Code:
    https://github.com/regueiro/CCDWrapper/tree/master/CCDWrapper
    Last edited by k_zeon; Dec 3rd, 2021 at 07:50 PM.

  20. #20

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2011
    Posts
    498

    Get Monitor Powerstate

    Hi. I have asked this question before and thought i had the answer. I dont.

    I need to check the powerstate of a 2nd Monitor when i start an app exe

    If 2nd Monitor On then position as before on 2nd Monitor.
    If 2nd Monitor Off then Position on Primary Monitor.

    Is there an API ir some other method to check the power state of monitors

    tks

  21. #21
    Frenzied Member
    Join Date
    Mar 2008
    Posts
    1,210

    Re: [RESOLVED] Test if second Monitor switched on

    Could be I am missing something but I wonder if this issue is a serious one.

    The typical situation is a laptop which is used at home with the built-in display only, and used at work where an additional monitor is available.

    So you are at work using the application on the additional monitor and close it down while it is on that monitor.
    Then you go home having disconnected/unplugged the additional monitor. With reference to the code discussed above it is possible to determine that Form placement must now be shifted to the primary and only display; and that done all is well.
    Then you go back to work and the app opens on the built-in monitor, if you want it on the additional monitor you just drag it there. You may apply further code as the app opens to place it on an alternative if more than a single monitor is available; albeit the target monitor chosen must be switched on.


    The only time the 'problem' is encountered is when using the app on a machine with multiple available (plugged-in) monitors and the monitor previously used is switched off, a possible circumstance but in practice an unlikely one. In such circumstances the user will probably be aware that if your app (or any other) app does not appear when run then the problem is likely to be because one of his monitors is switched off i.e. he will be having the same issue with other apps.

  22. #22
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: Get Monitor Powerstate

    I remember years ago there had been two VB classes by Microsoft pertaining to monitors, I am sure you can find them somewhere. I forgot what were the exact class names; let us assume one is called Monitor.cls and the other MultiMon.cls, then using a ListBox you will get a list of all the monitors in such a manner "\\.\Display1, \\.\Display2 ..." - the disconnected one(s) will not show up.
    Code:
    Set cMonitor = New clsMonitor
    lisMonitors.Clear
    For Each cMonitor In cMultiMon.colMonitors
        lisMonitors.AddItem cMonitor.name
    Next
    Please see if you would like to pursue this path.
    Last edited by Brenker; Dec 4th, 2021 at 03:16 PM.

  23. #23

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2011
    Posts
    498

    Re: [RESOLVED] Test if second Monitor switched on

    Quote Originally Posted by Magic Ink View Post
    Could be I am missing something but I wonder if this issue is a serious one.

    The typical situation is a laptop which is used at home with the built-in display only, and used at work where an additional monitor is available.

    So you are at work using the application on the additional monitor and close it down while it is on that monitor.
    Then you go home having disconnected/unplugged the additional monitor. With reference to the code discussed above it is possible to determine that Form placement must now be shifted to the primary and only display; and that done all is well.
    Then you go back to work and the app opens on the built-in monitor, if you want it on the additional monitor you just drag it there. You may apply further code as the app opens to place it on an alternative if more than a single monitor is available; albeit the target monitor chosen must be switched on.


    The only time the 'problem' is encountered is when using the app on a machine with multiple available (plugged-in) monitors and the monitor previously used is switched off, a possible circumstance but in practice an unlikely one. In such circumstances the user will probably be aware that if your app (or any other) app does not appear when run then the problem is likely to be because one of his monitors is switched off i.e. he will be having the same issue with other apps.
    Yes that is correct. I recently came across this issue. we have 2 monitors at work and my colleague had my app on monitor 2
    We leave the PC running but switch off both monitors.
    At home we only have 1 monitor and connect through remote desktop. so when he ran the app, he could see it in the task bar but not the form.
    I had to go into the registry and set the form left position to Zero.
    Then when he ran the app again, it appeared on the 1st (primary monitor)

    this is a big problem that i dont think there is a solution to.

    As i have seen mentioned many times , a monitor is only one way communication.

    So there is no status that checks if a monitor is switched on or off.

    not sure where to go from here

  24. #24

    Thread Starter
    Hyperactive Member
    Join Date
    Nov 2011
    Posts
    498

    Re: Get Monitor Powerstate

    Quote Originally Posted by Brenker View Post
    I remember years ago there had been two VB classes by Microsoft pertaining to monitors, I am sure you can find them somewhere. I forgot what were the exact class names; let us assume one is called Monitor.cls and the other MultiMon.cls, then using a ListBox you will get a list of all the monitors in such a manner "\\.\Display1, \\.\Display2 ..." - the disconnected one(s) will not show up.
    Code:
    Set cMonitor = New clsMonitor
    lisMonitors.Clear
    For Each cMonitor In cMultiMon.colMonitors
        lisMonitors.AddItem cMonitor.name
    Next
    Please see if you would like to pursue this path.
    I have tried the VBHelp method. see link

    http://vbnet.mvps.org/code/enums/enumdisplaydevices.htm

    Attachment 183201

    I have run app and wether the 2nd Monitor is On or Off , nothing changes.

    If anyone knows where to get the VB classes by Microsoft as mentioned above, would love to give it a go.

  25. #25
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: Get Monitor Powerstate

    Apparently a call to GetDevicePowerState "sometimes" works. Apparently, it depends on how much "feedback" the monitor gives to the Windows driver.

    Also, apparently a call to the get_Power method of the IMSVidDevice Interface has possibilities. That IMSVidDevice Interface is in the Quartz.dll. I was just playing around with that for other reasons. It's an ActiveX DLL, so just reference it and start instantiating objects with it (no API declarations needed).

    EDIT: Just an FYI ... that Quartz.dll is internally named "ActiveMovie", so that's what you'll see in your VB6 references.

    Good Luck. I'll be interested to see what you get going.

    And just to say it, I don't think any of the calls to "manipulate" or "enumerate" monitors are going to do this.
    Last edited by Elroy; Dec 4th, 2021 at 04:33 PM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  26. #26
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: [RESOLVED] Test if second Monitor switched on

    See my comments in your other thread. I haven't tested any of it though.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  27. #27
    Frenzied Member
    Join Date
    Mar 2008
    Posts
    1,210

    Re: [RESOLVED] Test if second Monitor switched on

    Seems strange that your RDP client is in someway aware of monitors plugged into the RDP server, I'm lost...

  28. #28
    Addicted Member
    Join Date
    May 2012
    Location
    42.787034,-81.176367
    Posts
    130

    Re: Get Monitor Powerstate

    If it can be done by MultiMonitorTool (Nirsoft), then VB6 should be able to do it.

    Note well that MultiMonitorTool.exe can be run from the command line, with various switches to Enable/disable/configure multiple monitors on Windows.

    If it cannot be done with VB6, one could always SHELL MultiMonitorTool.exe from VB6, with the appropriate command line switches.

    Name:  MultiMonitorTool.png
Views: 613
Size:  16.8 KB

    YMMV

    Joe

  29. #29
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    373

    Re: Get Monitor Powerstate

    @k_zeon: CodeGuru has the two classes. Their names are actually Monitor.cls and Monitors.cls

    https://forums.codeguru.com/showthre...7-Multimonitor

  30. #30
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,853

    Re: Get Monitor Powerstate

    I only have one monitor this weekend so I can't do much testing, but it seems that everyone just keeps circling back to the GetMonitorInfo and GetMonitorInfoEx API calls, which didn't work for me earlier this week.

    I did just download and take a look at the NirSoft MultiMonitorTool. I'll admit that it does have a "Disconnected" column, but it doesn't have an On/Off column. I'm guessing that it's also mostly using GetMonitorInfo and GetMonitorInfoEx as well. Joe, I see your screen shot, but I'm guessing that that actually should read "enable/disable" monitor, which really doesn't have anything to do with the monitor's power-state.

    It'd be nice if I was wrong, but we'll see.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  31. #31
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,988

    Re: Test if second Monitor switched on

    I merged the two threads to reduce any possible confusion and cross posting. It seems like an interesting question.
    My usual boring signature: Nothing

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width