「グリッドへのスナップ」機能を C# の WinForm アプリケーションに追加しようとしていますが、フォームを正しく移動するのに少し問題があります。
望ましい結果は、ユーザーがフォームをクリックしてドラッグすると、フォームの位置がマウスの目的の方向に移動しますが、50 ピクセル単位で移動し、常に最後のグリッド ポイントに切り捨てられます。境界線をクリックしてドラッグすると、同じ 50 ピクセル単位でフォームのサイズが変更されます。
WndProc の WM_SIZING メッセージで新しいサイズを計算することで、サイズ変更を正しく機能させることができました。WM_MOVING で同じことを試みましたが、正しい機能が得られません。
私が得たのは、フォームが開始位置よりも高い (右または下) グリッド ポイントに移動しないことです。マウスが 1 ピクセル下 (上または左) のグリッド ポイントに向かって移動すると、フォームは 50 ピクセルジャンプします。もちろん、これは下のポイントへの望ましい移動ですが、一度だけ移動し、次のジャンプを行う前にマウスが追加のスペースを移動するのを待つ必要がありますが、次の 1 ピクセルのマウス移動に対して 50 ピクセル移動します。
私が見つけたのは、Message.LParam 内のウィンドウの位置が各メッセージで計算され、WM_MOVE が完了したときにのみ更新されることです。これは、マウス ボタンが離されていない場合でも当てはまります。そのため、マウスを上または左に移動すると、ウィンドウが強制的に 50 ピクセル移動し、次のメッセージ (つまり、別の 1 ピクセルのマウス移動) で、LParam は 50 ピクセル低くなり、1 ピクセルで次に低いグリッド ポイントにスナップするのに十分です。 . ただし、マウスが最初のクリック ポイントから 50 ピクセル移動するまでウィンドウを右または下に移動させたくないため、WndProc はウィンドウの位置を同じままにし、開始位置よりも高いポイントに到達することはありません。何らかの理由で、WM_SIZING はこれを行いません。サイズの変更が画面に表示されていなくても、ウィンドウのサイズが変更されているように見えます。
これが私が使用している私のコードです。わかりやすくするために、WM_SIZING 部分は削除されています。
private const int WM_MOVING = 0x216;
private const int WM_MOVE = 0x3;
struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_MOVING)
{
RECT rc = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
int w = rc.Right - rc.Left;
int h = rc.Bottom - rc.Top;
rc.Top = ((int)rc.Top / 50) * 50;
rc.Left = ((int)rc.Left / 50) * 50;
rc.Right = rc.Left + w;
rc.Bottom = rc.Top + h;
Marshal.StructureToPtr(rc, m.LParam, true);
}
base.WndProc(ref m);
}
この問題についての助けや洞察をありがとう。-ダスティン