Вопрос

Есть ли способ контролировать, куда вы можете переместить форму?

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

Я не хочу, чтобы реализация с ошибками, такая как locationchanged или перемещение события, и вставление его обратно в строку.Нет, есть способ использовать что-то вроде переопределения WndProc, но после некоторого поиска я ничего не смог найти.Пожалуйста помоги

Это было полезно?

Решение

Скорее всего, вы захотите переопределить WndProc и обработать сообщение WM_MOVING. По данным MSDN:

Сообщение WM_Moving отправляется в окно, которое перемещает пользователь.Обработка этого сообщения, приложение может контролировать положение прямоугольника перетаскивания и, при необходимости, изменить его положение.

Это был бы способ сделать это, однако вам, очевидно, придется настроить его под свои нужды:

using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace VerticalMovingForm
{
    public partial class Form1 : Form
    {
        private const int WM_MOVING = 0x0216;
        private readonly int positionX;
        private readonly int positionR;

        public Form1()
        {
            Left = 400;
            Width = 500;                            
            positionX = Left;
            positionR = Left + Width;
        }
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_MOVING)
            {
                var r = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
                r.Left = positionX;
                r.Right = positionR;
                Marshal.StructureToPtr(r, m.LParam, false);
            }
            base.WndProc(ref m);                
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }
    }
}

Другие советы

Например:

using System.Runtime.InteropServices;

protected override void WndProc(ref Message m)
{
    if (m.Msg == 0x216)  // WM_MOVING = 0x216
    {
        Rectangle rect = 
           (Rectangle) Marshal.PtrToStructure(m.LParam, typeof (Rectangle));
        if (rect.Left < 100)
        {
            // compensates for right side drift
            rect.Width = rect.Width + (100 - rect.Left);
            // force left side to 100
            rect.X = 100;
            Marshal.StructureToPtr(rect, m.LParam, true);
        }
    }
    base.WndProc(ref m);
}

Приведенный выше код устанавливает минимальную левую позицию 100.

Нет необходимости воссоздавать структуру RECT, как это сделал Дрис, собственный Rectangle .NET работает нормально.Однако вам необходимо установить местоположение через свойство X, поскольку свойство Left доступно только для получения.

Версия VB.NET:

Protected Overloads Overrides Sub WndProc(ByRef m As Message)
    If m.Msg = &H216 Then
        ' WM_MOVING = 0x216
        Dim rect As Rectangle = DirectCast(Marshal.PtrToStructure(m.LParam, GetType(Rectangle)), Rectangle)
        If rect.Left < 100 Then
            ' compensates for right side drift
            rect.Width = rect.Width + (100 - rect.Left)
            ' force left side to 100
            rect.X = 100
            Marshal.StructureToPtr(rect, m.LParam, True)
        End If
    End If
    MyBase.WndProc(m)
End Sub
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top