125

境界線がない(FormBorderStyleが「none」に設定されている)フォームを、境界線があるかのようにマウスがフォーム上でクリックされたときに移動可能にする方法はありますか?

4

20 に答える 20

280

CodeProjectに関するこの記事では、テクニックについて詳しく説明します。基本的には次のようになります。

public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;

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

private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{     
    if (e.Button == MouseButtons.Left)
    {
        ReleaseCapture();
        SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
    }
}

これは基本的に、ウィンドウマネージャーの観点から、ウィンドウのタイトルバーを取得するのとまったく同じです。

于 2009-10-20T06:58:52.347 に答える
66

物事を必要以上に難しくしないようにしましょう。フォーム(または別のコントロール)をドラッグできるコードのスニペットをたくさん見つけました。そしてそれらの多くには独自の欠点/副作用があります。特に、フォーム上のコントロールが実際のフォームであるとWindowsをだまして考えさせるもの。

そうは言っても、これが私のスニペットです。いつも使っています。また、this.Invalidate();を使用しないでください。場合によってはフォームがちらつくため、他の人が好むように。場合によっては、これも同様です。更新します。this.Updateを使用すると、ちらつきの問題は発生していません。

private bool mouseDown;
private Point lastLocation;

    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
        mouseDown = true;
        lastLocation = e.Location;
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if(mouseDown)
        {
            this.Location = new Point(
                (this.Location.X - lastLocation.X) + e.X, (this.Location.Y - lastLocation.Y) + e.Y);

            this.Update();
        }
    }

    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
        mouseDown = false;
    }
于 2014-07-03T19:32:24.167 に答える
41

同じことをするもう一つの簡単な方法。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        // set this.FormBorderStyle to None here if needed
        // if set to none, make sure you have a way to close the form!
    }
    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        if (m.Msg == WM_NCHITTEST)
            m.Result = (IntPtr)(HT_CAPTION);
    }

    private const int WM_NCHITTEST = 0x84;
    private const int HT_CLIENT = 0x1;
    private const int HT_CAPTION = 0x2;
}
于 2014-07-11T06:10:15.870 に答える
19

MouseDown、MouseMove、MouseUpを使用します。そのための変数フラグを設定できます。サンプルはありますが、修正が必要だと思います。

マウスアクションをパネルにコーディングしています。パネルをクリックすると、フォームも一緒に移動します。

//Global variables;
private bool _dragging = false;
private Point _offset;
private Point _start_point=new Point(0,0);


private void panel1_MouseDown(object sender, MouseEventArgs e)
{
   _dragging = true;  // _dragging is your variable flag
   _start_point = new Point(e.X, e.Y);
}

private void panel1_MouseUp(object sender, MouseEventArgs e)
{
   _dragging = false; 
}

private void panel1_MouseMove(object sender, MouseEventArgs e)
{
  if(_dragging)
  {
     Point p = PointToScreen(e.Location);
     Location = new Point(p.X - this._start_point.X,p.Y - this._start_point.Y);     
  }
}
于 2009-10-20T07:30:46.990 に答える
13

WPFのみ


渡す正確なコードはありませんが、最近のプロジェクトでは、MouseDownイベントを使用して、これを単純に記述したと思います。

frmBorderless.DragMove();

Window.DragMoveメソッド(MSDN)

于 2009-10-20T07:05:16.780 に答える
9

参照。ビデオリンク

これはテスト済みで理解しやすいです。

protected override void WndProc(ref Message m)
{
    switch (m.Msg)
    {
        case 0x84:
            base.WndProc(ref m);
            if((int)m.Result == 0x1)
                m.Result = (IntPtr)0x2;
            return;
    }

    base.WndProc(ref m);
}
于 2015-02-10T17:19:56.140 に答える
9

それは私のために働いた。

    private Point _mouseLoc;

    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
        _mouseLoc = e.Location;
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            int dx = e.Location.X - _mouseLoc.X;
            int dy = e.Location.Y - _mouseLoc.Y;
            this.Location = new Point(this.Location.X + dx, this.Location.Y + dy);
        }
    }
于 2019-08-11T17:05:57.057 に答える
4

これを魔法のように実現するためにフリップできるプロパティはありません。this.Topフォームのイベントを見ると、とを設定してこれを実装するのはかなり簡単になりますthis.Left。具体的には、、、を確認する必要がMouseDownありMouseUpますMouseMove

于 2009-10-20T06:56:56.293 に答える
4
public Point mouseLocation;
private void frmInstallDevice_MouseDown(object sender, MouseEventArgs e)
{
  mouseLocation = new Point(-e.X, -e.Y);
}

private void frmInstallDevice_MouseMove(object sender, MouseEventArgs e)
{
  if (e.Button == MouseButtons.Left)
  {
    Point mousePos = Control.MousePosition;
    mousePos.Offset(mouseLocation.X, mouseLocation.Y);
    Location = mousePos;
  }
}

これはあなたの問題を解決することができます...

于 2013-02-21T07:41:55.633 に答える
4

https://social.msdn.microsoft.com/Forums/vstudio/en-US/d803d869-68e6-46ff-9ff1-fabf78d6393c/how-to-make-a-borderless-form-in-c?forum=csharpgeneral

上記のリンクからのこのビットのコードは、私の場合はトリックを行いました:)

protected override void OnMouseDown(MouseEventArgs e)  

{
      base.OnMouseDown(e);
      if (e.Button == MouseButtons.Left)
      {
        this.Capture = false;
        Message msg = Message.Create(this.Handle, 0XA1, new IntPtr(2), IntPtr.Zero);
        this.WndProc(ref msg);
      }
}
于 2016-09-26T06:44:49.647 に答える
4

一部の回答では子コントロールをドラッグできないため、小さなヘルパークラスを作成しました。トップレベルのフォームを渡す必要があります。必要に応じて、より一般的にすることができます。

class MouseDragger
{
    private readonly Form _form;
    private Point _mouseDown;

    protected void OnMouseDown(object sender, MouseEventArgs e)
    {
        _mouseDown = e.Location;
    }

    protected void OnMouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            int dx = e.Location.X - _mouseDown.X;
            int dy = e.Location.Y - _mouseDown.Y;
            _form.Location = new Point(_form.Location.X + dx, _form.Location.Y + dy);
        }
    }
    public MouseDragger(Form form)
    {
        _form = form;

        MakeDraggable(_form);            
    }

    private void MakeDraggable(Control control)
    {
        var type = control.GetType();
        if (typeof(Button).IsAssignableFrom(type))
        {
            return;
        }

        control.MouseDown += OnMouseDown;
        control.MouseMove += OnMouseMove;

        foreach (Control child in control.Controls)
        {
            MakeDraggable(child);
        }
    }
}
于 2018-06-20T09:54:21.340 に答える
3

私が見つけた最良の方法(もちろん変更されました)

// This adds the event handler for the control
private void AddDrag(Control Control) { Control.MouseDown += new System.Windows.Forms.MouseEventHandler(this.DragForm_MouseDown); }
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
[System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();

private void DragForm_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        ReleaseCapture();
        SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
        // Checks if Y = 0, if so maximize the form
        if (this.Location.Y == 0) { this.WindowState = FormWindowState.Maximized; }
    }
}

コントロールにドラッグを適用するには、InitializeComponent()の後にこれを挿入するだけです。

AddDrag(NameOfControl);
于 2017-07-20T14:15:16.137 に答える
2

.NETFramework4の場合

ドラッグに使用しているコンポーネント(この例ではmainLayout)this.DragMove()のイベントに使用できます。MouseDown

private void mainLayout_MouseDown(object sender, MouseButtonEventArgs e)
{
    this.DragMove();
}
于 2016-04-23T13:57:09.633 に答える
2

WPF要素ホストコントロールとWPFユーザーコントロールを含むフチなしウィンドウフォームを移動可能にしようとしていました。

WPFユーザーコントロールにStackPanelというスタックパネルが表示されました。これは、クリックして移動するのが理にかなっているようです。junmatsのコードを試すと、マウスをゆっくり動かしたときに機能しましたが、マウスを速く動かした場合、マウスがフォームから移動し、フォームが移動の途中で動かなくなってしまいます。

これにより、CaptureMouseとReleaseCaptureMouseを使用した私の状況に対する彼の回答が改善され、マウスをすばやく動かしても、マウスを動かしながらフォームから移動しなくなりました。

private void StackPanel_MouseDown(object sender, MouseButtonEventArgs e)
{
    _start_point = e.GetPosition(this);
    StackPanel.CaptureMouse();
}

private void StackPanel_MouseUp(object sender, MouseButtonEventArgs e)
{
    StackPanel.ReleaseMouseCapture();
}

private void StackPanel_MouseMove(object sender, MouseEventArgs e)
{
    if (StackPanel.IsMouseCaptured)
    {
        var p = _form.GetMousePositionWindowsForms();
        _form.Location = new System.Drawing.Point((int)(p.X - this._start_point.X), (int)(p.Y - this._start_point.Y));
    }
}

    //Global variables;
    private Point _start_point = new Point(0, 0);
于 2016-08-09T21:22:32.537 に答える
2

最も簡単な方法は次のとおりです。

まず、label1という名前のラベルを作成します。label1のイベント>マウスイベント>Label1_Mouseに移動し、次のように記述します。

if (e.Button == MouseButtons.Left){
    Left += e.X;
    Top += e.Y;`
}
于 2017-02-01T13:00:31.500 に答える
2

jay_t55のソリューションを拡張してToolStrip1_MouseLeave、マウスがすばやく移動して領域を離れるイベントを処理するもう1つのメソッドを使用します。

private bool mouseDown;
private Point lastLocation;

private void ToolStrip1_MouseDown(object sender, MouseEventArgs e) {
    mouseDown = true;
    lastLocation = e.Location;
}

private void ToolStrip1_MouseMove(object sender, MouseEventArgs e) {
    if (mouseDown) {
        this.Location = new Point(
            (this.Location.X - lastLocation.X) + e.X, (this.Location.Y - lastLocation.Y) + e.Y);

        this.Update();
    }
}

private void ToolStrip1_MouseUp(object sender, MouseEventArgs e) {
    mouseDown = false;
}

private void ToolStrip1_MouseLeave(object sender, EventArgs e) {
    mouseDown = false;
}
于 2019-06-04T07:50:25.380 に答える
1

また、DoubleClickでフォームを大きく/小さくする必要がある場合は、First Answerを使用して、グローバルint変数を作成し、ドラッグに使用するコンポーネントをクリックするたびに1を追加できます。その後、variable == 2フォームを大きく/小さくします。また、0.5秒または1秒ごとにタイマーを使用してvariable = 0;を作成します。

于 2016-11-16T20:10:03.647 に答える
1

MainWindowにMouseLeftButtonDownイベントハンドラーを追加するとうまくいきました。

自動的に生成されるイベント関数に、以下のコードを追加します。

base.OnMouseLeftButtonDown(e);
this.DragMove();
于 2018-06-19T07:45:05.847 に答える
0

Form1():new Moveable(control1, control2, control3);

クラス:

using System;
using System.Windows.Forms;

class Moveable
{
    public const int WM_NCLBUTTONDOWN = 0xA1;
    public const int HT_CAPTION = 0x2;
    [System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
    [System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
    public static extern bool ReleaseCapture();
    public Moveable(params Control[] controls)
    {
        foreach (var ctrl in controls)
        {
            ctrl.MouseDown += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    ReleaseCapture();
                    SendMessage(ctrl.FindForm().Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
                    // Checks if Y = 0, if so maximize the form
                    if (ctrl.FindForm().Location.Y == 0) { ctrl.FindForm().WindowState = FormWindowState.Maximized; }
                }
            };
        }
    }
}
于 2020-04-11T14:11:03.683 に答える
-2

次のことを試してみましたが、透明な窓が固定されていませんでしたが、移動することができました。(上記の他のすべての複雑なソリューションを破棄します...)

   private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        base.OnMouseLeftButtonDown(e);
        // Begin dragging the window
        this.DragMove();
    }
于 2018-07-20T16:04:00.087 に答える