Клонирование формы на расширенном рабочем столе - PullRequest
6 голосов
/ 07 сентября 2011

Вот моя ситуация (извините за многословность, но мне сложно описать это кратко):

У нас есть приложение на C # (которое мы разрабатываем), которое работает в системе сдва монитора.Тем не менее, каждый монитор сталкивается с другим пользователем.То есть пользователь 1, который имеет контроль, видит только монитор A, а пользователь 2, который имеет положение «только для чтения», видит только монитор B. До сих пор мы использовали клонированный дисплей, такой, что A и B отображаютта же информация.Тем не менее, желательно иметь возможность отображать разные вещи для пользователей 1 и 2 в определенных случаях в рабочем процессе.

Это требует ситуации, когда рабочий стол иногда клонируется, а другое время расширяется.К сожалению, это решение кажется мне нежелательным из-за того, что происходит визуально, когда вы переключаетесь между режимами рабочего стола (экран становится черным, временное изменение положения окон) - это в основном не чистый переход.Вот почему я изучаю альтернативы.

Очевидно, что решение только для клонирования не будет работать, поэтому он выходит из расширенного режима.

Расширенный режим позволяет легко отображать две разные формы наМониторы A и B, но что я могу сделать, если оба монитора показывают одно и то же?Есть ли способ показать мне «копию» или «клон» C # System.Windows.Forms.Form при открытом оригинале, который отражает ту же информацию?

Есть ли другое решение этой проблемы, которое я пропускаю?Или подход «переключаться между режимами отображения с использованием DisplaySwitch.exe» настолько хорош, насколько он есть?

(предположим, мы полностью контролируем платформу - аппаратное и программное обеспечение)

Ответы [ 3 ]

2 голосов
/ 07 сентября 2011

Рассмотрите возможность использования программы удаленного доступа, такой как TightVNC . Может работать в режиме loopback, отображая изображение основного монитора в клиентской программе. Который вы затем должны перейти на второй монитор, чтобы получить клон. Вместе с пользовательской формой, которую вы сверните и восстановите.

2 голосов
/ 07 сентября 2011

Чтобы уточнить мой комментарий сейчас, когда у меня больше времени.

Вместо того, чтобы пытаться клонировать Форму А в Форму B, установите некоторый уровень связи между ними, так, чтобы Форме A было все равно, с чем она общается, или отображаемые данные одинаковы или полностью различны.

Самый простой способ сделать это - подключить посредник к событиям в форме A и, когда эти события инициируются, отправить необходимые данные в форму B для их отображения.

В случае, когда данные совпадают, это может быть так же просто, как делать моментальный снимок каждый раз, когда форма А обновляет и отображать его в форме В (очень похоже на ответ harvardflu, но помещая эту логику в посредник), или это может занять процесс запуска приложения в другом потоке и одновременное обновление формы A и формы B с помощью различных посредников (хотя, как вы предполагаете, это, вероятно, будет основным реинжинирингом).

Вероятно, оптимальное решение находится где-то посередине.

0 голосов
/ 07 сентября 2011

В зависимости от ваших потребностей, т. Е. Как часто оно должно обновляться и т. Д., Всегда есть возможность создать растровое изображение вашей формы и отобразить это растровое изображение во 2-й форме.

Лично я бы посчитал это чем-то вроде взлома, и использование шаблона-посредника, как предлагает @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;
    }
}
...