Создание непрямоугольных форм, которые можно перемещать, перетаскивая в любом месте фоновой области - PullRequest
4 голосов
/ 17 февраля 2012

Я хочу переместить окно формы, щелкнув левой кнопкой мыши и удерживая фоновую область, как мы обычно делаем, используя строку заголовка.

И затем я также хочу изменить окно формы моего приложения(то есть прямоугольное окно) в мое собственное графическое окно.Я видел этот тип окна во многих других приложениях, поэтому я считаю, что это возможно.

Ответы [ 2 ]

5 голосов
/ 17 февраля 2012

Вопрос 1:

Чтобы разрешить перемещение формы при перетаскивании ее клиентской области, необходимо указать диспетчеру окон обрабатывать клиентскую область, как если бы она была строкой заголовка.(область подписи).Вы предлагаете нечто подобное в своем вопросе.

Это можно сделать в .NET, переопределив WndProc метод вашей формы, ответив на сообщение WM_NCHITTEST и вернув HTCAPTION, чтобы указать, что все должно быть обработанокак часть строки заголовка (заголовка) вместо значения по умолчанию HTCLIENT, которое указывает, что оно должно рассматриваться как клиентская область формы.Добавьте следующий код в класс формы:

private const int WM_NCHITTEST = 0x84;
private const int HTCLIENT = 0x1;
private const int HTCAPTION = 0x2;

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);

    if (m.Msg == WM_NCHITTEST)
    {
        // Convert HTCLIENT to HTCAPTION
        if (m.Result.ToInt32() == HTCLIENT)
        {
            m.Result = (IntPtr)HTCAPTION;
        }
    }
}

Вопрос 2:

Вы можете создать форму произвольной непрямоугольной формы, установив Region свойство вашей формы на заказ Region на ваш выбор.Если у вас есть опыт работы с графическими программами, такими как Photoshop, вы можете думать об этом как об установке «области отсечения» для вашей формы: оконный менеджер не будет рисовать ничего, кроме указанных вами границ.Пиксели в форме, описанной этой Region, могут даже не быть смежными.

Самый простой способ создать область - это, вероятно, использовать GraphicsPath класс , а затем использовать конструктор для Region класса , который принимает один объект GraphicsPath в качестве параметра.

И, как я полагаю, вы уже знаете, учитывая первый вопрос, вам придется задатьсвойство FormBorderStyle до None, чтобы гарантировать, что границы по умолчанию, нарисованные оконным менеджером, исчезают.

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

Наконец, стоит отметить, что этот последний подход к созданию непрямоугольных форм может привести к появлению совершенно уродливых пользовательских интерфейсов, которые неЭто ни в коем случае не повышает удобство использования вашего продукта, например:

Windows Media Player

Пожалуйста, используйте эту технику с осторожностью и придерживайтесь здравого смысла.Если вы сомневаетесь, прямоугольники - действительно хорошая форма для окон.

1 голос
/ 17 февраля 2012

Вот ссылка на впечатляющую статью CodeProject, которая ответит на оба ваших вопроса: Формируемая Windows-форма Alpha Channel с поддержкой дизайнера .Реализация использует комбинацию переднего и заднего окон.Он использует WS_EX_LAYERED для отображения окна, основанного на растровом изображении, и перехватывает события мыши в главной форме, чтобы можно было их перетаскивать.

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

В следующей статье CodeProject показан способ преодоления этой проблемы с использованием DeferWindowPos: Альфа-смешанные формы Windows .

Удачи!

...