it-swarm.com.de

Machen Sie eine randlose Form beweglich?

Gibt es eine Möglichkeit, ein Formular ohne Rand (FormBorderStyle ist auf "none" gesetzt) ​​beweglich zu machen, wenn mit der Maus im Formular geklickt wird, als ob ein Rand vorhanden wäre?

92
user

Dieser / Artikel über CodeProject beschreibt eine Technik. Läuft im Grunde auf:

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 Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{     
    if (e.Button == MouseButtons.Left)
    {
        ReleaseCapture();
        SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
    }
}

Dies entspricht im Wesentlichen genau dem Aufnehmen der Titelleiste eines Fensters aus Sicht des Fenstermanagers.

205
Joey

Machen wir es nicht schwieriger, als es sein muss. Ich bin auf so viele Codefragmente gestoßen, mit denen Sie ein Formular (oder ein anderes Steuerelement) ziehen können. Und viele von ihnen haben ihre eigenen Nachteile/Nebenwirkungen. Vor allem diejenigen, bei denen Windows dazu verleitet wird, zu glauben, dass ein Steuerelement in einer Form die tatsächliche Form ist.

Davon abgesehen, hier ist mein Ausschnitt. Ich benutze es die ganze Zeit. Ich möchte auch anmerken, dass Sie this.Invalidate () nicht verwenden sollten. wie es andere gerne tun, weil in manchen Fällen das Formular flackert. Und in einigen Fällen ist dies auch der Fall. Mit diesem.Update hatte ich keine flackernden Probleme:

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;
    }
37
jay_t55

Eine andere einfachere Möglichkeit, das Gleiche zu tun.

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;
}
28
elimad

verwenden Sie MouseDown, MouseMove und MouseUp. Sie können dafür ein variables Flag setzen. Ich habe eine Probe, aber ich denke, Sie müssen überarbeiten.

Ich codiere die Mausaktion in ein Panel. Sobald Sie auf das Panel klicken, wird Ihr Formular mit verschoben.

//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);     
  }
}
18
junmats

Nur WPF


ich habe nicht den genauen Code zur Hand, aber ich glaube, in einem aktuellen Projekt habe ich das MouseDown-Ereignis verwendet und einfach folgendes gesetzt:

frmBorderless.DragMove();

Window.DragMove-Methode (MSDN)

11
Chris

Ref. Video-Link

Dies ist getestet und leicht verständlich.

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);
}
8
Gnana Akilan

Es gibt keine Eigenschaft, die Sie umdrehen können, damit dies magisch geschieht. Schauen Sie sich die Ereignisse für das Formular an und es wird ziemlich einfach, dies durch die Einstellung von this.Top und this.Left zu implementieren. Insbesondere sollten Sie sich MouseDown, MouseUp und MouseMove anschauen.

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;
  }
}

das kann dein Problem lösen ....

4
Syed Ali

Bester Weg, den ich gefunden habe (natürlich geändert)

// 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; }
    }
}

Um ein Steuerelement auf ein Steuerelement anzuwenden, fügen Sie es nach InitializeComponent ()

AddDrag(NameOfControl);
3

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

Dieses bisschen Code aus dem obigen Link hat den Trick in meinem Fall gemacht :)

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);
      }
}
2

Der einfachste Weg ist:

Erstellen Sie zuerst ein Label mit dem Namen label1 . Gehen Sie zu Ereignisse von label1> Mausereignisse> Label1_Mouse Move und schreiben Sie diese:

if (e.Button == MouseButtons.Left){
    Left += e.X;
    Top += e.Y;`
}
1
user7500524

Da einige Antworten nicht zulassen, dass untergeordnete Steuerelemente gezogen werden können, habe ich eine kleine Hilfsklasse erstellt. Kann auf Wunsch generischer gemacht werden.

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);
        }
    }
}
1
Sebastian

Wenn Sie DoubleClick verwenden und Ihr Formular vergrößern/verkleinern müssen, können Sie die Antwort First verwenden, eine globale int-Variable erstellen und jedes Mal 1 hinzufügen, wenn der Benutzer auf die Komponente klickt, die Sie zum Ziehen verwenden. Wenn variable == 2, dann machen Sie Ihr Formular größer/kleiner. Verwenden Sie auch einen Timer für jede halbe Sekunde oder Sekunde, um Ihren variable = 0 zu erstellen.

1
Billy Xd

Ich habe versucht, eine randlose Fensterform beweglich zu machen, die ein WPF Element Host-Steuerelement und ein WPF User-Steuerelement enthielt. 

Am Ende bekam ich ein Stack-Panel namens StackPanel in meinem WPF-Benutzersteuerelement, das logisch zu sein schien. Das Ausprobieren von Junmats-Code funktionierte, wenn ich die Maus langsam bewegte, aber wenn ich die Maus schneller bewegte, würde sich die Maus vom Formular entfernen und das Formular steckte irgendwo in der Mitte. 

Dies verbesserte seine Antwort auf meine Situation mit CaptureMouse und ReleaseCaptureMouse. Jetzt bewegt sich die Maus nicht aus dem Formular, auch wenn ich sie schnell bewege.

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);
1
Mike Sage

Für .NET Framework 4 

Sie können this.DragMove() für das MouseDown-Ereignis der Komponente (in diesem Beispiel mainLayout) verwenden, die Sie zum Ziehen verwenden.

private void mainLayout_MouseDown(object sender, MouseButtonEventArgs e)
{
    this.DragMove();
}
1

Das Hinzufügen eines MouseLeftButtonDown-Ereignishandlers zum MainWindow hat für mich funktioniert.

Fügen Sie in der Ereignisfunktion, die automatisch generiert wird, den folgenden Code hinzu:

base.OnMouseLeftButtonDown(e);
this.DragMove();
0
Aparna Ratheesh

Ich habe folgendes ausprobiert und presto changeo, mein durchsichtiges Fenster war nicht mehr fixiert, konnte aber verschoben werden !! (alle anderen komplexen Lösungen oben wegwerfen ...)

   private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        base.OnMouseLeftButtonDown(e);
        // Begin dragging the window
        this.DragMove();
    }
0
RoySeberg

Es hat bei mir funktioniert.

    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);
        }
    }
0

Ich erweitere die Lösung von jay_t55 um eine weitere Methode ToolStrip1_MouseLeave, die das Ereignis behandelt, dass sich die Maus schnell bewegt und die Region verlässt.

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;
}
0
Michael