Why doesn't GroupBox have a MouseMove event?

The WinForms GroupBox control does not support MouseMove (or at least not sequentially), and I do not understand why.

Since it descends from Control, it has a MouseMove event, but the GroupBox explicitly enters it with Browsable(false), so it does not appear in the Property Grid. You can hook up the MouseMove event at run time, and sometimes it works - as long as the FlatStyle remains in the standard. If GroupBox FlatStyle is set to System, then no MouseMove events fire at all.

The reflector did not give me any clues. The GroupBox constructor doesn't seem to set any weird control styles, and the GroupBox doesn't do anything stupid like overriding MouseMove and cannot invoke the base.

This is also a WinForms limiting limitation, because OnMouseMove is supported just fine in the blocks of the Delphi group. Bugfix: comparison with Delphi is not valid. Delphi group boxes are not really standard BM_GROUPBOX controls; they are simply drawn before look , for example, of group boxes, without actually inheriting strange group behaviors like this. Thus, this may be a limitation of managing Windows group mailbox, although I have not seen anything documented anywhere.

Why does WinForms GroupBox not support MouseMove?

+3
source share
4 answers

According to this thread , a standard Windows batch package (i.e. a BUTTON control with the BS_GROUPBOX style) appears to return HTTRANSPARENT in response to WM_NCHITTEST, Since the control claims to be transparent, Windows sends mouse movement events to the parent window.

The thread confirms that if you process WM_NCHITTEST yourself and return HTCLIENT, the group package will receive mouse movement events. They use MFC, but this probably works for WinForms as well.

It is not clear why Windows returns HTTRANSPARENT by default, but at least the problem has been independently confirmed.

+4
source

Reflector, CreateParams OwnerDraw. GroupBox OwnerDraw = true, , FlatStyle = System. Windows group, , BUTTON BS_GROUPBOX.

Spy ++, , . , , SDK . , Windows 2.x, . , MouseMove , . Click Up/Down. FlatStyle , Control.UserMouse.

Anyhoo, , .

+2

, . "" , , . , , GroupBox.

, , GroupBox . , , MouseMove.

, , ... , VB.NET, #, , , , : <p > . , , , ... .

: , , WM_MOUSEMOVE... , VS 2008 Pro.

    public class MyGroupBox : System.Windows.Forms.GroupBox
    {
        private SubClass sc;
        private const int WM_MOUSEMOVE = 0x200;
        public delegate void MyMouseMoveEventHandler(object sender, System.EventArgs e);
        public event MyMouseMoveEventHandler MyMouseMove;
        public MyGroupBox()
            : base()
        {
            sc = new SubClass(this.Handle, true);
            sc.SubClassedWndProc += new SubClass.SubClassWndProcEventHandler(sc_SubClassedWndProc);
        }

        protected override void Dispose(bool disposing)
        {
            if (sc.SubClassed)
            {
                sc.SubClassedWndProc -= new SubClass.SubClassWndProcEventHandler(sc_SubClassedWndProc);
                sc.SubClassed = false;
            }
            base.Dispose(disposing);
        }
        private void OnMyMouseMove()
        {
            if (this.MyMouseMove != null) this.MyMouseMove(this, System.EventArgs.Empty);
        }
        void sc_SubClassedWndProc(ref Message m)
        {
            if (m.Msg == WM_MOUSEMOVE) this.OnMyMouseMove();
        }

    }

    #region SubClass Classing Handler Class
    public class SubClass : System.Windows.Forms.NativeWindow
    {
        public delegate void
          SubClassWndProcEventHandler(ref System.Windows.Forms.Message m);
        public event SubClassWndProcEventHandler SubClassedWndProc;
        private bool IsSubClassed = false;

        public SubClass(IntPtr Handle, bool _SubClass)
        {
            base.AssignHandle(Handle);
            this.IsSubClassed = _SubClass;
        }

        public bool SubClassed
        {
            get { return this.IsSubClassed; }
            set { this.IsSubClassed = value; }
        }

        protected override void WndProc(ref Message m)
        {
            if (this.IsSubClassed)
            {
                OnSubClassedWndProc(ref m);
            }
            base.WndProc(ref m);
        }

        #region HiWord Message Cracker
        public int HiWord(int Number)
        {
            return ((Number >> 16) & 0xffff);
        }
        #endregion

        #region LoWord Message Cracker
        public int LoWord(int Number)
        {
            return (Number & 0xffff);
        }
        #endregion

        #region MakeLong Message Cracker
        public int MakeLong(int LoWord, int HiWord)
        {
            return (HiWord << 16) | (LoWord & 0xffff);
        }
        #endregion

        #region MakeLParam Message Cracker
        public IntPtr MakeLParam(int LoWord, int HiWord)
        {
            return (IntPtr)((HiWord << 16) | (LoWord & 0xffff));
        }
        #endregion

        private void OnSubClassedWndProc(ref Message m)
        {
            if (SubClassedWndProc != null)
            {
                this.SubClassedWndProc(ref m);
            }
        }
    }
    #endregion

  • .
  • , groupBox1
  • , :
    System.Windows.Forms.GroupBox groupBox1;
    WindowsApplication.MyGroupBox groupBox1;
  • InitializeComponent() GroupBox :
    this.groupBox1 = new WindowsApplication.MyGroupBox();
  • .
  • , MyMouseMove .
  • :
        private void groupBox1_MyMouseMove(object sender, EventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("MyMouseMove!");
        }

Launch the application and each time you move the mouse inside the group window, you will see the output "MyMouseMove!".

Hope this gives you a hint, Best regards, Tom.

0
source

I noticed that many events for certain controls are not available through the events tab (in the "Properties" section) in VS. You can simply assign an event handler manually in the parent form of Designer to InitializeComponents():

this.groupBox1.MouseMove += new MouseEventHandler(this.groupBox1_MouseMove);

This will call the following method:

private void groupBox1_MouseMove(object sender, MouseEventArgs e)
{
    //doodle the stuff you want to happen after the trigger here
};
0
source

Source: https://habr.com/ru/post/1722494/


All Articles