Genişletilmiş cam alanında büyütülen olayı tıklayın?

Böylece formumun cam alanını DwmExtendFrameIntoClientArea (Vista/7 Aero gibi) ile istemci alanına genişletdim.

Burada açıklandığı gibi, pencerenin cam alanla birlikte hareket etmesine neden olan Form sınıfı yöntemi OnMouseDown() seçeneğine bir Windows iletisi göndermiştim sınırsız formu hareketli olun?

Bununla birlikte, genişletilmiş cam alanına tıklarken herhangi bir form Tıklama/MouseClick/DoubleClick vb.

Normal başlık çubukları gibi üst genişletilmiş cam alanını çift tıklattığımda formun büyütmesini istiyorum.

Form-Inheriting sınıfının kodu şöyledir:

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

Bunu işe almak için herhangi bir yolu var mı?

1
HT_CAPTION iletilerini gönderen doğru yoldasınız, ancak bunu bir WinForms olay işleyicisinde yapmamalısınız. Form sınıfı, HT_CAPTION göndermek için formunuz için geçersiz kılmanız gereken bir yerel WndProc() prosedürüne sahiptir. Kesin kodu tam olarak hatırlayamıyorum, ama wpf için benzer kod örneğim var .
katma yazar BoltClock, kaynak
@ Pac-Man: Gerçekten emin değilim, üzgünüm: /
katma yazar BoltClock, kaynak
Bu cevaptan çok iyi bir tavsiye almadın. Arama kutusuna 'wm_nchittest' yazın.
katma yazar Hans Passant, kaynak
Kod yazmanız gerekecek. Bunu ele alan olayın, Maksimize düğmesine basma yeteneğine bağlı olduğunu biliyorum. Bu devre dışı bırakılırsa, başlık çubuğuna çift tıklandığında hiçbir şey yapmazsınız, aslında en azından WinForms kadrosunda formun maksimize edilebilme özelliğini devre dışı bırakır.
katma yazar Security Hound, kaynak
@Ramhound: Tamam, mevcut fare ile ilgili kodu ekledim.
katma yazar Ray Koopa, kaynak
@BoltClock: Teşekkürler! Bu oldukça yardımcı oldu. Pencere sistemi menüsünü sağ tıklamayla nasıl alabilirim biliyor musunuz?
katma yazar Ray Koopa, kaynak
@BoltClock: Nasıl çözüme ulaştığımı ve nasıl eklediğimi öğrendim (cevap olarak kabul ettim) :)
katma yazar Ray Koopa, kaynak

1 cevap

WtF için bir çözüm için BoltClocks bana WinForms için benzer kod için bana ilham verdi.

Şimdi OnMouse * olayları yerine WndProc'u geçersiz kılıyorum.

Cam bölge tam olarak bir başlık çubuğu gibi davranır, örn. Windows 7'de dock desteği ile drag'n'drop ve maksimize/geri yükleme için çift tıklayın. Ayrıca, bu çözüm artık cam alanına sağ tıklandığında sistem penceresi bağlam menüsünü desteklemektedir.

[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
katma