WPF:多显示器编程

2024-04-21

我在用着WPF in C#

我想从多显示器编程开始,这意味着该应用程序将在许多具有不同视图的显示器上显示。

我在网上搜索过,我得到了使用的方法Screen.AllScreens[],但是我有以下问题

有多种方法可以将多台显示器连接到 PC

情况 1:在笔记本电脑中:1 个笔记本电脑的屏幕,1 个屏幕连接到 VGA 端口,1 个屏幕连接到 HDMI 端口...

情况 2:在台式机中:许多屏幕连接到支持多输出的 VGA 卡

情况3:多个屏幕连接到Hub HDMI或Hub VGA,并且Hub连接到PC

我的问题是,Screen.AllScreens[]支持哪种情况?

还有其他方法可以支持所有情况吗?

非常感谢!


Screens.AllScreens[]是一种 WinForms 方法,如果我没有记错的话,但是是的,这支持您的所有情况(据我所知)。如果我没记错的话,WinForms 方法会在应用程序启动时初始化静态属性,并且如果在运行时屏幕发生更改,它不会更新。

当您处理 WPF 时,我会完全避免使用 WinForms。而是写你自己的Screensp/调用 Win32 API 的包装器。另外,连接一个事件处理程序以在显示设置更改时通知您,例如:

Microsoft.Win32.SystemEvents.DisplaySettingsChanged += new EventHandler(this.SystemEvents_DisplaySettingsChanged);

这是我使用的包装器:

/// <summary>
/// This class deals with monitors.
/// </summary>
internal static class Monitors
{
    private static List<Monitors.Screen> Screens = null;

    internal static List<Monitors.Screen> GetScreens()
    {
        Monitors.Screens = new List<Monitors.Screen>();

        var handler = new NativeMethods.DisplayDevicesMethods.EnumMonitorsDelegate(Monitors.MonitorEnumProc);
        NativeMethods.DisplayDevicesMethods.EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, handler, IntPtr.Zero); // should be sequential

        return Monitors.Screens;
    }

    private static bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, NativeMethods.DisplayDevicesMethods.RECT rect, IntPtr dwData)
    {
        NativeMethods.DisplayDevicesMethods.MONITORINFO mi = new NativeMethods.DisplayDevicesMethods.MONITORINFO();

        if (NativeMethods.DisplayDevicesMethods.GetMonitorInfo(hMonitor, mi))
        {
            Monitors.Screens.Add(new Monitors.Screen(
                (mi.dwFlags & 1) == 1, // 1 = primary monitor
                mi.rcMonitor.Left, 
                mi.rcMonitor.Top, 
                Math.Abs(mi.rcMonitor.Right - mi.rcMonitor.Left), 
                Math.Abs(mi.rcMonitor.Bottom - mi.rcMonitor.Top)));
        }

        return true;
    }

    /// <summary>
    /// Represents a display device on a single system.
    /// </summary>
    internal sealed class Screen
    {
        /// <summary>
        /// Initializes a new instance of the Screen class.
        /// </summary>
        /// <param name="primary">A value indicating whether the display is the primary screen.</param>
        /// <param name="x">The display's top corner X value.</param>
        /// <param name="y">The display's top corner Y value.</param>
        /// <param name="w">The width of the display.</param>
        /// <param name="h">The height of the display.</param>
        internal Screen(bool primary, int x, int y, int w, int h)
        {
            this.IsPrimary = primary;
            this.TopX = x;
            this.TopY = y;
            this.Width = w;
            this.Height = h;
        }

        /// <summary>
        /// Gets a value indicating whether the display device is the primary monitor.
        /// </summary>
        internal bool IsPrimary { get; private set; }

        /// <summary>
        /// Gets the display's top corner X value.
        /// </summary>
        internal int TopX { get; private set; }

        /// <summary>
        /// Gets the display's top corner Y value.
        /// </summary>
        internal int TopY { get; private set; }

        /// <summary>
        /// Gets the width of the display.
        /// </summary>
        internal int Width { get; private set; }

        /// <summary>
        /// Gets the height of the display.
        /// </summary>
        internal int Height { get; private set; }
    }
}

internal static class NativeMethods
{
    /// <summary>
    /// Methods for retrieving display devices.
    /// </summary>
    internal static class DisplayDevicesMethods
    {
        internal delegate bool EnumMonitorsDelegate(IntPtr hMonitor, IntPtr hdcMonitor, NativeMethods.DisplayDevicesMethods.RECT rect, IntPtr dwData);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, EnumMonitorsDelegate lpfnEnum, IntPtr dwData);

        /// <summary>
        /// Retrieves information about a display monitor.
        /// </summary>
        /// <param name="hmonitor">A handle to the display monitor of interest.</param>
        /// <param name="info">A pointer to a MONITORINFO or MONITORINFOEX structure that receives information about the specified display monitor.</param>
        /// <returns>If the function succeeds, the return value is nonzero.</returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool GetMonitorInfo(IntPtr hmonitor, [In, Out] NativeMethods.DisplayDevicesMethods.MONITORINFO info);

        /// <summary>
        /// The RECT structure defines the coordinates of the upper-left and lower-right corners of a rectangle.
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        internal struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        /// <summary>
        /// The MONITORINFO structure contains information about a display monitor.
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
        internal class MONITORINFO
        {
            internal int cbSize = Marshal.SizeOf(typeof(NativeMethods.DisplayDevicesMethods.MONITORINFO));
            internal NativeMethods.DisplayDevicesMethods.RECT rcMonitor = new NativeMethods.DisplayDevicesMethods.RECT();
            internal NativeMethods.DisplayDevicesMethods.RECT rcWork = new NativeMethods.DisplayDevicesMethods.RECT();
            internal int dwFlags;
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WPF:多显示器编程 的相关文章

  • QCombobox 向下箭头图像

    如何更改Qcombobox向下箭头图像 现在我正在使用这个 QSS 代码 但这不起作用 我无法删除向下箭头边框 QComboBox border 0px QComboBox down arrow border 0px background
  • 如何保证对象只有一个线程

    我有以下代码 class Service public void start creates thread which creates window and goes to message loop void stop sends WM C
  • 何时使用 =default 使析构函数默认?

    尽管对构造函数使用 default 对我来说很清楚 即强制编译器在其他构造函数存在时创建默认构造函数 但我仍然无法理解这两种类型的析构函数之间的区别 那些使用 default 的 那些没有显式定义并由编译器自动生成的 我唯一想到的是 gro
  • 更改 Qt OpenGL 窗口示例以使用 OpenGL 3.3

    我正在尝试更改 Qt OpenGL 示例以使用更现代的 opengl 版本 330 似乎合适 所以我做了 在 main cpp 上设置版本和配置文件 设置着色器版本 更改着色器以使用统一 它现在构建没有任何错误 但我只看到一个空白窗口 我错
  • 在 Xamarin 中隐藏软键盘

    如何隐藏软键盘以便在聚焦时显示Entry在 Xamarin forms 便携式表单项目中 我假设我们必须为此编写特定于平台的渲染器 但以下内容不起作用 我创建自己的条目子类 public class MyExtendedEntry Entr
  • VS 程序在调试模式下崩溃,但在发布模式下不崩溃?

    我正在 VS 2012 中运行以下程序来尝试 Thrust 函数查找 include cuda runtime h include device launch parameters h include
  • ASP.NET Web API 客户端 ProgressMessageHandler Post 任务卡在 WinForm 应用程序中

    我在用着HttpClient and ProgressMessageHandler来自MS ASP NET Web API 客户端库 http nuget org packages Microsoft AspNet WebApi Clien
  • 防止 boost::asio::io_context 在空轮询调用时停止

    此代码调用发布的句柄 boost asio io context ioc boost asio post ioc std cout lt lt lol lt lt std endl ioc poll 而这并没有 boost asio io
  • 根据 N 个值中最小的一个返回不同的结果

    不确定如何使标题更具描述性 所以我只是从一个例子开始 我使用下面的代码位 它从枚举中选择一个方向 具体取决于四个轴中哪一个与给定方向相比形成最小角度 static Direction VectorToDirection Vector2 di
  • 找不到 assimp-vc140-mt.dll ASSIMP

    我已经从以下位置下载了 Assimp 项目http assimp sourceforge net main downloads html http assimp sourceforge net main downloads html Ass
  • 动态生成的控件 ID 返回为 NULL

    我可以在 Page PreInit 函数中创建动态控件 如何检索控件及其 ID 我的 C 代码用于创建动态控件之一 var btn new WebForms Button btn Text btn ID Addmore btn Click
  • std::forward_as_tuple 将参数传递给 2 个构造函数

    我想传递多个参数以便在函数内构造两个对象 以同样的方式std pair
  • 如何从文本文件读取整数到数组

    这就是我想做的 我对此有些不满 但我希望你能容忍我 这对我来说是一个非常新的概念 1 在我的程序中 我希望创建一个包含 50 个整数的数组来保存来自文件的数据 我的程序必须获取用户的文档文件夹的路径 2 文件的名称为 grades txt
  • 将二进制数据从 C# 上传到 PHP

    我想将文件从 Windows C 应用程序上传到运行 PHP 的 Web 服务器 我知道 WebClient UploadFile 方法 但我希望能够分块上传文件 以便我可以监控进度并能够暂停 恢复 因此 我正在读取文件的一部分并使用 We
  • 给出 5 个参数,但在终端中只得到 3 个参数

    我想将一个文件传递给一个c 程序 如果我在 IDE 中执行此操作 test string string lt test txt return argc 5 但在终端上我刚刚得到argc 3 看来 这是因为 什么是 lt 意思是 我正在使用
  • 每个租户的唯一用户名和电子邮件

    我正在使用以下代码编写多租户应用程序ASP NET Core 2 1 我想覆盖默认的与用户创建相关的验证机制 目前我无法创建多个具有相同的用户UserName My ApplicationUser模型有一个名为TenantID 我想要实现的
  • 新任务中使用的依赖注入服务

    我在需要时使用依赖项注入来访问我的服务 但我现在想要创建一个并发任务 但这会由于依赖项注入对象及其生命周期而导致问题 我读过这篇文章 标题 防止多线程 Link http mehdi me ambient dbcontext in ef6
  • 使用taskkill停止Windows服务

    我需要帮助来使用 C 终止 Windows 服务 现在要终止该服务 请使用以下选项 从命令 sc queryex ServiceName 发现后PID服务的 taskkill pid 1234 exemple f 为了便于阅读 但如果您明白
  • 带有命令绑定的 KeyBinding 不适用于 TextBox UpdateSourceTrigger LostFocus

    我正在使用 MVVM 并遇到以下问题 我的 TextBox Text 与 UpdateSourceTrigger LostFocus 绑定 这就是用户想要的 我有一个带有 SaveCommand CommandBinding 的按钮 这有效
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐

  • 理解 scala 中参与者的线程性

    有人告诉我 Scala Actors 实际上从来不会同时执行两个操作 这表明 act 或 React 或 receive 方法本质上是同步的 我知道 act 方法中的长操作可能会导致阻塞问题 并且我假设对消息队列的访问必须以某种方式同步 但
  • Rails 路由中的“mount”指令是什么意思?

    我找不到关键字 mount 的含义轨道布线系统 http api rubyonrails org classes ActionDispatch Routing html 我已经设置了Mercury http jejacks0n github
  • 如何使用multiple属性在Android上上传多个文件?

    I got a
  • 在 python 上使用 TensorRT .engine 文件进行推理

    我使用 Nvidia 的迁移学习工具包 TLT 进行训练 然后使用 tlt converter 将 etlt 模型转换为 engine 文件 我想使用这个 engine 文件在 python 中进行推理 但由于我使用 TLT 进行训练 因此
  • 合并冲突后暂存区中有哪些文件?

    我运行时与 file1 txt 发生冲突git merge b2当前分支是master ls files somcdt file1 txt然后显示 M 100644 4111d50ada6cc03ec6079f226c23efa3142c9
  • 是否可以在 LLVM IR 代码中指定十六进制数?

    例如 error floating point constant invalid for type 3 and i8 0x80 2 从扫描的红外参考手册 http llvm org docs LangRef html simple cons
  • 从 Java 方法返回多个值:为什么没有 n 元组对象?

    为什么没有一个 标准的 Java 认证的 解决方案作为 Java 语言本身的一部分 从 Java 方法返回多个值 而不是开发人员必须使用自己的方法 例如映射 列表 对等 为什么Java不支持n元组对象 特别是考虑可能一起 串联 修改两个对象
  • 防止PHP脚本被淹没

    我想防止我的脚本被淹没 如果用户按 F5 它每次都会执行脚本 我想防止这种情况并允许每 2 秒执行一个脚本 有什么解决方案吗 您可以使用内存缓存来执行此操作 简单的演示脚本 memcache new Memcache memcache gt
  • Typescript 中的 new() 是什么?

    我遇到了new 在官方文件中here https www typescriptlang org docs handbook generics html关于泛型 这是代码上下文 function create
  • javascript - 从输入类型=文件获取文件名和扩展名

    我有一个文件上传输入 当我单击浏览按钮并选择文件时 我希望文件名和扩展名显示在两个输入文本框中 请参阅代码示例 它与扩展名一起正常工作 但文件名还显示了给我 fakepath 警告的路径 我明白为什么 但是有什么好方法可以做到这一点并将文件
  • 在 thymeleaf spring boot 中,动态轮播滑块不起作用

    In my spring boot thymeleaf this following code is slider does not work well Show the result in image What wrong with in
  • 您应该如何诊断错误 SEHException - 外部组件抛出异常

    每当用户报告错误时 例如 System Runtime InteropServices SEHException 外部组件引发的异常 作为一名程序员 我可以做些什么来确定原因吗 场景 一名用户 使用我公司编写的程序 报告了此错误 这可能是也
  • 从另一个页面访问时引导滚动间谍

    我试图链接到主页的特定部分 同时保持滚动间谍功能 有了这个代码 li a href sec1 About a li 滚动间谍正在运行 但如果我尝试从主页以外的页面访问它 它只会添加 sec1 到当前页面的 url 没有效果 如果我把它改成
  • 关于在单列中查找重复项的宏的建议

    发现了很多涉及在两列中查找重复项的问题 i e MS Excel 如何创建宏来查找重复项并突出显示它们 https stackoverflow com questions 2162684 ms excel how to create a m
  • 为什么numba cuda调用几次后运行速度变慢?

    我正在尝试如何在 numba 中使用 cuda 然而我却遇到了与我预想不同的事情 这是我的代码 from numba import cuda cuda jit def matmul A B C Perform square matrix m
  • ggpairs 中的数字四舍五入

    是否可以将 ggpairs 中的相关数字舍入为例如 2 位数字 library GGally ggpairs iris columns 1 4 mapping ggplot2 aes col Species 这是一个修改版本ggally c
  • 用于累积逗号分隔字符串的 C++ 预处理器宏

    我需要执行以下操作 const char my var Something REGISTER my var const char my var2 Selse REGISTER my var2 concst char all OUTPUT R
  • SSIS 错误 - 包中的版本号无效

    失败作业对应的日志如下 2014 年 4 月 11 日 06 40 00 LPR New 错误 0 USPHND0088 LPR New 作业 结果 作业失败 该作业由 Schedule 14 调用 LPR New Job 最后运行的一步是
  • 如何检测远程机器的操作系统

    从基于 net 的应用程序中 确定远程计算机上运行的操作系统是 Windows 还是 Linux 的最快方法是什么 只需 ping 一下即可 如果 TTL 生存时间 为 254 或更小 则它是基于 UNIX 的 如果 TTL 为 128 或
  • WPF:多显示器编程

    我在用着WPF in C 我想从多显示器编程开始 这意味着该应用程序将在许多具有不同视图的显示器上显示 我在网上搜索过 我得到了使用的方法Screen AllScreens 但是我有以下问题 有多种方法可以将多台显示器连接到 PC 情况 1