Как вы предотвращаете перемещение Windows?

#c# #winforms

#c# #.net #winforms #пользовательский интерфейс

Вопрос:

Как бы я мог остановить перемещение формы. У меня установлен стиль границы формы как FixedSingle, и я хотел бы сохранить его таким образом, потому что он хорошо смотрится в Vista 🙂

Комментарии:

1. Что вы подразумеваете под перемещением? Вы имеете в виду невозможность перетащить ее в другое место на рабочем столе?

2. Что, если у пользователя есть какой-то другой виджет в правом нижнем углу, например, боковая панель Vista? Вы действительно хотите указывать, где должно оставаться ваше окно? Это ни в коем случае не удобно для пользователя, и я лично не принял бы такое ограничение.

3. разве невозможно переместить форму на ее исходное место, если она перемещена?

Ответ №1:

Взгляните на эту ссылку. Возможно, вас заинтересует вариант № 3. Это потребует от вас обернуть некоторый машинный код, но должно сработать. Внизу ссылки также есть комментарий, который показывает более простой способ сделать это. Взято из комментария (не могу приписать это себе, но я избавлю вас от необходимости искать):

 protected override void WndProc(ref Message message)
{
    const int WM_SYSCOMMAND = 0x0112;
    const int SC_MOVE = 0xF010;

    switch(message.Msg)
    {
        case WM_SYSCOMMAND:
           int command = message.WParam.ToInt32() amp; 0xfff0;
           if (command == SC_MOVE)
              return;
           break;
    }

    base.WndProc(ref message);
}
  

Комментарии:

1. Спасибо, это сработало отлично. Также ознакомился с сайтом. Нужно подробнее изучить WinAPI.

2. Как я могу снова сделать ее подвижной?

3. У вас должен быть какой-то флаг, указывающий, следует ли вообще запускать код в инструкции switch (которая просто проверяет, было ли сообщение Windows для перемещения окна … в этом случае оно возвращается и ничего не делает).

Ответ №2:

Для FormBorderStyle свойства формы можно установить значение None

 this.FormBorderStyle=System.Windows.Forms.FormBorderStyle.None
  

Ответ №3:

Я нашел это, чтобы остановить перемещение формы (это в c #)

 protected override void WndProc(ref Message m)
        {
            const int WM_SYSCOMMAND = 0x0112;
            const int SC_MOVE = 0xF010;

            switch (m.Msg)
            {
                case WM_SYSCOMMAND:
                    int command = m.WParam.ToInt32() amp; 0xfff0;
                    if (command == SC_MOVE)
                        return;
                    break;
            }
            base.WndProc(ref m);
        }
  

Найдено здесь

Комментарии:

1. В каком случае я должен это написать?

2. Вы должны переопределить WndProc для формы, которую, по вашему желанию, не следует перемещать. Введите переопределение и пробел, вы получите список, в котором вы найдете метод, упомянутый выше

3. @V4Vendetta возможно, потому, что ваш ответ точно такой же, как принятый, который был опубликован двумя годами ранее… Я тоже этого не понимаю (не мой отрицательный отзыв)

4. @Knickedi Это может быть случай, когда аналогичный вопрос был бы объединен вместе с ответами, так что вы видите огромную разницу во временных рамках.

Ответ №4:

Попробуйте переопределить WndProc:

 protected override void WndProc(ref Message m)
{
   const int WM_NCLBUTTONDOWN = 161;
   const int WM_SYSCOMMAND = 274;
   const int HTCAPTION = 2;
   const int SC_MOVE = 61456;

   if ((m.Msg == WM_SYSCOMMAND) amp;amp; (m.WParam.ToInt32() == SC_MOVE))
   {
       return;
   }

   if ((m.Msg == WM_NCLBUTTONDOWN) amp;amp; (m.WParam.ToInt32() == HTCAPTION))
   {
       return;
   }

   base.WndProc(ref m);
}
  

Комментарии:

1. как я могу снова сделать ее подвижной?

Ответ №5:

Это не совсем красиво (при попытке переместить форму происходит некоторое мигание), но вы можете использовать свойство LocationChanged, чтобы сохранить форму там, где вы хотите:

 private Point _desiredLocation;
// assign the _desiredLocation variable with the form location at some
// point in the code where you know that the form is in the "correct" position


private void Form_LocationChanged(object sender, EventArgs e)
{
    if (this.Location != _desiredLocation)
    {
        this.Location = _desiredLocation;
    }
}
  

Из любопытства; почему вы хотите это сделать?

Комментарии:

1. Да, я понял, что это будет нелегко : (Причина, по которой я хочу этого, заключается в том, что я хочу, чтобы форма отображалась в правом нижнем углу экрана, как меню. Таким образом, вы можете выбирать файлы и т.д.

2. Как бы я это сделал — не глядя, я не думаю, что в .NET есть свойство, которое вы можете установить для этого, так что это ваш лучший выбор.

Ответ №6:

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

Однако, если вам нужно иметь заголовок и при этом достичь желаемого, тогда следующим стилем было бы захватить сообщение WM_NCHITTEST и проверить наличие HTCAPTION. Если код является HTCAPTION , верните вместо этого NTNOWHERE. Это предотвратит выполнение процедуры окна по умолчанию для перемещения окна по умолчанию.

Комментарии:

1. Спасибо за ответ. Я начал программировать на настольных компьютерах всего около месяца назад, поэтому понятия не имею, как реализовать что-либо из того, что вы сказали .. извините. Я чувствую себя невежественным : (

Ответ №7:

Не рекомендуется делать вашу форму неподвижной. На вашем месте я бы еще раз подумал об этом.
В любом случае, вы можете сделать это, переопределив WinProc, чтобы отключить [Переместить] menuitem из системного меню.

 [DllImport("user32.dll")]
private static extern Int32 EnableMenuItem ( System.IntPtr hMenu , Int32uIDEnableItem, Int32 uEnable);  
private const Int32 HTCAPTION = 0×00000002;  
private const Int32 MF_BYCOMMAND =0×00000000;  
private const Int32 MF_ENABLED =0×00000000;  
private const Int32 MF_GRAYED =0×00000001;  
private const Int32 MF_DISABLED =0×00000002; 
private const Int32 SC_MOVE = 0xF010; 
private const Int32 WM_NCLBUTTONDOWN = 0xA1;
private const Int32 WM_SYSCOMMAND = 0×112;
private const Int32 WM_INITMENUPOPUP = 0×117;

protected override void WndProc(ref System.Windows.Forms.Message m )
{
if (m.Msg == WM_INITMENUPOPUP)
{
    //handles popup of system menu
    if ((m.LParam.ToInt32() / 65536) != 0) // 'divide by 65536 to get hiword
    {
        Int32 AbleFlags = MF_ENABLED;
        if (!Moveable)
        {
            AbleFlags = MF_DISABLED | MF_GRAYED; // disable the move
        }
        EnableMenuItem(m.WParam, SC_MOVE, MF_BYCOMMAND | AbleFlags);
    }
}
if (!Moveable)
{
    if (m.Msg == WM_NCLBUTTONDOWN) //cancels the drag this is IMP
    {
        if (m.WParam.ToInt32() == HTCAPTION) return;
    }
    if (m.Msg == WM_SYSCOMMAND) // Cancels any clicks on move menu
    {
        if ((m.WParam.ToInt32() amp; 0xFFF0) == SC_MOVE) return;
    }
}
base.WndProc(ref m);
}  
  

Кроме того, вы можете обрабатывать OnMove событие вашей формы. Но я думаю, что это вызовет некоторое мерцание:

 private void Form1_Move(object sender, EventArgs e)
{
    this.Location = defaultLocation;
}
  

Ответ №8:

Просто измените FormBorderStyle свойство на None .

Комментарии:

1. Что ж, это делает то, что я хотел. Полноэкранный пользовательский интерфейс.

Ответ №9:

измените startpostionсвойства формы на Manual. Затем обработайте событие LocationChanged:

 private void frmMain_LocationChanged(object sender, EventArgs e)
{
Location = new Point(0, 0);
}
  

Ответ №10:

  1. Перейдите к событиям формы -> Местоположение изменено

напишите следующий код

 Location = new Point(this.Width,this.Height);
  

Комментарии:

1. у меня не работает! Я думаю, вам следует сначала сохранить значения верхнего и левого положений, затем: Location = новая точка (LeftPosition,TopPosition);

Ответ №11:

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

Комментарии:

1. Что ж… весь смысл программы в том, чтобы ее не перемещали, lol.

Ответ №12:

Вы можете подписаться на Form.Move событие и изменить его расположение.

Комментарии:

1. Да, я пробовал это, но форма начинает часто мигать, когда я пытаюсь переместить ее в новое место.

2. @Failed_Noob — отредактируйте свой вопрос, опубликуйте код и, возможно, кто-нибудь сможет предложить исправление.

Ответ №13:

Просто сбросьте местоположение в событии formlocation_changed туда, где оно было, т. Е. Установите Form.Location в переменную перед ее перемещением, и когда пользователь попытается переместить ее, она вернется в переменную location, в которую вы ее установили.

Ответ №14:

Частный подраздел MyFormLock() Me.Location = Новая точка (0, 0) конечного подраздела

 Private Sub SearchSDR_LocationChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LocationChanged
    Call MyFormLock()
End Sub
  

Ответ №15:

Вы можете попробовать:

 this.Locked = true;
  

Комментарии:

1. Есть ответы намного лучше, чем этот! Если вы собираетесь добавить совершенно другой ответ, по крайней мере, объясните это!