Spostare la finestra senza bordo
-
14-10-2019 - |
Domanda
Come faccio a spostare una finestra che non ha un bordo. Non c'è spazio vuoto sull'applicazione, tutto ciò che è disponibile è un browser web e un MenuStrip. Vorrei gli utenti siano in grado di spostare la finestra trascinando la barra di menu. Come faccio a Questo codice? Ho provato un paio di blocchi di codice che ho trovato on-line, ma nessuno di loro ha lavorato.
Soluzione
Questo articolo Codice progetto dovrebbe aiutare a realizzare questo. Ho usato questo io senza problemi. Questo è il jist di esso:
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);
}
}
Questo sarà essenzialmente "ingannare" il window manager a pensare che è afferrare la barra del titolo della WinForm.
Per applicare al vostro progetto, basta usare l'evento MouseDown dal MenuStrip.
Altri suggerimenti
Ecco il .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;
}
questo è tutto.
È possibile falsificare la tua MenuStrip, ad esempio utilizzando un pannello con un'etichetta, invece. E poi è possibile gestire manualmente: quando l'utente fa clic l'etichetta, un menu a comparsa si aprirà, e quando l'utente trascina l'etichetta, la finestra si muoverà. Ma vorrei consigliare contro tali soluzioni alternative, perché non è un comportamento GUI standard e si potrebbe ottenere gli utenti confuso.
Non ho provato, ma se è possibile gestire il "OnMouseDown" e gli eventi "onMouseUp" sulla barra dei menu:
- Al passaggio del mouse verso il basso - Spostare la finestra in base al movimento del mouse
- interrompere il tracciamento del movimento del mouse sul mouse in alto, o il mouse fuori
Se si utilizza un pannello si deve aggiungere questo nel
YourForm.Designer.cs
this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseDown);
e questo nel
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 è sulla strada giusta, ma vorrei farlo in questo modo.
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;
}
Ho dovuto usare System.Runtime.InteropServices.DllImportAttribute
- solo pensato vorrei commentare e lasciare che tutti conosciamo.
Basta mettere il punto di partenza in un array 2D in questo modo:
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);
}
}
}