2011-01-02 2 views
9

Как переместить окно, которое не имеет границы. В приложении нет свободного места, все, что доступно, - это webbrowser и menustrip. Я бы хотел, чтобы пользователи могли перемещать окно, перетаскивая полосу меню. Как это сделать? Я пробовал несколько кодовых блоков, которые я нашел в Интернете, но никто из них не работал.Перемещение окна без границы

+5

Наверное, потому, что это невозможно для приложения (или пользователя), чтобы отличить щелчок на 'MenuStrip' предназначен ли переместить приложение или открыть меню. Есть причина, что окна имеют границы - переосмыслите свой дизайн. –

ответ

14

This Код Проект статьи должен помочь вам выполнить это. Я сам использовал это без проблем. Это тэки его:

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

Это будет в основном «трюк» менеджер окон, думая, что он захватывая строку заголовка WinForm.

Чтобы применить его к вашему проекту, просто используйте событие MouseDown из MenuStrip.

+1

Это работает отлично. Вы можете добавить содержимое метода в любое событие MouseDown, например изображение ... – Otiel

+0

Это было почти слишком просто :) Спасибо! –

0

Вы можете подделать свой menustrip, например, используя панель с меткой. И тогда вы можете справиться с этим вручную: когда пользователь нажмет на ярлык, откроется всплывающее меню, и когда пользователь перетащит ярлык, окно переместится. Но я бы посоветовал отказаться от таких обходных решений, потому что это не стандартное поведение графического интерфейса, и вы можете смутить своих пользователей.

+1

* Пожалуйста, не делайте этого. Это не совсем нестандартный пользовательский интерфейс, но он все еще не решает проблему интерпретации щелчка. Помните, что «перетаскивание» происходит * после * щелчка.Должен ли щелчок открыть меню или его следует интерпретировать как начало перетаскивания? Машины времени еще не усовершенствованы. –

+0

@Cody Щелчок происходит, когда вы отпускаете кнопку мыши. Посмотрите, как он работает на панели «Папки» проводника Windows: если вы щелкнете папку, она откроется в правой панели, но если вы перетащите папку, она не откроется, ее просто перетащит. –

+2

Понял. Но поймите, что вы определяете событие «Click» иначе, чем его интерпретирует в Windows. Как только я нажимаю кнопку мыши в любом меню в любом приложении в Windows, меню падает. Это не происходит, когда кнопка мыши отпущена. Я думаю, что важно отметить, что конструктивные решения, которые резко изменяют ожидаемое поведение, должны быть рассмотрены особенно тщательно. –

0

Я не пробовал, но если вы можете справиться с «OnMouseDown» и «OnMouseUp» события в строке меню:

  • На мыши вниз - Переместить окно в соответствии с движением мыши
  • Остановить отслеживание движения мыши по мыши, или мышь
0

Если вы используете панель, вы должны добавить это в

YourForm.Designer.cs

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

и это в

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

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

все.

+3

+1 для чисто C# решения. –

0

Mbithi Kioko на правильном пути, но я сделал бы это так.

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

Я должен был использовать System.Runtime.InteropServices.DllImportAttribute - просто думал, что комментарии, и пусть вы все знаете.

0

Просто поместите начальную точку в 2D массив как это:

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

     } 

    } 
} 
Смежные вопросы