Изменить размер окна без полей в правом нижнем углу

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

Я не могу найти свойства для настройки формы таким образом.

Может быть, кто-то может помочь мне в этой проблеме.

Изображение можно найти здесь:

введите описание изображения здесь

4 ответа

Решение

Надлежащим способом для достижения этой цели было бы добавить обработчик proc сообщения (переопределяя Form.WndProc например) к вашей форме и обработать WM_NCHITTEST сообщение. (Вы можете найти определение C# этого сообщения на http://pinvoke.net/.) В частности, когда вы получаете сообщение, рассчитайте, соответствует ли тест попадания точке в области, для которой вы назначили изменение размера, и, если это так, верните HTBOTTOMRIGHT. Окно по умолчанию будет делать все остальное за вас, так как будет предполагать, что пользователь щелкнул в правом нижнем углу границы окна, даже если у вашего окна нет границы.

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

Самый простой способ - сделать так, как сказал @benPearce, поместить панель в угол и отрегулировать размер формы, используя ширину / высоту. Это будет работать, но изменение размера не будет гладким, особенно в Vista и Win7 Basic, где полная перерисовка отключена при стандартном перемещении и изменении размера, в то время как будет пытаться перерисовать на каждом шаге.

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

Обновление 2: если у вас есть элемент управления, охватывающий все окно, он будет использовать сообщения мыши в форме. Вы должны каким-то образом обрезать место, которое вы хотите использовать для изменения размера этого элемента управления. У вас есть несколько вариантов решения этой проблемы:

  1. Измените размер элемента управления, чтобы освободить место для ручки изменения размера.
  2. Настройте область управления (через свойство Region), чтобы исключить изменение размера.
  3. Закройте ручку изменения размера панели, прослушайте ее сообщение MouseEnter и установите для свойства формы Capture значение true, что приведет к тому, что все дальнейшие сообщения мыши перейдут к нему. Примечание: вам придется освободить захват, как только мышь покинет эту область после завершения изменения размера.

Я бы порекомендовал перейти на вариант 1 как самый простой. Вариант 3 является наиболее сложным и требует подробных сведений о том, как работает ввод с помощью мыши в Windows, поэтому я не рекомендовал бы его. Вариант 2 является хорошей альтернативой варианту 1, но вам нужно будет попытаться увидеть, как элемент управления ListView отреагирует на его область, подвергаемую настройке.

Вот код, соответствующий объяснениям Франци, я писал его, но он тем временем ответил, так что проголосуйте за его объяснение, и это хорошо, если этот код соответствует вашим потребностям.

protected override void WndProc(ref Message m) {
    const int wmNcHitTest = 0x84;
    const int htBottomLeft = 16;
    const int htBottomRight = 17;
    if (m.Msg == wmNcHitTest) {
        int x = (int) (m.LParam.ToInt64() & 0xFFFF);
        int y = (int) ((m.LParam.ToInt64() & 0xFFFF0000) >> 16);
        Point pt = PointToClient(new Point(x, y));
        Size clientSize = ClientSize;
        if (pt.X >= clientSize.Width - 16 && pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16) {
            m.Result = (IntPtr) (IsMirrored ? htBottomLeft : htBottomRight);
            return;
        }
    }
    base.WndProc(ref m);
}

Редактировать: чтобы написать захват, вы можете инициализировать new VisualStyleRenderer(VisualStyleElement.Status.Gripper.Normal) и использовать его PaintBackground() метод.

Большое спасибо за размещение этого замечательного образца и объяснения. Ниже я добавил некоторые дополнения, которые могут заинтересовать других. Некоторые из приведенных здесь кодов взяты из других публикаций в стеке, но возможность увидеть их в одном блоке кода может оказаться полезной для других. Я хотел иметь возможность изменять размер формы на ВСЕХ границах, а не только в правом нижнем углу. Я также хотел иметь возможность перетаскивать форму. Наконец, я хотел тень.

//***********************************************************
//This gives us the ability to resize the borderless from any borders instead of just the lower right corner
protected override void WndProc(ref Message m)
{
    const int wmNcHitTest = 0x84;
    const int htLeft = 10;
    const int htRight = 11;
    const int htTop = 12;
    const int htTopLeft = 13;
    const int htTopRight = 14;
    const int htBottom = 15;            
    const int htBottomLeft = 16;
    const int htBottomRight = 17;          

    if (m.Msg == wmNcHitTest)
    {
        int x = (int)(m.LParam.ToInt64() & 0xFFFF);
        int y = (int)((m.LParam.ToInt64() & 0xFFFF0000) >> 16);
        Point pt = PointToClient(new Point(x, y));
        Size clientSize = ClientSize;
        ///allow resize on the lower right corner
        if (pt.X >= clientSize.Width - 16 && pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16)
        {           
            m.Result = (IntPtr)(IsMirrored ? htBottomLeft : htBottomRight);
            return;
        }       
        ///allow resize on the lower left corner
        if (pt.X <= 16 && pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16)
        {
            m.Result = (IntPtr)(IsMirrored ? htBottomRight : htBottomLeft);
            return;
        }
        ///allow resize on the upper right corner
        if (pt.X <= 16 && pt.Y <= 16 && clientSize.Height >= 16)
        {
            m.Result = (IntPtr)(IsMirrored ? htTopRight : htTopLeft);
            return;
        }
        ///allow resize on the upper left corner
        if (pt.X >= clientSize.Width - 16 && pt.Y <= 16 && clientSize.Height >= 16)
        {
            m.Result = (IntPtr)(IsMirrored ? htTopLeft : htTopRight);
            return;
        }
        ///allow resize on the top border
        if (pt.Y <= 16 && clientSize.Height >= 16)
        {
            m.Result = (IntPtr)(htTop);
            return;
        }
        ///allow resize on the bottom border
        if (pt.Y >= clientSize.Height - 16 && clientSize.Height >= 16)
        {
            m.Result = (IntPtr)(htBottom);
            return;
        }
        ///allow resize on the left border
        if (pt.X <= 16 && clientSize.Height >= 16)
        {
            m.Result = (IntPtr)(htLeft);
            return;
        }
        ///allow resize on the right border
        if (pt.X >= clientSize.Width - 16 && clientSize.Height >= 16)
        {
            m.Result = (IntPtr)(htRight);
            return;
        }
    }
    base.WndProc(ref m);
}
//***********************************************************
//***********************************************************
//This gives us the ability to drag the borderless form to a new location
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;

[DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();

private void YOURCONTROL_MouseDown(object sender, MouseEventArgs e)
{
    //ctrl-leftclick anywhere on the control to drag the form to a new location 
    if (e.Button == MouseButtons.Left && Control.ModifierKeys == Keys.Control)
    {       
        ReleaseCapture();
        SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
    }  
}
//***********************************************************
//***********************************************************
//This gives us the drop shadow behind the borderless form
private const int CS_DROPSHADOW = 0x20000;
protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ClassStyle |= CS_DROPSHADOW;
        return cp;
    }
}
//***********************************************************

Поместите панель или какой-либо другой элемент управления в угол, используя события MouseDown и MouseMove панели, соответствующим образом отрегулируйте размер форм.

В MouseDown я записываю координаты, затем в MouseMove вы можете рассчитать разницу от исходного положения для настройки размера форм.

Другие вопросы по тегам