none
コントロール上のマウスイベントを親フォームですべて受け取る方法 RRS feed

  • 質問

  • FormクラスのControlsに追加した各種コントロールで発生したマウス関連のイベントをすべてFormクラス内で処理できる方法(いわばKeyPreviewのマウス版)を探しています。今のところ検討している方法は子コントロールすべてにMouseイベントを追加して、その子コントロールでイベントが発生したときは、親フォームにイベントを通知するというものなのですが、他によい案はありますでしょうか。
    2009年7月17日 9:26

回答

  • 適当に書いてみた。

        public partial class Form1 : Form, IMessageFilter
        {
            public Form1()
            {
                InitializeComponent();
    
                AddMessage();
              }
    
            private void AddMessage()
            {
                Application.AddMessageFilter(this);
            }
            private void RemoveMessage()
            {
                Application.RemoveMessageFilter(this);
            }
    
            #region IMessageFilter メンバ
    
            [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
            public static extern IntPtr GetParent(IntPtr hWnd);
    
            public bool PreFilterMessage(ref Message m)
            {
                const int WM_MOUSEMOVE = 0x200;
                const int WM_LBUTTONDOWN = 0x201;
                const int WM_LBUTTONUP = 0x202;
                const int WM_LBUTTONDBLCLK = 0x203;
                const int WM_RBUTTONDOWN = 0x204;
                const int WM_RBUTTONUP = 0x205;
                const int WM_RBUTTONDBLCLK = 0x206;
                const int WM_MBUTTONDOWN = 0x207;
                const int WM_MBUTTONUP = 0x208;
                const int WM_MBUTTONDBLCLK = 0x209;
                const int WM_MOUSEWHEEL = 0x20A;
                const int WM_MOUSEHWHEEL = 0x20E;
    
                if (!this.IsDisposed)
                {
                    if (m.HWnd != this.Handle)
                    {
                        switch (m.Msg)
                        {
                        case WM_MOUSEMOVE:
                        case WM_LBUTTONDOWN:
                        case WM_LBUTTONUP:
                        case WM_LBUTTONDBLCLK:
                        case WM_RBUTTONDOWN:
                        case WM_RBUTTONUP:
                        case WM_RBUTTONDBLCLK:
                        case WM_MBUTTONDOWN:
                        case WM_MBUTTONUP:
                        case WM_MBUTTONDBLCLK:
                        case WM_MOUSEWHEEL:
                        case WM_MOUSEHWHEEL:
    
                            IntPtr parent;
                            parent = m.HWnd;
                            do
                            {
                                parent = GetParent(parent);
                                if (parent == this.Handle)
                                {
                                    this.WndProc(ref m); //本当はきちんと振り分けたほうがいい
                                    break;
                                }
                            } while (parent != IntPtr.Zero);
    
                            break;
                        }
                    }
                }
    
                return false;
            }
    
    
            #endregion
    
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    RemoveMessage();
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
        }
    
    
    • 回答としてマーク Tank2005 2009年7月21日 13:09
    2009年7月17日 11:10