0

There is a method that I take a lot of screenshots. In that:

private Bitmap GetPlayedScreen()
{
    var rect = new Rectangle(Location.X, Location.Y, Width, Height);
    var img = new Bitmap(rect.Width, rect.Height, PixelFormat.Format64bppArgb);
    var GFX = Graphics.FromImage(img);
    GFX.CopyFromScreen(rect.Left, rect.Top, 0, 0, Size);
    return img;
}

I use this method with the code like this:

GetPlayedScreen().Save(/*file_path_to_be_saved*/, ImageFormat.Jpeg);
labelFileName.Text = @"● " + file_name;
_counter += 1;

When this process is repeated several hundred times, I get StackOverflowException error. As I could not solve this error, it was not possible to catch and end the process.

Here is my full code:

public partial class PlayedScreen : Form
{
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);
    private int _counter { get; set; } = 1;
    public PlayedScreen()
    {
        InitializeComponent();
        RegisterHotKey(Handle, 0, 0, Keys.F5.GetHashCode());
    }
    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);

        if (m.Msg == 0x0312)
        {
            if (_counter < 1300)
            {
                var file_name = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fff") + ".jpg";
                GetPlayedScreen().Save("D:\\Test\\" + file_name, ImageFormat.Jpeg);
                label1.Text = @"● " + file_name;

                SendKeys.SendWait("{F5}");
                _counter += 1;
            }
        }
    }
    private Bitmap GetPlayedScreen()
    {
        var rect = new Rectangle(Location.X, Location.Y, Width, Height);
        var img = new Bitmap(rect.Width, rect.Height, PixelFormat.Format64bppArgb);
        var GFX = Graphics.FromImage(img);
        GFX.CopyFromScreen(rect.Left, rect.Top, 0, 0, Size);
        return img;
    }
}

I want the GetPlayedScreen method to repeat 1300 times when I press F5 but it gives StackOverflowException error in about 500 repetitions.

Quince
  • 144
  • 11

1 Answers1

2

Avoid SendMessage within the message handler.

protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);

        if (m.Msg == 0x0312)
        {
            Task.Run( () => {
              for( int i=0; i<1300; i++ )
              {
                  var file_name = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fff") + ".jpg";
                  using( var bitmap = GetPlayedScreen())
                  {
                    bitmap.Save("D:\\Test\\" + file_name, ImageFormat.Jpeg)
                  }
            // Needs some WinForms dispatch message here...
            //    label1.Text = @"● " + file_name;
              }
            });
        }
    }

    private Bitmap GetPlayedScreen()
    {
        var rect = new Rectangle(Location.X, Location.Y, Width, Height);
        var img = new Bitmap(rect.Width, rect.Height, PixelFormat.Format64bppArgb);
        var GFX = Graphics.FromImage(img);
        GFX.CopyFromScreen(rect.Left, rect.Top, 0, 0, Size);
        return img;
    }
Frank Nielsen
  • 1,546
  • 1
  • 10
  • 17
  • Thank you very much for your support, but I keep getting the same error. – Quince Jan 19 '20 at 20:54
  • @Quince updated answer, try to see if that will do the job. – Frank Nielsen Jan 19 '20 at 21:06
  • Thank you very much for your interest and support. It is very gratifying to fix an error that I do not even understand what it is ... – Quince Jan 19 '20 at 21:15
  • 1
    I think that `SendKey` uses `SendMessage` under the hood, so it waits for the response. That means that your call `WndProc` recursively 1300 times. https://stackoverflow.com/questions/3376619/what-is-the-difference-between-send-message-and-post-message-and-how-these-relat – Frank Nielsen Jan 19 '20 at 21:24