C# 在扩展桌面上克隆窗体

C# 在扩展桌面上克隆窗体,c#,multiple-monitors,C#,Multiple Monitors,以下是我的情况(很抱歉说得太多,但我发现很难简明扼要地描述这一点): 我们有一个C#应用程序(我们开发的),它运行在一个有两个监视器的系统上。但是,每个监视器面对不同的用户。也就是说,拥有控制权的用户1只看到监视器A,而处于“只读”位置的用户2只看到监视器B。到目前为止,我们一直在使用克隆显示,这样A和B显示相同的信息。但是,希望能够在工作流中的特定实例向用户1和2显示不同的内容 这就需要出现这样一种情况:桌面有时被克隆,有时被扩展。不幸的是,这个解决方案对我来说似乎是不可取的,因为当你在桌面模

以下是我的情况(很抱歉说得太多,但我发现很难简明扼要地描述这一点):

我们有一个C#应用程序(我们开发的),它运行在一个有两个监视器的系统上。但是,每个监视器面对不同的用户。也就是说,拥有控制权的用户1只看到监视器A,而处于“只读”位置的用户2只看到监视器B。到目前为止,我们一直在使用克隆显示,这样A和B显示相同的信息。但是,希望能够在工作流中的特定实例向用户1和2显示不同的内容

这就需要出现这样一种情况:桌面有时被克隆,有时被扩展。不幸的是,这个解决方案对我来说似乎是不可取的,因为当你在桌面模式之间切换(屏幕变黑,窗口临时重新定位)时,视觉上会发生什么——它基本上不是一个干净的过渡。这就是为什么我在探索其他选择

显然,仅克隆的解决方案将不起作用,因此将离开扩展模式

扩展模式很容易让我在监视器A和B上显示两种不同的形式,但是当我希望两个监视器都显示相同的内容时,我能做些什么呢?有没有一种方法可以让我在原稿打开时显示C#System.Windows.Forms.Form的“副本”或“克隆”以反映相同的信息

这个问题有没有我忽略的另一个解决方案?或者“使用DisplaySwitch.exe在显示模式之间切换”的方法是否尽可能好


(假设我们完全控制平台-硬件和软件)

根据您的需要,即必须刷新的频率等,始终可以选择创建表单的位图,并在第二个表单中显示该位图

我个人认为这有点像黑客,使用@pdr建议的中介模式肯定是一种更干净的方法。但是如果你需要一个快速的(肮脏的)解决方案,这可能会完成工作

张贴的代码具有原型质量,应进行相应处理

public partial class MainForm : Form
{
    private bool m_Running;

    public MainForm()
    {
        InitializeComponent();

        DuplicateForm f2 = new DuplicateForm(this.Text);
        f2.Show();

        m_Running = true;
        Thread t = new Thread(new ThreadStart(() =>
            {
                while (m_Running)
                {
                    this.Invoke(new MethodInvoker(() =>
                    {
                      Bitmap bm = new Bitmap(Width, Height);
                      // pnl is a Panel with Dock=Fill
                      pnl.DrawToBitmap(bm, new Rectangle(0, 0, Width, Height));
                      f2.SetImage(this, bm);
                     }));

                    Thread.Sleep(500); // or use a timer
                }
            }));

        t.Start();
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        m_Running = false;
    }
}

public partial class DuplicateForm : Form
{
    public DuplicateForm(string title)
    {
        InitializeComponent();
        Text = title + " [copy]";
    }

    public void SetImage(Form source, Image img)
    {
        this.Size = source.Size;
        // Picturebox is a PictureBox control with Dock=Fill
        pictureBox1.Image = img;
    }
}

考虑使用远程访问程序,如。它可以在环回模式下运行,在客户端程序中显示主监视器图像。然后必须移动到第二个监视器才能获得克隆。以及您最小化和恢复的自定义表单

现在我有更多的时间来详细说明我的评论

与其尝试将表单A克隆到表单B中,不如在两者之间建立某种通信层,这样表单A就不关心它与什么通信,也不关心显示的数据是相同的还是完全不同的

最简单的方法是将中介挂接到表单a上的事件中,当这些事件被触发时,将必要的数据发送到表单B以呈现它

在数据相同的情况下,这可能很简单,只要在每次表单a更新时拍摄快照并将其呈现在表单B上(很像harvardflu的回答,但将该逻辑放在中介中),或者,您可以在另一个线程中运行应用程序流程,并通过不同的中介同时更新表单A和表单B(不过,正如您所建议的,这可能是一次重大的重新设计)


最佳解决方案可能介于两者之间。

使用显示不同信息但显示相同信息的完全相同的系统有什么问题?(可能很好地使用了中介模式)@pdr我不确定,但我认为您建议的方法是,对于需要在A和B上显示相同信息的情况,我创建两个表单X实例,并在每个监视器上显示一个?然后,调解人将促进两个实例(比如X1和X2)的形式保持最新,我想。我想我试图避免这种方法的主要原因是它意味着一个相当重要的重新分解,但这可能是唯一的选择。该应用程序包括实时视频,所以我虽然很欣赏快速破解的建议(在某种程度上,我要求一个),但这可能对我不起作用。这是一个有趣的选择。我必须调查TightVNC在扩展桌面上的外观(我需要它是无缝的,例如没有边框,这样我就可以在辅助监视器上“全屏”显示),以及我是否可以在不违反GPL的情况下使用它。感谢您的详细说明。我确实觉得“最佳”解决方案就在这个空间的某个地方。我需要更仔细地看一看这需要多少重新分解。我想是时候做个原型了:)