Я создаю собственное нарисованное окно, указав стиль границы NONE и пользовательскую обработку WM_NCHITTEST. Я определил некоторую область как «заголовок моего окна» и возвращаю результат HTCAPTION для WM_NCHITTEST в этой области. Когда окно находится в нормальном состоянии, поведение я ожидаю. Окно можно перемещать, перетаскивая «заголовок моего окна», и его можно развернуть, дважды щелкнув по нему.
Проблема в поведении моего окна в развернутом состоянии. Я все еще возвращаю результат HTCAPTION для WM_NCHITTEST в области «заголовка моего окна», и окно можно восстановить до исходного размера, дважды щелкнув по нему снова, но его также можно переместить, и это не то, что я хочу. Что я должен сделать, чтобы исправить такое поведение?
Fix:
protected override void WndProc(ref Message m)
{
if(m.Msg == WM_NCHITTEST)
{
Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
pos = this.PointToClient(pos);
if(HitTestForNC(ref m, pos))
{
if(WindowState != FormWindowState.Maximized || m.Result != (IntPtr)HitTestValues.HTCAPTION)
{
return;
}
}
}
else if(m.Msg == WM_GETMINMAXINFO)
{
base.WndProc(ref m);
MinMaxInfo mmi = (MinMaxInfo)Marshal.PtrToStructure(m.LParam, typeof(MinMaxInfo));
mmi.ptMaxPosition = Screen.FromControl(this).WorkingArea.Location;
mmi.ptMaxSize = Screen.FromControl(this).WorkingArea.Size;
Marshal.StructureToPtr(mmi, m.LParam, false);
return;
}
base.WndProc(ref m);
}
protected override void OnMouseDoubleClick(MouseEventArgs e)
{
if(e.Button == MouseButtons.Left)
{
Message m = new Message();
if(HitTestForNC(ref m, e.Location))
{
if(m.Result == (IntPtr)HitTestValues.HTCAPTION && WindowState == FormWindowState.Maximized)
{
WindowState = FormWindowState.Normal;
return;
}
}
}
base.OnMouseDoubleClick(e);
}
Метод HitTestForNC отвечает за оценку результата теста на удар в моей пользовательской нарисованной форме. Реализация может выглядеть уродливо, но это довольно просто.