2

我有一个带有标准标题栏的标准表单,用户可以抓取并移动表单。在某些情况下,我只想将此移动限制为水平移动,因此无论鼠标实际如何移动,表单都保持在相同的 Y 坐标上。

为此,我捕获移动事件,当我检测到与 Y 的偏差时,我将表单移回原始 Y。就像这样:

private void TemplateSlide_Move(object sender, EventArgs e)
{
    int y = SlideSettings.LastLocation.Y;
    if (y != this.Location.Y)
    {
        SlideSettings.LastLocation = new Point(this.Location.X, y);
        this.Location=Settings.LastLocation;
    }
}

但这会导致很多闪烁。此外,因为表单实际上会在短时间内远离所需的 Y,这会导致我的程序特有的其他问题。

有没有办法防止表格偏离所需的 Y 坐标?

4

2 回答 2

3

在适当的时候,只需使用鼠标的Y坐标,将 X 坐标替换为您的静态值。例如

... // e.g Mouse Down
originalX = Mouse.X; // Or whatever static X value you have.

... // e.g Mouse Move
// Y is dynamically updated while X remains static
YourObject.Location = new Point(originalX, Mouse.Y);
于 2013-05-21T18:52:05.943 回答
3

捕获 WM_MOVING 并相应地修改 LPARAM 中的 RECT 结构。

就像是:

public partial class Form1 : Form
{

    public const int WM_MOVING = 0x216;

    public struct RECT
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }

    private int OriginalY = 0;
    private int OriginalHeight = 0;
    private bool HorizontalMovementOnly = true;

    public Form1()
    {
        InitializeComponent();
        this.Shown += new EventHandler(Form1_Shown);
        this.SizeChanged += new EventHandler(Form1_SizeChanged);
        this.Move += new EventHandler(Form1_Move);
    }

    void Form1_Move(object sender, EventArgs e)
    {
        this.SaveValues();
    }

    void Form1_SizeChanged(object sender, EventArgs e)
    {
        this.SaveValues();
    }

    void Form1_Shown(object sender, EventArgs e)
    {
        this.SaveValues();
    }

    private void SaveValues()
    {
        this.OriginalY = this.Location.Y;
        this.OriginalHeight = this.Size.Height;
    }

    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case WM_MOVING:
                if (this.HorizontalMovementOnly)
                {
                    RECT rect = (RECT)System.Runtime.InteropServices.Marshal.PtrToStructure(m.LParam, typeof(RECT));
                    rect.Top = this.OriginalY;
                    rect.Bottom = rect.Top + this.OriginalHeight;
                    System.Runtime.InteropServices.Marshal.StructureToPtr(rect, m.LParam, false);
                }
                break;
        }
        base.WndProc(ref m);            
    }
}
于 2013-05-21T19:15:42.163 回答