Klik evenement niet verhoogd in gebied met uitgebreid glas?

dus heb ik gewoon het glazen gedeelte van mijn formulier uitgebreid naar het client-gebied met DwmExtendFrameIntoClientArea (Vista/7 Aero-dingen).

Ik heb al een Windows-bericht verzonden in de vervangende Form class-methode OnMouseDown() waardoor het venster verplaatsbaar is met het glazen gebied, zoals hier wordt uitgelegd Maak een randloos formulier verplaatsbaar? .

Om deze reden ontvang ik geen enkele vorm van Click/MouseClick/DoubleClick etc. -gebeurtenissen wanneer ik op het gebied met de uitgebreide glazen klik.

Ik wil eigenlijk dat de vorm maximaliseert wanneer ik dubbelklik op het bovenste gebied met uitgebreid glas, zoals normale titelbalken.

Hier is de code van de 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 er een manier om dit te laten werken?

1
U bent op de goede weg met het verzenden van HT_CAPTION berichten, maar u zou dit niet moeten doen in een WinForms-gebeurtenisafhandelaar. De klasse Form heeft een native WndProc() -procedure die u moet negeren voor uw formulier om HT_CAPTION te verzenden. Ik kan me niet de exacte code herinneren, maar Ik heb een vergelijkbaar codevoorbeeld voor wpf .
toegevoegd de auteur BoltClock, de bron
@ Pac-Man: Dat ben ik niet echt zeker, sorry: /
toegevoegd de auteur BoltClock, de bron
Je hebt geen goed advies gekregen van dat antwoord. Typ 'wm_nchittest' in het vak Zoeken.
toegevoegd de auteur Hans Passant, de bron
U moet code plaatsen. Ik weet wel dat de gebeurtenis die dit afgeeft verbonden is met de mogelijkheid om op de knop Maximaliseren te klikken. Als dat is uitgeschakeld, dubbelklikt u op de titelbalk om niets te doen, maar wordt de mogelijkheid om het formulier te maximaliseren ten minste uitgeschakeld in de cast van WinForms.
toegevoegd de auteur Security Hound, de bron
@Ramhound: Ok, ik heb de huidige muisgerelateerde code toegevoegd.
toegevoegd de auteur Ray Koopa, de bron
@BoltClock: Bedankt! Dit hielp vrijwel. Weet je hoe ik het menu van het venstersysteem ook kan krijgen door met de rechtermuisknop te klikken?
toegevoegd de auteur Ray Koopa, de bron
@BoltClock: Ik ontdekte hoe en voegde het toe in de onderstaande oplossing (die ik zojuist heb geaccepteerd als antwoord) :)
toegevoegd de auteur Ray Koopa, de bron

1 antwoord

BoltClocks-koppeling naar een oplossing voor wpf inspireerde me voor de volgende, vergelijkbare code voor WinForms.

Ik overschrijf nu WndProc in plaats van de OnMouse * -gebeurtenissen.

Het glasgebied gedraagt ​​zich precies als een titelbalk, b.v. drag'n'drop met dock-ondersteuning in Windows 7 en dubbelklik voor maximaliseren/herstellen. Bovendien ondersteunt deze oplossing nu het contextmenu van het systeemvenster wanneer u met de rechtermuisknop op het glazen gebied klikt.

[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);
    }
}
2
toegevoegd