2011-01-02 14 views
9

Come si sposta una finestra che non ha un bordo. Non c'è spazio vuoto sull'applicazione, tutto ciò che è disponibile è un browser e un menustrip. Vorrei che gli utenti fossero in grado di spostare la finestra trascinando la barra dei menu. Come posso codificare questo? Ho provato alcuni blocchi di codice che ho trovato online, ma nessuno di loro ha funzionato.Sposta finestra senza bordo

+5

Probabilmente perché è impossibile per l'applicazione (o l'utente) di distinguere se un clic sul 'MenuStrip' ha lo scopo di spostare l'applicazione o apri un menu. C'è un motivo per cui le finestre hanno dei bordi - ripensa il tuo design. –

risposta

14

This Codice Articolo di progetto dovrebbe aiutarti a realizzare questo. L'ho usato io stesso 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 homepage.

Per applicarlo al progetto, è sufficiente utilizzare l'evento MouseDown dal MenuStrip.

+1

Funziona davvero alla grande. È possibile aggiungere il contenuto del metodo in qualsiasi evento MouseDown, ad esempio un'immagine ... – Otiel

+0

Era quasi troppo facile :) Grazie! –

0

È possibile falsificare il tuo menustrip, ad esempio utilizzando un pannello con un'etichetta. E poi puoi gestirlo manualmente: quando l'utente fa clic sull'etichetta, si aprirà un menu a comparsa e, quando l'utente trascina l'etichetta, la finestra si sposterà. Ma vorrei sconsigliare simili soluzioni, perché non è un comportamento GUI standard e potresti confondere gli utenti.

+1

* Per favore * non farlo. Non solo è un'interfaccia utente completamente non standard, ma non risolve il problema dell'interpretazione di un clic. Ricorda che un "trascinamento" avviene * dopo * si verifica un clic.Dovrebbe un clic aprire il menu, o dovrebbe essere interpretato come iniziare un trascinamento? Le macchine del tempo non sono ancora state perfezionate. –

+0

@Cody Un clic si verifica quando si rilascia il pulsante del mouse. Guarda come funziona nel pannello delle cartelle di Windows Explorer: se fai clic su una cartella, questa si apre nel riquadro destro, ma se trascini una cartella, non si apre, ma viene semplicemente trascinata. –

+2

Capito. Ma comprendi che stai definendo un evento "Click" in modo diverso da come un controllo del menu lo interpreta in Windows. Non appena premo il pulsante del mouse su un menu qualsiasi in qualsiasi applicazione di Windows, il menu si interrompe. Non si verifica quando il pulsante del mouse viene rilasciato. Penso che sia importante sottolineare che le decisioni di progettazione che modificano drasticamente il comportamento previsto devono essere considerate con particolare attenzione. –

0

non l'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
  • Interrompi il rilevamento del movimento del mouse sul mouse o del mouse all'esterno
0

Se si utilizza un pannello si deve aggiungere questo nei

YourForm.Designer.cs

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

e questo nei

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

Qui è il modo .Net

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

il gioco è fatto.

+3

+1 per una soluzione puramente C#. –

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

Ho dovuto usare System.Runtime.InteropServices.DllImportAttribute - solo pensato vorrei commentare e farvi sapere.

0

appena messo il punto di partenza in una matrice 2D come questo:

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

     } 

    } 
} 
Problemi correlati