Натискати на подію, не підняту в зоні розширеного скла?

тому я просто розширив скляне поле моєї форми в клієнтській області за допомогою DwmExtendFrameIntoClientArea (речі Vista/7 Aero).

Я вже надіслав повідомлення Windows у формі класу "Перевизначення класу" 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);
}

Чи є спосіб отримати це на роботу?

1
Ви перебуваєте на правильному шляху, надсилаючи повідомлення HT_CAPTION , але ви не повинні робити це в обробнику подій WinForms. Клас Form має власну процедуру WndProc() , яку слід перевизначити для вашої форми, щоб відправити HT_CAPTION . Я не можу пам'ятати біта точний код, але У мене є аналогічний зразок коду для wpf .
додано Автор BoltClock, джерело
@ Pac-Man: Що я не дуже впевнений, вибачте: /
додано Автор BoltClock, джерело
Ви не отримали дуже корисного поради з цієї відповіді. Введіть 'wm_nchittest' у вікні пошуку.
додано Автор Hans Passant, джерело
Вам потрібно буде опублікувати код. Я знаю, що подія, яка обробляє це, пов'язана з можливістю натискати кнопку "Збільшити". Якщо це буде вимкнено, подвійне клацання на панелі заголовка нічого не зробить, воно фактично вимикає можливість максимізації форми, принаймні, у відтворенні WinForms.
додано Автор Security Hound, джерело
@Ramhound: Добре, я додав поточний код миші.
додано Автор Ray Koopa, джерело
@BoltClock: Дякую! Це дуже допомогло. Чи знаєте ви, як я можу отримати меню вікна системи за допомогою клацання правою кнопкою миші?
додано Автор Ray Koopa, джерело
@BoltClock: я дізнався, як додати його до рішення нижче (який я просто прийняв як відповідь) :)
додано Автор Ray Koopa, джерело

1 Відповіді

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);
    }
}
2
додано
var chat = new Chat();
var chat = new Chat();
642 учасників

Обсуждение вопросов по C# / .NET / .NET Core / .NET Standard / Azure Сообщества-организаторы: — @itkpi — @dncuug