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 に答える