所以我只是用DwmExtendFrameIntoClientArea(Vista / 7 Aero的东西)将表单的玻璃区域扩展到客户区。
我已经在覆盖Form类方法OnMouseDown()中发送了一条Windows消息,导致窗口可以与玻璃区域一起移动,如Make a borderless form movable?所述。
但是正因为如此,我在点击展开的玻璃区域时没有收到任何形式的Click / MouseClick / DoubleClick等事件。
当我双击顶部展开的玻璃区域时,我实际上希望表单最大化,就像普通的标题栏一样。
以下是Form-inheriting类的代码:
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);
}
有什么方法可以让它发挥作用吗?
答案 0 :(得分:2)
BoltClocks链接到WPF的解决方案激发了我以下类似的WinForms代码。
我现在覆盖WndProc而不是OnMouse *事件。
玻璃区域的行为与标题栏完全相同,例如:在Windows 7中使用Dock支持拖放并双击以最大化/恢复。此外,此解决方案现在支持右键单击玻璃区域时的系统窗口上下文菜单。
[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);
}
}