Как установить минимальный размер настраиваемого элемента управления с помощью CreateParams - PullRequest
0 голосов
/ 19 июня 2020

Я пытаюсь сделать перетаскиваемую , панель с изменяемым размером с минимальным размером . Я использовал CreateParams для изменения размера, и теперь свойство Minimum size не работает.

Мой вопрос, как установить минимальный размер в этом случае?

Я пробовал Ограничить изменяемые размеры настраиваемого элемента управления (c#. net) но не могу заставить его работать.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Move_Resize_Controls
{
    class MyPanel: Panel
    {
        // For Moving Panel "Drag the Titlebar and move the panel"
        public const int WM_NCLBUTTONDOWN = 0xA1;
        public const int HT_CAPTION = 0x2;

        [DllImportAttribute("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd,
                         int Msg, int wParam, int lParam);
        [DllImportAttribute("user32.dll")]
        public static extern bool ReleaseCapture();

        // Constructor
        public MyPanel()
        {
            typeof(MyPanel).InvokeMember("DoubleBuffered", BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic, null, this, new object[] { true }); // Double buffer MyPanel
            TitleBar(); // TitleBar
        }

        // Resize function for the panel - "Resizable Panel"
        protected override CreateParams CreateParams
        {
            get
            {
                var cp = base.CreateParams;
                cp.Style |= (int)0x00040000L;  // Turn on WS_BORDER + WS_THICKFRAME
                //cp.Style |= (int)0x00C00000L;  // Move
                return cp;
            }
        }

        // The Title Bar
        private void TitleBar()
        {
            Panel titleBar = new Panel();
            titleBar.BackColor = Color.Black;
            titleBar.Size = new Size(this.Size.Width, 20);
            titleBar.Dock = DockStyle.Top;
            this.Controls.Add(titleBar);

            titleBar.MouseDown  += new System.Windows.Forms.MouseEventHandler(this.MouseDownTitleBar); // Mouse Down - Event
            typeof(Panel).InvokeMember("DoubleBuffered", BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic, null, titleBar, new object[] { true }); // Double Buffered 
        }

        // Move Panel
        private void MouseDownTitleBar(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ReleaseCapture();
                SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
            }
        }
    }
}

Ответы [ 3 ]

1 голос
/ 19 июня 2020

Задайте свойство MinimumSize(), чтобы вы хотели, чтобы ваш элемент управления (как обычно, через IDE или через код), затем добавьте приведенный ниже код в свой элемент управления, чтобы перехватить сообщение WM_GETMINMAXINFO и переопределить минимум размер, поскольку размер элемента управления динамически изменяется:

class MyPanel: Panel
{

    public const int WM_GETMINMAXINFO = 0x24;

    public struct POINTAPI
    {
        public Int32 X;
        public Int32 Y;
    }

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

    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case WM_GETMINMAXINFO:
                MINMAXINFO mmi = (MINMAXINFO)System.Runtime.InteropServices.Marshal.PtrToStructure(m.LParam, typeof(MINMAXINFO));
                mmi.ptMinTrackSize.X = this.MinimumSize.Width;
                mmi.ptMinTrackSize.Y = this.MinimumSize.Height;
                System.Runtime.InteropServices.Marshal.StructureToPtr(mmi, m.LParam, true);
                break;
        }
        base.WndProc(ref m);
    }

}
0 голосов
/ 19 июня 2020

Полный рабочий код: Спасибо за помощь

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Move_Resize_Controls
{
    class MyPanel: Panel
    {


        // For Moving Panel "Drag the Titlebar and move the panel"
        public const int WM_NCLBUTTONDOWN = 0xA1;
        public const int HT_CAPTION = 0x2;

        [DllImportAttribute("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd,
                         int Msg, int wParam, int lParam);
        [DllImportAttribute("user32.dll")]
        public static extern bool ReleaseCapture();





        // Constructor
        public MyPanel()
        {

            typeof(MyPanel).InvokeMember("DoubleBuffered", BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic, null, this, new object[] { true }); // Double buffer MyPanel
            TitleBar(); // TitleBar
            this.MinimumSize = new System.Drawing.Size(200, 200);
        }






        // Resize function for the panel - "Resizable Panel"
        protected override CreateParams CreateParams
        {
            get
            {
                var cp = base.CreateParams;
                cp.Style |= (int)0x00040000L;  // Turn on WS_BORDER + WS_THICKFRAME
                //cp.Style |= (int)0x00C00000L;  // Move
                return cp;

            }
        }







        // The Title Bar
        private void TitleBar()
        {
            Panel titleBar = new Panel();
            titleBar.BackColor = Color.Black;
            titleBar.Size = new Size(this.Size.Width, 20);
            titleBar.Dock = DockStyle.Top;
            this.Controls.Add(titleBar);

            titleBar.MouseDown  += new System.Windows.Forms.MouseEventHandler(this.MouseDownTitleBar); // Mouse Down - Event
            typeof(Panel).InvokeMember("DoubleBuffered", BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic, null, titleBar, new object[] { true }); // Double Buffered 

        }








        // Move Panel
        private void MouseDownTitleBar(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ReleaseCapture();
                SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
            }
        }






     // Make the Minumum Size - Work
        public const int WM_GETMINMAXINFO = 0x24;

        public struct POINTAPI
        {
            public Int32 X;
            public Int32 Y;
        }


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


        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_GETMINMAXINFO:
                    MINMAXINFO mmi = (MINMAXINFO)System.Runtime.InteropServices.Marshal.PtrToStructure(m.LParam, typeof(MINMAXINFO));
                    mmi.ptMinTrackSize.X = this.MinimumSize.Width;
                    mmi.ptMinTrackSize.Y = this.MinimumSize.Height;
                    System.Runtime.InteropServices.Marshal.StructureToPtr(mmi, m.LParam, true);
                    break;
            }
            base.WndProc(ref m);
        }




    }
}
0 голосов
/ 19 июня 2020

Просто установите свойство MinimumSize:

Этот класс является частью одного из моих пакетов Nuget. Я добавил этот MinimumSize в конструктор, просто чтобы показать вам, у меня обычно этого нет в коде:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DataJuggler.Win.Controls.Objects
{

    #region class PanelExtender : Panel
    /// <summary>
    /// This class inherits from Panel; this is intended to stop the flickering on panels
    /// </summary>
    public class PanelExtender : Panel
    {

        #region Constructor
        /// <summary>
        /// Create a new instance of a PanelExtender object
        /// </summary>
        public PanelExtender()
        {
            // Set Style to stop flickering
            this.SetStyle(System.Windows.Forms.ControlStyles.UserPaint | System.Windows.Forms.ControlStyles.AllPaintingInWmPaint | System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer, true);

            // Set the minimum size
            this.MinimumSize = new System.Drawing.Size(400, 800);
        }
        #endregion

        #region Properties

            #region CreateParams
            /// <summary>
            /// This property here is what did the trick to reduce the flickering.
            /// I also needed to make all of the controls Double Buffered, but
            /// this was the final touch. It is a little slow when you switch tabs
            /// but that is because the repainting is finishing before control is
            /// returned.
            /// </summary>
            protected override CreateParams CreateParams
            {
                get
                {
                    // initial value
                    CreateParams cp = base.CreateParams;

                    // Apparently this interrupts Paint to finish before showing
                    cp.ExStyle |= 0x02000000;

                    // return value
                    return cp;
                }
            }
            #endregion

        #endregion

    }
    #endregion

}

Я не уверен, какое изменение размера вам нужно, настройте его в соответствии с вашей ситуацией.

Если хотите:

Nuget: DataJuggler.Win.Controls

Источник: https://github.com/DataJuggler/DataJuggler.Win.Controls

...