Переместить окно без рамки

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


person Sean    schedule 02.01.2011    source источник
comment
Вероятно, потому что приложение (или пользователь) не может различить, предназначено ли нажатие на MenuStrip для перемещения приложения или открытия меню. Есть причина, по которой у окон есть границы — переосмыслите свой дизайн.   -  person Cody Gray    schedule 02.01.2011


Ответы (8)


Эта статья Code Project должна помочь вам в этом. Я сам использовал это без проблем. Вот суть этого:

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.

person user    schedule 02.01.2011
comment
Это действительно здорово работает. Вы можете добавить содержимое метода в любое событие MouseDown, например картинку... - person Otiel; 09.08.2011
comment
Это было почти слишком просто :) Спасибо! - person David Thielen; 14.05.2012

Вот путь .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;
    }

Это оно.

person Ciel Phantomhive    schedule 14.10.2013

Просто поместите начальную точку в 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);

        }

    }
}
person Ricardo Fercher    schedule 22.02.2017

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

person Ilya Kogan    schedule 02.01.2011
comment
Пожалуйста не делайте этого. Мало того, что это совершенно нестандартный пользовательский интерфейс, так еще и не решает проблему интерпретации щелчка. Помните, что перетаскивание происходит после щелчка. Должен ли щелчок открывать меню или его следует интерпретировать как начало перетаскивания? Машины времени еще не совершенны. - person Cody Gray; 02.01.2011
comment
@Cody Щелчок происходит, когда вы отпускаете кнопку мыши. Посмотрите, как это работает на панели «Папки» проводника Windows: если щелкнуть папку, она откроется в правой панели, но если перетащить папку, она не откроется, ее просто перетащите. - person Ilya Kogan; 02.01.2011
comment
Понял. Но поймите, что вы определяете событие Click не так, как его интерпретирует элемент управления меню в Windows. Как только я нажимаю кнопку мыши в любом меню в любом приложении Windows, меню выпадает. Это не происходит, когда кнопка мыши отпущена. Я думаю, важно отметить, что проектные решения, которые резко изменяют ожидаемое поведение, требуют особенно тщательного рассмотрения. - person Cody Gray; 02.01.2011

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

  • По нажатию мыши - перемещать окно в соответствии с движением мыши.
  • Прекратить отслеживание движения мыши при поднятии или отведении мыши
person Doobi    schedule 02.01.2011

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

ВашаФорма.Designer.cs

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

и это в

ВашаФорма.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);
            }
        }
person h3nk    schedule 26.07.2013

Мбити Киоко на правильном пути, но я бы поступил так.

    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;
    }
person Dudeman    schedule 11.12.2013

Мне пришлось использовать System.Runtime.InteropServices.DllImportAttribute - просто подумал, что прокомментирую и дам вам всем знать.

person Rekless    schedule 07.01.2017