Давно хотел применять в своих приложениях что-то подобное, но вот win32 как-то все не удается освоить...
И вот думаю: "Надо же когда-то начинать..." Пошел в
Build desktop Windows apps using the Win32 API, потом в
WM_NCHITTEST message... но это же бездна! И чтобы успокоиться, хоть какой-то прок поиметь и не забыть через месяц, взял за основу пример ответа, налепил на него то, что нашел и объяснил - как понял:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.None;
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.ResizeRedraw, true);
}
// Внутри клиентской области окна создаем витруальную изменяемую рамку окна.
// Она состоит из 6 функциональных областей: заголовка, верхней, нижней, левой, правой рамок
// и области в правом нижнем углу, перетаскивание которой изменяет размеры окна по диагонали
private const int ВысотаЗаголовка = 32;
private const int ВысотаВерхнейРамки = 5;
private const int ВысотаНижнейРамки = 5;
private const int ШиринаПравойРамки = 5;
private const int ШиринаЛевойРамки = 5;
private const int СторонаКвадратаВПравомНижнемУглу = 16;
protected override void OnPaint(PaintEventArgs e)
{
// Рисуем пиктограмму ручки изменения размеров окна по диагонали
Rectangle rc = new Rectangle(ClientSize.Width - СторонаКвадратаВПравомНижнемУглу,
ClientSize.Height - СторонаКвадратаВПравомНижнемУглу,
СторонаКвадратаВПравомНижнемУглу,
СторонаКвадратаВПравомНижнемУглу);
ControlPaint.DrawSizeGrip(e.Graphics, BackColor, rc);
// Раскрашиваем заголовок
//rc = new Rectangle(0, 0, this.ClientSize.Width, ВысотаЗаголовка);
//e.Graphics.FillRectangle(Brushes.DarkBlue, rc);
}
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x84) { // Trap WM_NCHITTEST
// Рассчитываем координаты курсора относительно клиентской области окна
Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
pos = this.PointToClient(pos);
// Назначаем нашу функциональность области окна в которой находится курсор
// с тем, чтобы вызвавший произвел с окном соответствующие этой функциональности действия
if (pos.Y <= ВысотаЗаголовка && pos.Y >= ВысотаВерхнейРамки) {
m.Result = (IntPtr)2; // HTCAPTION - курсор в заголовке окна
return;
}
if (pos.Y <= ВысотаВерхнейРамки) {
m.Result = (IntPtr)12; // HTTOP - курсор в верхней горизонтальной рамке окна
return;
}
if (pos.Y >= ClientSize.Height - ВысотаНижнейРамки &&
pos.X < ClientSize.Width - СторонаКвадратаВПравомНижнемУглу) {
m.Result = (IntPtr)15; // HTBOTTOM - курсор в нижней горизонтальной рамке окна
return;
}
if (pos.X >= ClientSize.Width - ШиринаПравойРамки &&
pos.Y < ClientSize.Height - СторонаКвадратаВПравомНижнемУглу) {
m.Result = (IntPtr)11; // HTRIGHT - курсор в правой вертикальной рамке окна
return;
}
if (pos.X <= ШиринаЛевойРамки) {
m.Result = (IntPtr)10; // HTLEFT - курсор в левой вертикальной рамке окна
return;
}
if (pos.X >= ClientSize.Width - СторонаКвадратаВПравомНижнемУглу &&
pos.Y >= ClientSize.Height - СторонаКвадратаВПравомНижнемУглу) {
m.Result = (IntPtr)17; // HTBOTTOMRIGHT - курсор в пиктограмме ручки изменения размера окна по диагонали
return;
}
}
base.WndProc(ref m);
}
}