0

I need help please. I want to implement the ability to choose a folder before saving screenshots. This is my working code that I have created:

bmpScreenshot.Save("C:\\test\\pictures\\scr_(" + pict_no + ").Jpeg", ImageFormat.Jpeg);

pict_no++;

It is autoscreenshoter which increments a number of screenshot. But the folder now is constant. I want to create selection of folder before capturing auto screenshot. I used this:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

    }

    public void Tick(Object stateInfo)
    {
        string s;
        s = textBox3.Text+ "\\scr_(" + pict_no + ").Jpeg";

        // Set the bitmap object to the size of the screen

        bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);

        // Create a graphics object from the bitmap

        gfxScreenshot = Graphics.FromImage(bmpScreenshot);

        // Take the screenshot from the upper left corner to the right bottom corner

        gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);

        // Save the screenshot to the specified path that the user has chosen

        bmpScreenshot.Save(s, ImageFormat.Jpeg);

        pict_no++;


    }

    private void button1_Click(object sender, EventArgs e)
    {    
        MessageBox.Show("Printscreenování právě začalo a bude probíhat po " +textBox1.Text+ " sekundách.\nPřeji příjemný den :D");
         Cas();
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        int anInteger;
        anInteger = Convert.ToInt32(textBox1.Text);
        anInteger = int.Parse(textBox1.Text);

    }

    public void Cas()
    {
        int anInteger;
        anInteger = Convert.ToInt32(textBox1.Text);
        anInteger = int.Parse(textBox1.Text);
        TimerCallback callback = new TimerCallback(Tick);
        // create a timer tick
        System.Threading.Timer stateTimer = new System.Threading.Timer(callback, null, 0, anInteger*1000);
        // loop here forever
        for (; ; )
        {
            int enInteger;
            enInteger = Convert.ToInt32(textBox2.Text);
            enInteger = int.Parse(textBox2.Text);
            if (pict_no == enInteger) Environment.FailFast("Konec programu.");
        }
    }

    public void ChooseFolder()
    {
        if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
        {
            textBox3.Text = folderBrowserDialog1.SelectedPath;
        }
    }

    public static Bitmap bmpScreenshot { get; set; }

    public static Graphics gfxScreenshot { get; set; }

    public static int pict_no { get; set; }

    private void textBox2_TextChanged(object sender, EventArgs e)
    {

    }

    private void textBox3_TextChanged(object sender, EventArgs e)
    {

    }

    private void button2_Click(object sender, EventArgs e)
    {
        ChooseFolder();

    }

}

I don't know why it doesn't work.

  • Could you show what the path string outputs? What does this resolve into? `textBox3.Text+ "\\scr_(" + pict_no + ").Jpeg"` – Toon Casteele May 13 '13 at 08:35
  • It resolve into nothing. It wont save it in choosed folder by folderbrowser dialog. The first code with constant folder is working, but this isnt. Or what do you mean with strings output? I am newbie in C#. In my work, my boss wanted C# from me, but he didnt give me any time to start learning. So i must learn in progress. :( I can copy here the whole Application... – Jiri Vocelka May 13 '13 at 08:39
  • if you try `string s = textBox3.Text+ "\\scr_(" + pict_no + ").Jpeg"` what does `s` contain? – Toon Casteele May 13 '13 at 09:13
  • this makes the same, i choosed the folder, but it doesnt start to screenshoting. how can i see what s contains? Thx for advancing. – Jiri Vocelka May 13 '13 at 09:17
  • print it out in your application, or debug... – Toon Casteele May 13 '13 at 09:18
  • yeah, you mean Console.Writeline(s); ? Ill try it. – Jiri Vocelka May 13 '13 at 09:20
  • Ouch, i cant use Console.Writeline in Windows form application. Can you tell me please how exactly can i see what S contains? Thanks – Jiri Vocelka May 13 '13 at 09:23
  • ... You can set the text property of a label in your application or debug it with breakpoints... – Toon Casteele May 13 '13 at 09:24
  • pict_no 0 int s null string + textBox3 {Text = '((System.Windows.Forms.TextBox)(textBox3)).Text' threw an exception of type 'Microsoft.VisualStudio.Debugger.Runtime.CrossThreadMessagingException'} System.Windows.Forms.TextBox + textBox3.Text 'textBox3.Text' threw an exception of type 'Microsoft.VisualStudio.Debugger.Runtime.CrossThreadMessagingException' string {Microsoft.VisualStudio.Debugger.Runtime.CrossThreadMessagingException} + this {WindowsFormsApplication4.Form1} WindowsFormsApplication4.Form1 – Jiri Vocelka May 13 '13 at 09:30
  • Are you executing your `Save` in a different Thread? – Toon Casteele May 13 '13 at 09:31
  • the whole void is: public void Tick(Object stateInfo) { string s; s = textBox3.Text+ "\\scr_(" + pict_no + ").Jpeg"; bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb); gfxScreenshot = Graphics.FromImage(bmpScreenshot); bmpScreenshot.Save(s, ImageFormat.Jpeg); pict_no++; } – Jiri Vocelka May 13 '13 at 09:33
  • Well there you have it. You're using a timer tick, which is executed in a different thread. You cannot access controls from your main form from a different thread like that. Please also note that you should edit your question instead of putting large code fragments here – Toon Casteele May 13 '13 at 09:38
  • Ok, thanks for help, ill now edit the question. And how can i repair it? – Jiri Vocelka May 13 '13 at 09:43
  • The first question you have to ask yourself if you absolutely need the Timer and why? – Toon Casteele May 13 '13 at 09:45
  • The application needs timer for timming of the printscreens. You run the app and it asks you: What is the frequency of screenshots. You set 5 and the application makes every 5 seconds screenshot. Its app for our 8hours tests ( eg. we need scrnsht every 10 minutes) – Jiri Vocelka May 13 '13 at 09:49
  • Anyway, thanks for advancing. I dont know how to make it without timer + with this optionally folder. – Jiri Vocelka May 13 '13 at 10:33

1 Answers1

0

You can Invoke methods in your main thread where you can access the GUI from the Tick Event.

In your Tick event:

this.Invoke(new MethodInvoker(delegate { this.Proceed(); }), null);

Then you can put what you want to do in the Proceed() method.

private void Proceed()
{
    string s;
    s = textBox3.Text+ "\\scr_(" + pict_no + ").Jpeg";

    // Set the bitmap object to the size of the screen

    bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);

    // Create a graphics object from the bitmap

    gfxScreenshot = Graphics.FromImage(bmpScreenshot);

    // Take the screenshot from the upper left corner to the right bottom corner

    gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);

    // Save the screenshot to the specified path that the user has chosen

    bmpScreenshot.Save(s, ImageFormat.Jpeg);

    pict_no++;
}
Toon Casteele
  • 2,479
  • 15
  • 25
  • Really thanks for advantage, but when i use this Invoke and new Void Proceed on my old functionally program with the fixed destination, it does not screenshoting. I deleted my Tick event and put there: this.Invoke(new MethodInvoker(delegate { this.Proceed(); }), null); then i made new Void Proceed as you wrote, but it doesnt works. – Jiri Vocelka May 13 '13 at 13:50
  • Well, you will have to look to debug your program. Set some breakpoints and run through your code – Toon Casteele May 13 '13 at 13:51
  • Does it throw an exception? – Toon Casteele May 13 '13 at 13:57
  • Nope, when i give Breakpoint on private void Proceed(), the program never jumps there. So it throws nothing. It didnt run there. Thank you really much. It went to the Tick event with this.Invoke(new MethodInvoker(delegate { this.Proceed(); }), null);, but then it didnt jump on Proceed() – Jiri Vocelka May 13 '13 at 13:58
  • try using a threading timer instead of the forms one. Then try again invoking your method when your timer has elapsed – Toon Casteele May 13 '13 at 14:08
  • 1
    Thank you really much man, youre the BOSS! I´ll be not fired now thank to you. We´ll meet again when i get some new work. :D – Jiri Vocelka May 13 '13 at 14:59