Search code examples
c#formsoptimizationpictureboxdrag

Drag PictureBox


I want to drag a PictureBox, and I have managed to do so. But my application doesn't do it as smoothly as Windows photo viewer. I mean the difference isn't huge or anything, but it's noticeable. Is there something I could do to make it a little less choppy? This is my simple code:

int MOUSE_X = 0;
int MOUSE_Y = 0;

public Form1()
{
    InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
    picBox.Image = Image.FromFile(@"D:\test_big.png");
    picBox.Width = 3300;
    picBox.Height = 5100;
}

private void picBox_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        MOUSE_X = e.X;
        MOUSE_Y = e.Y;
    }
}

private void picBox_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        picBox.Left = picBox.Left + (e.X - MOUSE_X);
        picBox.Top = picBox.Top + (e.Y - MOUSE_Y);
    }
}

Solution

  • Here's a demo that illustrates your approach and the suggested one in the comments.

    Testing your code produces:

    SOQ60819266A

    Whereas the suggested code:

    using System.Runtime.InteropServices;
    //...
    
    private const int WM_SYSCOMMAND = 0x112;
    private const int MOUSE_MOVE = 0xF012;
    
    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(
        IntPtr hWnd,
        int wMsg,
        IntPtr wParam,
        IntPtr lParam);
    
    [DllImport("user32.dll")]
    private static extern int ReleaseCapture(IntPtr hWnd);
    
    private void picBox_MouseMove(object sender, MouseEventArgs e)
    {
        if (!DesignMode && e.Button == MouseButtons.Left)
        {
            ReleaseCapture(picBox.Handle);
            SendMessage(picBox.Handle, WM_SYSCOMMAND, (IntPtr)MOUSE_MOVE, IntPtr.Zero);
        }
    }
    

    Produces:

    SOQ60819266B

    Note that, I also use a background image to make the situation worse if I may say that. However, without the background image, it hard to detect which code snippet is used.