0

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);
    }
}
spunit
  • 523
  • 2
  • 6
  • 23
  • If you have DoubleBuffer set on the Form, turn it off. – Jimi Mar 28 '20 at 18:27
  • I've not touched DoubleBuffer, but I tested false / true on form load, but I didn't notice anything different. – spunit Mar 28 '20 at 20:30
  • 1
    DoubleBuffer active on the Form can cause stuttering when a large Image is dragged around. If it's already off, I don't see why the drag operation shouldn't be smooth. Unless you have some other sizing or painting logic in place (or other calculations) that you have not mentioned. – Jimi Mar 28 '20 at 20:52
  • No I only have the code in the question, I haven't modified anything else. I mean it doesn't stutter super much, but when comparing to Windows photo viewer it's definitely noticeable. – spunit Mar 28 '20 at 21:07
  • Do you have a background image in the parent, the Form? –  Mar 28 '20 at 21:08
  • No, it's a brand new project. Nothing changed. – spunit Mar 28 '20 at 21:10
  • It doesn't seem to make any difference at all if I change to a small image by the way. – spunit Mar 28 '20 at 21:14
  • What is the Framework version in use? – Jimi Mar 28 '20 at 21:20
  • Strange. well, try win32 functions to move that picture, in the `picBox.MouseMove` event call `ReleaseCapture(picBox.Handle);` and `SendMessage(picBox.Handle, WM_SYSCOMMAND, (IntPtr)MOUSE_MOVE, IntPtr.Zero);` I think you'll get a better result. Here: [ReleaseCapture](https://www.pinvoke.net/default.aspx/user32.releasecapture) and [SendMessage](http://pinvoke.net/default.aspx/user32.SendMessage) –  Mar 28 '20 at 21:21
  • `WM_SYSCOMMAND = 0x112` and `MOUSE_MOVE = 0xF012`. –  Mar 28 '20 at 21:22
  • Jimi: 4.6.1. JQSOFT: I'm sorry what do I do after ReleaseCapture and SendMessage? Sorry I'm not very advanced. – spunit Mar 28 '20 at 21:30
  • Do nothing, run and move it. I mean the `picBox` :) –  Mar 28 '20 at 21:31
  • Well I mean I think I have missed something... https://imgur.com/pep7Gbn – spunit Mar 28 '20 at 21:36
  • Oh I got all dll imported! but this is red: (IntPtr)MOUSE_MOVE, IntPtr.Zero =) – spunit Mar 28 '20 at 21:39
  • Hmmm just to be sure: did I do your code correct? Also this is the error when moving https://imgur.com/a/spwrVIm – spunit Mar 28 '20 at 21:59

1 Answers1

1

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.

  • First code can go right above picBox_MouseMove right? using at the very top of course. If that's correct, as soon as I drag the picture, it crashes. Thanks for all the help so far! =) – spunit Mar 28 '20 at 21:49
  • Great example! I don't know why, but when I use this exact code I get an error: https://imgur.com/jCniFg5 – spunit Mar 29 '20 at 10:49
  • Oh wait it works if I don't run it trough VS for some reason... But sadly I didn't notice any difference (I have no background). Maybe Windows photo viewer is just written in a little better suited language to drag a picture than C#. As I said the difference between Windows photo viewer and this isn't huge or anything, but definitely noticeable if comparing. Anyway thanks a ton for helping me try out this win32 method! =) – spunit Mar 29 '20 at 12:30