Изменить размер окна без полей в правом нижнем углу - PullRequest
14 голосов
/ 08 октября 2009

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

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

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

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

enter image description here

Ответы [ 4 ]

32 голосов
/ 08 октября 2009

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

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() метод.

19 голосов
/ 20 июня 2013

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

//***********************************************************
//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;
    }
}
//***********************************************************
13 голосов
/ 08 октября 2009

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

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

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

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

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

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

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

2 голосов
/ 08 октября 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...