поэтому я просто расширил область стекла моей формы в клиентскую область с помощью DwmExtendFrameIntoClientArea (Vista/7 Aero).
Я уже отправил сообщение Windows в методе переопределения класса Form OnMouseDown (), заставляя окно перемещаться со стеклянной областью, как описано здесь Сделать форму без полей подвижной? .
Однако из-за этого я не получаю никаких форм Click/MouseClick/DoubleClick и т. Д. Событий при нажатии на расширенную область стекла.
Я действительно хочу, чтобы форма максимизировалась, когда я дважды нажимаю верхнюю расширенную область стекла, как это делают обычные заголовки.
Вот код класса, наследующего форму:
protected override void OnMouseDown(MouseEventArgs e)
{
//Fensterverschiebung in Glass-Regionen
if (_glassMovable && e.Button == MouseButtons.Left
&& (e.X < _glassPadding.Left || e.X > Width - _glassPadding.Right
|| e.Y < _glassPadding.Top || e.Y > Height - _glassPadding.Bottom))
{
NativeMethods.ReleaseCapture();
NativeMethods.SendMessage(Handle, NativeMethods.WM_NCLBUTTONDOWN,
NativeMethods.HT_CAPTION, 0);
}
base.OnMouseDown(e);
}
protected override void OnMouseDoubleClick(MouseEventArgs e)
{
//Fenstermaximierung/Minimierung in Glass-Regionen
if (MaximizeBox && e.Button == MouseButtons.Left && e.Y < _glassPadding.Top)
{
if (WindowState == FormWindowState.Normal)
{
WindowState = FormWindowState.Maximized;
}
else if (WindowState == FormWindowState.Maximized)
{
WindowState = FormWindowState.Normal;
}
}
base.OnMouseDoubleClick(e);
}
Есть ли способ заставить это работать?
Ссылка BoltClocks на решение для WPF вдохновила меня на следующий, похожий код для WinForms.
Теперь я переопределяю WndProc вместо событий OnMouse *.
Область стекла ведет себя точно так же, как строка заголовка, например. drag'n'drop с поддержкой док-станции в Windows 7 и двойной щелчок для максимизации/восстановления. Кроме того, это решение теперь поддерживает контекстное меню системного окна при щелчке правой кнопкой мыши по области стекла.
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
private const int WM_NCHITTEST = 0x0084;
private const int WM_NCRBUTTONDOWN = 0x00A4;
private const int WM_SYSCOMMAND = 0x0112;
private const int HT_CAPTION = 0x02;
private const int TPM_RIGHTBUTTON = 0x0002;
private const int TPM_RETURNCMD = 0x0100;
[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll")]
private static extern int TrackPopupMenu(int hMenu, int wFlags, int x, int y,
int nReserved, int hwnd, ref RECT lprc);
[DllImport("user32.dll")]
private static extern int PostMessage(int hWnd, int Msg, int wParam,
int lParam);
protected override void WndProc(ref Message m)
{
if (!DesignMode)
{
switch (m.Msg)
{
case WM_NCHITTEST:
if (MouseInClientArea())
{
if (MouseInGlassArea())
{
m.Result = (IntPtr)HT_CAPTION;
}
else
{
m.Result = IntPtr.Zero;
}
return;
}
break;
case WM_NCRBUTTONDOWN:
if (MouseInClientArea())
{
IntPtr menuHandle = GetSystemMenu(Handle, false);
RECT rect = new RECT();
int menuItem = TrackPopupMenu(menuHandle.ToInt32(),
TPM_RIGHTBUTTON | TPM_RETURNCMD,
Cursor.Position.X, Cursor.Position.Y, 0,
Handle.ToInt32(), ref rect);
if (menuItem != 0)
{
PostMessage(Handle.ToInt32(), WM_SYSCOMMAND,
menuItem, 0);
}
}
break;
}
}
base.WndProc(ref m);
}
private bool MouseInClientArea()
{
Point p = PointToClient(Cursor.Position);
return (p.X > 0 && p.X < ClientRectangle.Width
&& p.Y > 0 && p.Y < ClientRectangle.Height);
}
private bool MouseInGlassArea()
{
if (_glassPadding.Left == -1 || _glassPadding.Right == -1
|| _glassPadding.Top == -1 || _glassPadding.Bottom == -1)
{
return true;
}
else
{
Point p = PointToClient(Cursor.Position);
return (p.X < _glassPadding.Left
|| p.X > ClientRectangle.Width - _glassPadding.Right
|| p.Y < _glassPadding.Top
|| p.Y > ClientRectangle.Height - _glassPadding.Bottom);
}
}