|
■No95532 (くまくま さん) に返信
> 申し訳ございませんが、今後魔界の仮面弁士さんに回答をお任せしたいと思います。
(^_^;)
えぇと、それじゃ No95530 の案2パターンでのサンプル。
PictureBox 上の矩形をドラッグ移動できるようにして、
Shift キー押下中は移動範囲を制限してみました。
ただし、いろいろ手抜きな実装になっています。
たとえば、縦横移動制限時の起点座標は、
No95526 で書いていた「シフトキーを押した時の位置」ではなく、
「ドラッグ開始位置」に変更されています。
また、下記だと MouseDown 時にいきなりドラッグが開始されてしまいますが、
本来は、SystemInformation.DragSize 以上のマウス移動が発生するまでは
ドラッグを開始するべきではないですね。
public partial class Form1 : Form
{
// ドラッグ中にマウスカーソルを非表示にするかどうか
private readonly bool InvisibleCursor = true;
public Form1()
{
InitializeComponent();
}
private Rectangle box = new Rectangle(200, 200, 64, 64);
private Point? dragStart = null; // ドラッグ開始位置
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (dragStart == null)
{
e.Graphics.FillRectangle(Brushes.Blue, box);
}
else
{
bool shiftDown = ModifierKeys.HasFlag(Keys.Shift);
var pos = pictureBox1.PointToClient(Cursor.Position);
e.Graphics.DrawRectangle(shiftDown ? Pens.DarkGreen : Pens.DarkRed, box);
e.Graphics.FillRectangle(shiftDown ? Brushes.Green : Brushes.Red, DraggingPosition());
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (dragStart != null)
{
pictureBox1.Invalidate();
}
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (box.Contains(e.Location) && e.Button.HasFlag(MouseButtons.Left))
{
if (InvisibleCursor) { Cursor.Hide(); }
dragStart = e.Location;
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (dragStart != null)
{
if (InvisibleCursor) { Cursor.Show(); }
box = DraggingPosition();
dragStart = null;
pictureBox1.Refresh();
if (InvisibleCursor)
{
var pos = pictureBox1.PointToScreen(box.Location);
pos.Offset(box.Width / 2, box.Height / 2);
Cursor.Position = pos; // ドラッグ終了時に、マウス座標を本当に移動させる
}
}
}
private Rectangle DraggingPosition()
{
var newBox = box;
var f = dragStart.Value;
var t = pictureBox1.PointToClient(Cursor.Position);
bool shiftDown = ModifierKeys.HasFlag(Keys.Shift);
// 縦横の移動量を計測
int offsetX = t.X - f.X;
int offsetY = t.Y - f.Y;
// 新しい移動先を算出
// ただし Shift 押下中は、垂直・水平方向に制限する
int direction = Math.Abs(offsetX).CompareTo(Math.Abs(offsetY));
if (!shiftDown || direction > 0) { newBox.X += offsetX; }
if (!shiftDown || direction < 0) { newBox.Y += offsetY; }
return newBox;
}
}
|