C # Form Control Move - PullRequest
       11

C # Form Control Move

3 голосов
/ 01 июня 2009

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

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

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

Ответы [ 3 ]

3 голосов
/ 01 июня 2009

Например:

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, как это делал driis, .NET Rectangle работает нормально. Однако вы должны установить местоположение с помощью свойства X, поскольку Left является свойством Get only.

2 голосов
/ 01 июня 2009

Скорее всего, вы захотите переопределить 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;
        }
    }
}
1 голос
/ 28 июня 2009

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