60484
お世話になります。

<https://dobon.net/vb/dotnet/form/moveform.html>

こちらのサイト様にあるような、フォーム上でドラッグしてフォームの移動をさせるコードを  
書いています。

このフォーム上にコントロールを追加すると、そのコントロール上ではマウスイベントは発生しません。移動させるには、追加したコントロールにそれぞれMouseDownとMouseMoveを実装し、その中でOnMouseDownやOnMouseMoveをしないといけません。

これはわかっているのですが、いざフォームにコントロールを五つ六つ…と追加していくと、それぞれに上記の処理を追加しなければならず、手間です。コードでコントロールを追加するなら、コードで何とかできますが、VisualStudioのエディタ上で追加していくと、そうもいきません。

作る側として、その程度の手間は当然といえば当然といわれるかもしれませんが、もしできるなら  
もっと楽な方法はありませんでしょうか。たとえて言うなら、キーボードの受付を親が管理する  
『KeyPreview』のようなものがあるといいなと思うのですが。

よい実装方法などありましたら、ご助力いただければ幸いです。

よろしくお願いいたします。
CC BY-SA 4.0
2019-11-13T01:22:37.803
60459
2019-11-13T11:42:22.007
9374
question
c# form
C# フォームの上に乗せたコントロールにもフォームのマウスイベントが走る簡単な方法
<https://stackoverflow.com/questions/4991044/winforms-intercepting-mouse-
event-on-main-form-first-not-on-controls>

に書いている事を流用して機能拡張してみます。

まずは マウスをクリックするとフォームが移動できるように  
マウスイベントの処理を書きます。  
この状態では ボタン上で マウスクリックするとフォームの移動はできません。

```

    this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseDown);
    this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove);
    this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove);
    
```

```

            bool mousePressed;
            private Point diff;
    
            private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Left)
                {
                    mousePressed = true;
    
                    Point p = new Point(e.X, e.Y);
                    p = PointToScreen(p);
                    diff.X = p.X - DesktopLocation.X;
                    diff.Y = p.Y - DesktopLocation.Y;
                }
            }
    
            private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
            {
                if (mousePressed && (e.Button & MouseButtons.Left) != 0)
                {
                    Point p = new Point(e.X, e.Y);
                    p = PointToScreen(p);
                    p.X -= diff.X;
                    p.Y -= diff.Y;
                    DesktopLocation = p;
                }
            }
    
            private void Form1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
            {
                mousePressed = false;
            }
    
    
```

次に 上記リンク先の記事を参考に  
フォーム上のコントロールのイベントを 転送する設定をします。

```

    foreach (Control control in Controls)
    {
       control.MouseMove += RedirectMouseMove;
       control.MouseDown += RedirectMouseDown;
    }
    
```

```

            private void RedirectMouseDown(object sender, MouseEventArgs e)
            {
                Control control = (Control)sender;
                Point screenPoint = control.PointToScreen(new Point(e.X, e.Y));
                Point formPoint = PointToClient(screenPoint);
                MouseEventArgs args = new MouseEventArgs(e.Button, e.Clicks,
                    formPoint.X, formPoint.Y, e.Delta);
    
                OnMouseDown(args);
            }
    
            private void RedirectMouseMove(object sender, MouseEventArgs e)
            {
                Control control = (Control)sender;
                Point screenPoint = control.PointToScreen(new Point(e.X, e.Y));
                Point formPoint = PointToClient(screenPoint);
                MouseEventArgs args = new MouseEventArgs(e.Button, e.Clicks,
                    formPoint.X, formPoint.Y, e.Delta);
                OnMouseMove(args);
            }
    
```

ちょっと、ボタンの色が変わるのが気になりますけど、ボタンの上でマウスクリックしても  
ちゃんとフォームが移動できるようになります。
CC BY-SA 4.0
2019-11-13T11:42:22.007
60484
2019-11-13T11:42:22.007
18851
60459
answer