在双显示器系统中,找出在哪个显示器上显示 PowerPoint 幻灯片

Posted

技术标签:

【中文标题】在双显示器系统中,找出在哪个显示器上显示 PowerPoint 幻灯片【英文标题】:In a dual-monitor system, finding out on which monitor a PowerPoint slideshow is displayed 【发布时间】:2011-11-06 04:24:48 【问题描述】:

在多显示器系统上运行的 Powerpoint 2007/2010 中,我们可以通过转到“幻灯片”->“设置幻灯片”->“显示幻灯片”并选择所需的监视器。

是否可以通过编程方式确定这些设置(例如使用 VBA)?

我真正需要的是显示幻灯片的显示器的像素分辨率。 我该怎么做?

【问题讨论】:

您是否尝试过录制宏并查看生成的代码? PPT 2007/2010 中不再有宏记录器。 【参考方案1】:

来自 Edwin Vermeer 的代码 @JMax 非常棒。我敢肯定我会为此被模组搞砸,但我制作了下图以准确显示代码中的Sub test() 返回的内容。希望这能再节省一两个小时的时间。

提示:用 MsgBox 查找-替换 Dubug.Print 并使用不同的监视器安排运行代码几次,以确保您了解返回。

以下是一个奇怪的监视器安排,它很好地展示了您将获得的不同回报:

...好吧,在我获得 10 个声望之前它不会让我发布照片,图表在这里:

"Monitor" returns for Primary monitor

"Work area" returns for Primary monitor

辅助监视器的“监视器/工作区”返回

(与其他 2 个在同一个相册中,需要 10 个声望才能发布 >2 个链接...)

【讨论】:

【参考方案2】:

即使你已经接受了史蒂夫的回答。这里有一些有用的sn-ps代码。

您可以使用这种代码(找到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

并将结果与​​当前的SlideShowWindows(1) 结果进行比较。

【讨论】:

空白 -- 填得很好。谢谢!【参考方案3】:

试试这个:

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

这会给你分数。 一英寸有 72 个点,所以:

ResultInPixels = (ResultInPoints * WindowsDPI) / 72

通常 WindowsDPI 为 96,但您不能依赖它。 对 GetSystemMetrics 的 API 调用将为您提供当前值。

【讨论】:

如何以编程方式选择在显示器上显示我想要的幻灯片

以上是关于在双显示器系统中,找出在哪个显示器上显示 PowerPoint 幻灯片的主要内容,如果未能解决你的问题,请参考以下文章

找出用户在iOS显示的UIAlertView上选择了哪个按钮的方法,请求允许应用程序接收推送通知

试图找出页面上使用了哪个Web部件

如何在双硬盘下同时安装windows和linux

如何使用 Resharper 准确找出哪个规则将语法突出显示应用于 VS2022 中的特定代码元素?

在双显示器方案中将自动关闭消息框置于应用程序窗口的中心

C#找出控件是不是显示在屏幕上[重复]