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

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

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

Может кто-то может помочь мне в решении проблемы.

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

enter image description here

Ответ 1

Правильный способ добиться этого - добавить обработчик proc сообщения (например, переопределив Form.WndProc) в вашу форму и обработать сообщение WM_NCHITTEST. (Вы можете найти определение этого сообщения на PInvoke.net). В частности, когда вы получаете сообщение, вычислите, соответствует ли критерий попадания пункт в регионе, который вы назначили для изменения размера, и если это так, верните HTBOTTOMRIGHT. По умолчанию окно proc сделает все остальное за вас, так как предполагается, что пользователь нажал на нижний правый угол границы окна, даже если ваше окно не имеет границы.

Для этого aproach требуется бит Microsoft Win32, но он изменит размер вашего изображения так же, как и любое другое изменение размера окна.

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

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

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

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

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

Ответ 2

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

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().

Ответ 3

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

//***********************************************************
//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;
    }
}
//***********************************************************

Ответ 4

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

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