0

Here is the code i have:

 public string selectedProgram;

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    public static extern IntPtr GetForegroundWindow();
    [DllImport("user32.dll")]
    private static extern bool GetWindowRect(IntPtr hWnd, Rectangle rect); 

    private void button2_Click(object sender, EventArgs e)
    {
        Process[] process = Process.GetProcesses();
        foreach (var p in process)
        {
            selectedProgram = listView1.SelectedItems.ToString();
            Rectangle bonds = new Rectangle();
            GetWindowRect(Handle, bonds);  
            Bitmap bmp = new Bitmap(bonds.Width, bonds.Height);
            using (var gfx = Graphics.FromImage(bmp))
            {
                gfx.CopyFromScreen(bonds.Location, Point.Empty, bonds.Size);
                pictureBox1.Image = bmp;
                frm2.Show();
                frm2.pictureBox1.Image = pictureBox1.Image;
            }
        }

I am getting an error or some green highlighting on GetWindowRect(Handle, bonds); that says:

A call to PInvoke function 'Screen Shot!WindowsFormsApplication1.Form3::GetWindowRect' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

How do i fix this so i can get a screenshot of the other application's window?

Hunter Mitchell
  • 7,063
  • 18
  • 69
  • 116
  • possible resolution http://stackoverflow.com/questions/2941960/a-call-to-pinvoke-function-has-unbalanced-the-stack , http://stackoverflow.com/questions/3749059/error-calling-function-a-call-to-pinvoke-function-unbalanced-the-stack – Devjosh Jul 09 '12 at 06:32
  • Within your loop you say `selectedProgram = listView1.SelectedItems.ToString()`. This should be `SelectedItem` (i.e. not plural), or else selectedProgram will always be `System.Windows.Forms.ListView.SelectedListViewItemCollection`. – walkingTarget Jul 09 '12 at 14:31

2 Answers2

1

Your declaration is missing the 'out' and using the wrong rectangle type, it should be as follows:

private static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);

The you call it with:

GetWindowRect(Handle, out bonds);

The Rectangle also needs to be a WinApi rectangle, not the .net class. See here for its definition. The convention is to call it RECT rather than Rectangle.

Michael
  • 8,891
  • 3
  • 29
  • 42
1

Looking at pinvoke.net (great reference), the signature GetWindowRect for should be:

public static extern bool GetWindowRect(HandleRef hwnd, out RECT lpRect);

It might also work to do this, which doesn't require you to define a custom RECT struct:

public static extern bool GetWindowRect(IntPtr hwnd, out Rectangle lpRect);

If that doesn't work, you can define a RECT struct based on this page, and use:

public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);

The pinvoke.net page on RECT shows how to convert between RECT and Rectangle.

Kendall Frey
  • 43,130
  • 20
  • 110
  • 148