点击事件未在扩展玻璃区域中引发?

发布于 12-12 09:54 字数 1511 浏览 7 评论 0原文

所以我只是使用 DwmExtendFrameIntoClientArea (Vista / 7 Aero 的东西)将窗体的玻璃区域扩展到客户区域。

我已经在覆盖 Form 类方法 OnMouseDown() 中发送了一条 Windows 消息,导致窗口可以随玻璃区域移动,如此处所述 使无边框表单可移动?

但是,因此,当单击扩展玻璃区域时,我没有收到任何形式的 Click / MouseClick / DoubleClick 等事件。

实际上,我希望当我双击顶部扩展玻璃区域时,表单最大化,就像普通标题栏一样。

下面是 Form 继承类的代码:

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);
}

有什么方法可以让它工作吗?

so I just expanded the glass area of my form into the client area with DwmExtendFrameIntoClientArea (Vista / 7 Aero stuff).

I have already sent a Windows message in the override Form class method OnMouseDown() causing the window to be movable with the glass area, as explained here Make a borderless form movable?.

However because of this, I am not receiving any form Click / MouseClick / DoubleClick etc. events when clicking on the expanded glass area.

I actually want the form to maximize when I double click the top expanded glass area, like normal titlebars do.

Here's the code of the Form-inheriting class:

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);
}

Is there any way to get this to work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

热血少△年2024-12-19 09:54:08

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);
    }
}

BoltClocks link to a solution for WPF inspired me for the following, similar code for WinForms.

I now override WndProc instead of the OnMouse* events.

The glass region behaves exactly like a title bar, e.g. drag'n'drop with dock support in Windows 7 and double click for maximizing / restoring. Additionally, this solution now supports the system window context menu when right clicking the glass area.

[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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文