Как не дать диалогу оставить родительские границы?

1

У меня есть окно, которое показывает перетаскиваемый диалог, однако я не хочу, чтобы диалоговое окно покидало границы родительского окна.

using (var dialog = new MyDialog())
{
    if (dialog.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
    {
        // do something
    }
}

Как я могу это сделать?

  • 0
    Не. Позвольте пользователю делать то, что он хочет или нуждается.
  • 0
    @TaW прав. Вы сказали «родительское окно», но ваш код не отображает родительские dialog.MDIParent = this : dialog.MDIParent = this или что-то подобное.
Показать ещё 3 комментария
Теги:
winforms
.net-3.5

1 ответ

2
Лучший ответ

Вы можете попытаться перезаписать метод формы WndProc и WM_WINDOWPOSCHANGING системное сообщение WM_WINDOWPOSCHANGING для новой позиции и размера:

public class DialogForm : Form
{
    private struct WindowPos
    {
        public IntPtr hwnd;
        public IntPtr hwndInsertAfter;
        public int x;
        public int y;
        public int cx;
        public int cy;
        public uint flags;
    }

    public DialogForm()
    {
    }

    protected override void WndProc(ref Message m)
    {
        const int WM_WINDOWPOSCHANGING = 0x0046;
        if (m.Msg == WM_WINDOWPOSCHANGING)
        {
            WindowPos mwp = (WindowPos)Marshal.PtrToStructure(m.LParam, typeof(WindowPos));
            if (mwp.hwnd == Handle)
            {
                const int SWP_NOMOVE = 0x0002;
                const int SWP_NOSIZE = 0x0001;
                int x = mwp.x;
                int y = mwp.y;
                if (x < Owner.Left || y < Owner.Top || x + mwp.cx > Owner.Right || y + mwp.cy > Owner.Bottom)
                {
                    m.Result = IntPtr.Zero;
                    mwp.flags |= SWP_NOMOVE | SWP_NOSIZE;
                    Marshal.StructureToPtr(mwp, m.LParam, true);
                }
            }
        }
        base.WndProc(ref m);
    }
}

РЕДАКТИРОВАТЬ. Для большей гладкости используйте этот метод:

protected override void WndProc(ref Message m)
{
    const int WM_WINDOWPOSCHANGING = 0x0046;
    if (m.Msg == WM_WINDOWPOSCHANGING)
    {
        WindowPos mwp = (WindowPos)Marshal.PtrToStructure(m.LParam, typeof (WindowPos));
        if (mwp.hwnd == Handle)
        {
            int x = mwp.x;
            int y = mwp.y;
            if (x < Owner.Left || y < Owner.Top || x + mwp.cx > Owner.Right || y + mwp.cy > Owner.Bottom)
            {
                bool resizing = mwp.cx != Width || mwp.cy != Height;
                if (resizing)
                {
                    if (x < Owner.Left)
                    {
                        mwp.x = x = Owner.Left;
                        mwp.cx = Width;
                    }
                    if (y < Owner.Top)
                    {
                        mwp.y = y = Owner.Top;
                        mwp.cy = Height;
                    }

                    if (mwp.cx > Owner.Right - x)
                        mwp.cx = Owner.Right - x;
                    if (mwp.cy > Owner.Bottom - y)
                        mwp.cy = Owner.Bottom - y;
                }
                else
                {
                    if (x < Owner.Left)
                        mwp.x = Owner.Left;
                    else if (x > Owner.Right - mwp.cx)
                        mwp.x = Owner.Right - mwp.cx;

                    if (y < Owner.Top)
                        mwp.y = Owner.Top;
                    else if (y > Owner.Bottom - mwp.cy)
                        mwp.y = Owner.Bottom - mwp.cy;
                }
                m.Result = IntPtr.Zero;
                Marshal.StructureToPtr(mwp, m.LParam, true);
            }
        }
    }
    base.WndProc(ref m);
}
  • 0
    Это не очень гладко, однако это работает. Я посмотрю, что я могу сделать, чтобы изменить код, чтобы он работал более плавно, иначе я попробую альтернативный подход к этой задаче. Спасибо.
  • 0
    Если я правильно понимаю, что такое гладкость в этом случае, был добавлен более плавный метод.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню