Pregunta

¿Cómo puedo mover una ventana que no tiene una frontera. No hay espacio vacío en la aplicación, todo lo que está disponible es un navegador web y una menustrip. Me gustaría que los usuarios sean capaces de mover la ventana arrastrando la banda de menú. ¿Cómo puedo codificar esta? He probado unos cuantos bloques de código que he encontrado en línea, pero ninguno de ellos funcionó.

¿Fue útil?

Solución

This Code Project article should help you accomplish this. I've used this myself with no problems. This is the jist of it:

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();

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

This will basically "trick" the window manager into thinking that it is grabbing the title bar of the winform.

To apply it to your project, just use the MouseDown event from the MenuStrip.

Otros consejos

Here is the .Net Way

    private bool dragging = false;
    private Point dragCursorPoint;
    private Point dragFormPoint;

    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
        dragging = true;
        dragCursorPoint = Cursor.Position;
        dragFormPoint = this.Location;
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if (dragging)
        {
            Point dif = Point.Subtract(Cursor.Position, new Size(dragCursorPoint));
            this.Location = Point.Add(dragFormPoint, new Size(dif));
        }
    }

    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
        dragging = false;
    }

that's it.

You can fake your menustrip, for example using a panel with a label instead. And then you can handle this manually: when the user clicks the label, a popup menu will open, and when the user drags the label, the window will move. But I would advise against such workarounds, because it's not a standard GUI behavior, and you might get your users confused.

I haven't tried it, but if you can handle the "OnMouseDown" and "onMouseUp" events on the menu bar:

  • On mouse down - Move the window according to the mouse movement
  • Stop tracking the mouse movement on mouse up, or mouse out

If you are using a Panel you have to add this in the

YourForm.Designer.cs

this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseDown);

and this in the

YourForm.cs

 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();

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

Mbithi Kioko is on the right track but i would do it this way.

    bool dragging = false;
    int xOffset = 0;
    int yOffset = 0;

    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
        dragging = true;

        xOffset = Cursor.Position.X - this.Location.X;
        yOffset = Cursor.Position.Y - this.Location.Y;
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if (dragging)
        {
            this.Location = new Point(Cursor.Position.X - xOffset, Cursor.Position.Y - yOffset);
            this.Update();
        }
    }

    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
        dragging = false;
    }

I had to use System.Runtime.InteropServices.DllImportAttribute - just thought I would comment and let you all know.

Just put the start point into an 2D Array like this:

public partial class mainForm : Form
{
    //Global variables for Moving a Borderless Form
    private bool dragging = false;
    private Point startPoint = new Point(0, 0); 


    public mainForm()
    {
        InitializeComponent();
    }

    private void mainForm_MouseDown(object sender, MouseEventArgs e)
    {
        dragging = true;
        startPoint = new Point(e.X, e.Y);

    }

    private void mainForm_MouseUp(object sender, MouseEventArgs e)
    {
        dragging = false;
    }

    private void mainForm_MouseMove(object sender, MouseEventArgs e)
    {
        if (dragging)
        {
            Point p = PointToScreen(e.Location);
            Location = new Point(p.X - this.startPoint.X, p.Y - this.startPoint.Y);

        }

    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top