Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Разработка Windows Forms > Окно с фиксированной высотой


Автор: Voyager 13.2.2009, 12:13
Интересует как сделать форму с фиксированной высотой  (например как в Delphi 7, на форме меню, тулбары).
Кинул на форму меню, тулбары, все это лежит в toolStripContainer. Окно должно автоматически менять высоту при перетаскивании тулбаров (например по высоте toolStripContainer).

Код:
Код

 public partial class Form1 : Form
    {
        //---------------------------------------------------------------------

        private const int WM_GETMINMAXINFO = 0x24;
        private const int WM_SIZE = 5;
        private const int WM_WINDOWPOSCHANGING = 70;

        public struct POINTAPI
        {
            public int x;
            public int y;
        }

        public struct MINMAXINFO
        {
            public POINTAPI ptReserved;
            public POINTAPI ptMaxSize;
            public POINTAPI ptMaxPosition;
            public POINTAPI ptMinTrackSize;
            public POINTAPI ptMaxTrackSize;
        }

        //---------------------------------------------------------------------

        public Form1()
        {
            InitializeComponent();
        }

        //---------------------------------------------------------------------

        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            if (m.Msg == WM_GETMINMAXINFO)
            {
                int h = Size.Height - ClientSize.Height + toolStripContainer1.TopToolStripPanel.Height;
                MINMAXINFO mmi = (MINMAXINFO)m.GetLParam(typeof(MINMAXINFO));
                mmi.ptMinTrackSize.y = h;
                mmi.ptMaxTrackSize.y = h;
                Marshal.StructureToPtr(mmi, m.LParam, true);
            }
            base.WndProc(ref m);
        }

        //---------------------------------------------------------------------

        private void toolStripContainer1_TopToolStripPanel_SizeChanged(object sender, EventArgs e)
        {
            int h = Size.Height - ClientSize.Height + toolStripContainer1.TopToolStripPanel.Height;
            this.Height = h;
        }

        //---------------------------------------------------------------------
    }


Пример в аттаче.

В состоянии WindowState=Normal работает как надо, при максимизации (WindowState=Maximazed) проблемы - окно можно перетаскивать за заголовок (нужно отключить, чтобы в максимизированном состоянии вело себя как обычное окно) и не меняется автоматически высота при перетаскивании тулбаров. При сворачивании-разворачивании сбивается высота окна. Есть идеи как побороть?

В принципе перетаскивание окна в максимизированном состоянии поборол так (как вариант):
Код

        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            if (m.Msg == WM_GETMINMAXINFO)
            {
                int h = Size.Height - ClientSize.Height + toolStripContainer1.TopToolStripPanel.Height;
                MINMAXINFO mmi = (MINMAXINFO)m.GetLParam(typeof(MINMAXINFO));
                mmi.ptMinTrackSize.y = h;
                mmi.ptMaxTrackSize.y = h;
                Marshal.StructureToPtr(mmi, m.LParam, true);
            }
            else if (m.Msg == WM_WINDOWPOSCHANGING
                && this.WindowState == FormWindowState.Maximized)
            {
                WINDOWPOS wp = (WINDOWPOS)Marshal.PtrToStructure(m.LParam, typeof(WINDOWPOS));
                wp.x = this.Left;
                wp.y = this.Top;
                Marshal.StructureToPtr(wp, m.LParam, true);
            }
            base.WndProc(ref m);
        }


Остается автоматическое изменение высоты при Maximazed и сворачивание/разворачивание.

Автор: emmanuil 17.2.2009, 07:08
Файл не смотрел. Если я все правильно понял, то может вот так подойдет?
Код

        private int height;

        public Form1() {
            InitializeComponent();
            height = toolStripContainer1.TopToolStripPanel.Height;
        }

        private void toolStripContainer1_ContentPanel_Resize(object sender, EventArgs e) { // можно вместо этого на событие TopToolStripPanel подписаться
            if (this.WindowState == FormWindowState.Normal) {
                this.ClientSize = new Size(this.ClientSize.Width,
                    this.ClientSize.Height + (toolStripContainer1.TopToolStripPanel.Height - height));
            }
            height = toolStripContainer1.TopToolStripPanel.Height;
        }

Автор: Voyager 17.2.2009, 14:43
Решил сам, если кому интересно:

Код

 public partial class Form1 : Form
    {
        //---------------------------------------------------------------------

        private const int WM_GETMINMAXINFO = 0x24;
         private const int WM_WINDOWPOSCHANGING = 0x46;
 
        public struct POINTAPI
        {
            public int x;
            public int y;
        }

        public struct MINMAXINFO
        {
            public POINTAPI ptReserved;
            public POINTAPI ptMaxSize;
            public POINTAPI ptMaxPosition;
            public POINTAPI ptMinTrackSize;
            public POINTAPI ptMaxTrackSize;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct WINDOWPOS
        {
            public IntPtr hwnd;
            public IntPtr hwndInsertAfter;
            public int x;
            public int y;
            public int cx;
            public int cy;
            public int flags;
        }

        //---------------------------------------------------------------------

        public Form1()
        {
            InitializeComponent();
        }

        //---------------------------------------------------------------------

        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            if (m.Msg == WM_GETMINMAXINFO)
            {
                int h = Size.Height - ClientSize.Height + toolStripContainer1.TopToolStripPanel.Height;
                MINMAXINFO mmi = (MINMAXINFO)m.GetLParam(typeof(MINMAXINFO));
                mmi.ptMinTrackSize.y = h;
                mmi.ptMaxTrackSize.y = h;
                Marshal.StructureToPtr(mmi, m.LParam, true);
            }
            else if (m.Msg == WM_WINDOWPOSCHANGING
                && this.WindowState == FormWindowState.Maximized)
            {
                WINDOWPOS wp = (WINDOWPOS)Marshal.PtrToStructure(m.LParam, typeof(WINDOWPOS));
                wp.x = this.Left;
                wp.y = this.Top;
                Marshal.StructureToPtr(wp, m.LParam, true);
            }
            base.WndProc(ref m);
        }

        //---------------------------------------------------------------------

        private void toolStripContainer1_TopToolStripPanel_SizeChanged(object sender, EventArgs e)
        {
            int h = Size.Height - ClientSize.Height + toolStripContainer1.TopToolStripPanel.Height;
            this.Height = h;
            if (WindowState == FormWindowState.Maximized)
            {
                Rectangle rc = RestoreBounds;
                this.MinimumSize = new Size(this.MinimumSize.Width, h);
                Bounds = rc;
            }
            else if (WindowState == FormWindowState.Normal)
            {
                this.MinimumSize = new Size(this.MinimumSize.Width, h);
            }
        }        

        //---------------------------------------------------------------------

       
    }


Автор: emmanuil 18.2.2009, 05:30
Voyager, ты мой пост читал? Не подошло?!  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)