In a dual-monitor system, finding out on which monitor a PowerPoint slideshow is displayed

后端 未结 3 1915
灰色年华
灰色年华 2020-12-21 16:53

In Powerpoint 2007/2010 run on a multiple monitor system, we can select the monitor on which the slideshow will be shown by going to \"Slide Show\"-> \"Set up slideShow\" ->

相关标签:
3条回答
  • 2020-12-21 17:12

    The code @JMax from Edwin Vermeer is really great. I'm sure I'll get smashed by the mods for this but I made the below diagram to show exactly what Sub test() in the code returns. Hopefully this will save another n00b an hour or two.

    Tip: Find-replace Dubug.Print with MsgBox and run through the code a few times with different monitor arrangements to make sure you understand the returns.

    The below is an odd monitor arrangement bet it demonstrates well the different returns you'll get:

    ...well it won't let me post pics until I have 10 reputation, diagrams are here:

    "Monitor" returns for Primary monitor

    "Work area" returns for Primary monitor

    "Monitor/Work area" returns for Secondary monitor

    (in the same album as the other 2, need 10 reputation to post >2 links...)

    0 讨论(0)
  • 2020-12-21 17:17

    Even if you already accepted Steve's answer. Here are a few useful snippets of code.

    You can get info about system monitor with this kind of code (found here):

    Attribute VB_Name = "MonitorInfo"
    Option Explicit
    
    Public Declare Function LoadLibraryEx Lib "kernel32.dll" Alias "LoadLibraryExA" (ByVal lpFileName As String, ByVal hFile As Long, ByVal dwFlags As Long) As Long
    Public Declare Function GetProcAddress Lib "kernel32.dll" (ByVal hModule As Long, ByVal lpProcName As String) As Long
    Public Declare Function GetModuleHandle Lib "kernel32.dll" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
    Public Declare Function FreeLibrary Lib "kernel32.dll" (ByVal hLibModule As Long) As Boolean
    Public Declare Function EnumDisplayMonitors Lib "user32.dll" (ByVal hdc As Long, ByRef lprcClip As Any, ByVal lpfnEnum As Long, ByVal dwData As Long) As Boolean
    Public Declare Function GetMonitorInfo Lib "user32.dll" Alias "GetMonitorInfoA" (ByVal hMonitor As Long, ByRef lpmi As MONITORINFOEX) As Boolean
    
    Public Const CCHDEVICENAME = 32
    Public Const MONITORINFOF_PRIMARY = &H1
    
    Public Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
    
    Public Type MONITORINFOEX
        cbSize As Long
        rcMonitor As RECT
        rcWork As RECT
        dwFlags As Long
        szDevice As String * CCHDEVICENAME
    End Type
    
    Dim MonitorId() As String
    
    Public Sub Test()
    Dim i As Integer
        Debug.Print "Number of monitors in this system : " & GetMonitorId
        Debug.Print
        For i = 1 To UBound(MonitorId)
            PrintMonitorInfo (MonitorId(i))
        Next i
    End Sub
    
    Public Function GetMonitorId()
        ReDim MonitorId(0)
        ' Of course dual screen systems are not available on all Win versions.
        If FunctionExist("user32.dll", "EnumDisplayMonitors") = True Then
            If EnumDisplayMonitors(&H0, ByVal &H0, AddressOf MonitorEnumProc, &H0) = False Then
                Failed "EnumDisplayMonitors"
            End If
        End If
        GetMonitorId = UBound(MonitorId)
    End Function
    
    
    Private Sub PrintMonitorInfo(ForMonitorID As String)
    Dim MONITORINFOEX As MONITORINFOEX
        MONITORINFOEX.cbSize = Len(MONITORINFOEX)
        If GetMonitorInfo(CLng(ForMonitorID), MONITORINFOEX) = False Then Failed "GetMonitorInfo"
        With MONITORINFOEX
            Debug.Print "Monitor info for device number : " & ForMonitorID
            Debug.Print "---------------------------------------------------"
            Debug.Print "Device Name : " & .szDevice
            If .dwFlags And MONITORINFOF_PRIMARY Then Debug.Print "Primary Display = True" Else Debug.Print "Primary Display = False"
            With .rcMonitor
                Debug.Print "Monitor Left : " & .Left
                Debug.Print "Monitor Top : " & .Top
                Debug.Print "Monitor Right : " & .Right
                Debug.Print "Monitor Bottom : " & .Bottom
            End With
            With .rcWork
                Debug.Print "Work area Left : " & .Left
                Debug.Print "Work area Top : " & .Top
                Debug.Print "Work area Right : " & .Right
                Debug.Print "Work area Bottom : " & .Bottom
            End With
        End With
        Debug.Print
        Debug.Print
    End Sub
    
    
    Public Function FunctionExist(ByVal strModule As String, ByVal strFunction As String) As Boolean
    Dim hHandle As Long
        hHandle = GetModuleHandle(strModule)
        If hHandle = &H0 Then
            Failed "GetModuleHandle"
            hHandle = LoadLibraryEx(strModule, &H0, &H0): If hHandle = &H0 Then Failed "LoadLibrary"
            If GetProcAddress(hHandle, strFunction) = &H0 Then
                Failed "GetProcAddress"
            Else
                FunctionExist = True
            End If
            If FreeLibrary(hHandle) = False Then Failed "FreeLibrary"
        Else
            If GetProcAddress(hHandle, strFunction) = &H0 Then
                Failed "GetProcAddress"
            Else
                FunctionExist = True
            End If
        End If
    End Function
    
    
    Public Sub Failed(ByVal strFunction As String)
        If errMsg = True Then
            If Err.LastDllError = 0 Then
                MessageBoxEx &H0, strFunction & Chr$(13) & Chr$(10) & Chr$(13) & Chr$(10) & "Failed", "Error", MB_OK Or MB_ICONWARNING Or MB_SETFOREGROUND, 0
            Else
                Errors Err.LastDllError, strFunction
            End If
        End If
    End Sub
    
    
    Public Function MonitorEnumProc(ByVal hMonitor As Long, ByVal hdcMonitor As Long, ByRef lprcMonitor As RECT, ByVal dwData As Long) As Boolean
    Dim ub As Integer
        ub = 0
        On Error Resume Next
        ub = UBound(MonitorId)
        On Error GoTo 0
        ReDim Preserve MonitorId(ub + 1)
        MonitorId(UBound(MonitorId)) = CStr(hMonitor)
        MonitorEnumProc = 1
    End Function
    

    And compare the results with the current SlideShowWindows(1) results.

    0 讨论(0)
  • 2020-12-21 17:23

    Try this:

    With SlideShowWindows(1)
    Debug.Print .Height
    Debug.Print .Width
    End With
    

    That'll give you results in points. There are 72 points to the inch, so:

    ResultInPixels = (ResultInPoints * WindowsDPI) / 72

    Typically WindowsDPI is 96 but you can't rely on that. API calls to GetSystemMetrics will give you the current value.

    0 讨论(0)
提交回复
热议问题