Изменение размера windows без полей в нижнем правом углу
Я бы хотел, чтобы пользователь изменил размер windows без полей в нижнем правом углу, как я могу resize windows автозаполнения элемента управления combobox.
Я не могу найти свойства для настройки формы таким образом.
Может быть, кто-то может помочь мне в этой проблеме.
- Получить значение для элемента списка по индексу
- Как отключить вкладку внутри TabControl?
- Как улучшить производительность графики DataGridView?
- Объединить ячейки в datagridview
- Загрузка изображения из относительного пути в Windows Forms
Изображение можно найти здесь:
- Сложный пользовательский интерфейс внутри ListBoxItem
- Каков правильный способ избавиться от новой формы без немедленного закрытия?
- Перенос слов для ярлыка в Windows Forms
- Структурирование проектов и зависимостей приложений больших winforms в C #
- Безопасно ли просто устанавливать CheckForIllegalCrossThreadCalls на false, чтобы избежать ошибок сквозной streamовой передачи во время отладки?
- Какая радио кнопка в группе проверена?
- DateTimePicker: выберите дату и время
- Лучшая практика сохранения настроек приложения в приложении Windows Forms
Правильный способ достичь этого – добавить обработчик proc сообщения (например, переопределив Form.WndProc
) в вашу форму и обработать сообщение WM_NCHITTEST
. (Вы можете найти определение C # этого сообщения на PInvoke.net ). В частности, когда вы получаете сообщение, подсчитайте, соответствует ли критерий хита для точки в регионе, который вы назначили для изменения размера, и если это так, верните HTBOTTOMRIGHT. По умолчанию окно proc сделает все остальное для вас, так как предполагается, что пользователь нажал на правый нижний угол границы windows, даже если в вашем окне нет границы.
Этот aproach требует небольшого количества бит Win32 interop, но он изменит размер вашего изображения точно так же, как и любое другое изменение размера windows.
Простым способом было бы сделать так, как сказал @benPearce, и поместите панель в угол и отрегулируйте размер формы с помощью Width / Height. Он будет работать, но изменение размера не будет плавным, особенно в Vista и Win7 Basic, где полное перерисовывание отключено при стандартном перемещении и изменении размера, а будет пытаться перерисовать на каждом шаге.
Обновление . В обоих подходах вам также придется выяснить, как рисовать захват. Например, вы можете поместить bitmap стандартного захвата. Хотя, учитывая, что ваша форма не имеет названия и границы, поэтому вы не обязательно зацикливаетесь на стандартных визуальных видах Windows, вы можете выбрать что-то более злобное.
Обновление 2 : Если у вас есть элемент управления, который охватывает все окно, он будет использовать форму сообщения мыши. Вы должны каким-то образом закрепить место, которое хотите использовать для изменения размера этого элемента управления. У вас есть несколько вариантов решения этой проблемы:
- Измените размер элемента управления, чтобы создать пространство для изменения размера.
- Измените область управления (отключите свойство Region), чтобы исключить изменение размера.
- Закройте панель изменения размера панели, выслушайте ее сообщение 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()
.
Большое спасибо за публикацию этого замечательного примера и объяснения. Я добавил некоторые дополнения ниже, которые могут быть интересны другим. Некоторые из этих кодов пришли из других сообщений 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; } } //***********************************************************
Поместите панель или какой-либо другой элемент управления в угол, используя события MouseDown и MouseMove на панели, соответствующим образом отрегулируйте размер форм.
В MouseDown я записывал координаты, затем в MouseMove вы можете рассчитать разницу с исходной позицией, чтобы настроить размер форм.