我在做截取整个窗口的程序时,窗体在屏幕的不同位置,使用GetWindowRect得到的width和Height会不同,为什么?求解决办法,谢谢
代码如下:
  private void test()
        {
            IntPtr hWnd = User32Dll.FindWindow(null, "FormTest");
            string savePath = "D:\\temp.bmp";//设置图片的临时保存路径。
            Rectangle formRect = new Rectangle(0, 0, 0, 0);
            if (User32Dll.GetWindowRect(hWnd, ref formRect))
            {
                //this.button1.Text = p.MainWindowTitle;
                this.textBox1.Text = "宽  " + formRect.Width;
                this.textBox2.Text = "高  " + formRect.Height;
                this.textBox3.Text = "Right  " + formRect.Right;
                this.textBox4.Text = "left  " + formRect.Left;
                this.textBox5.Text = "bottom  " + formRect.Bottom;
                this.textBox6.Text = "top  " + formRect.Top;
                Bitmap img = GetImg(hWnd, formRect.Width, formRect.Height);
                img.Save(savePath, ImageFormat.Bmp);//保存得到的截图
            }
        }        public Bitmap GetImg(IntPtr hWnd, int Width, int Height)//得到窗口截图
        {
            IntPtr hscrdc = User32Dll.GetWindowDC(hWnd);
            IntPtr hbitmap = Gdi32Dll.CreateCompatibleBitmap(hscrdc, Width, Height);
            IntPtr hmemdc = Gdi32Dll.CreateCompatibleDC(hscrdc);
            Gdi32Dll.SelectObject(hmemdc, hbitmap);
            Gdi32Dll.PrintWindow(hWnd, hmemdc, 0);
            Bitmap bmp = Bitmap.FromHbitmap(hbitmap);
            Gdi32Dll.DeleteDC(hscrdc);//删除用过的对象
            Gdi32Dll.DeleteObject(hbitmap);//删除用过的对象
            Gdi32Dll.DeleteDC(hmemdc);//删除用过的对象
            return bmp;
        }
截图效果如下(高和宽可以在窗体的TextBox中看到):

解决方案 »

  1.   

    说明一下:我这里为了截取第三方程序窗口,这里选用同一窗口,只是为了测试,谢谢使用到的类如下:using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.Drawing;
    using System.Windows.Forms;namespace WindowsAPI
    {
        public class User32Dll
        {
            #region User32.dll 函数
            [DllImport("user32.dll")]
            public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);        [DllImport("user32.dll")]
            public static extern bool GetWindowRect(IntPtr hWnd, ref Rectangle rect);        [DllImport("user32.dll")]
            public static extern IntPtr GetWindowDC(IntPtr hWnd);
            #endregion
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;namespace WindowsAPI
    {
        public class Gdi32Dll
        {
            [DllImport("gdi32.dll")]
            public static extern IntPtr CreateCompatibleBitmap(
            IntPtr hdc, // handle to DC
            int nWidth, // width of bitmap, in pixels
            int nHeight // height of bitmap, in pixels
            );        [DllImport("gdi32.dll")]
            public static extern IntPtr CreateCompatibleDC(
            IntPtr hdc // handle to DC
            );        [DllImport("gdi32.dll")]
            public static extern IntPtr SelectObject(
            IntPtr hdc, // handle to DC
            IntPtr hgdiobj // handle to object
            );        [DllImport("user32.dll")]
            public static extern bool PrintWindow(
            IntPtr hwnd, // Window to copy,Handle to the window that will be copied. 
            IntPtr hdcBlt, // HDC to print into,Handle to the device context. 
            UInt32 nFlags // Optional flags,Specifies the drawing options. It can be one of the following values. 
            );        [DllImport("gdi32.dll")]
            public static extern int DeleteDC(
            IntPtr hdc // handle to DC
            );        [DllImport("gdi32.dll")]
            public static extern int DeleteObject(
            IntPtr hdc
            );
        }
    }
      

  2.   

    帮你分析了下测试结果1和测试结果2对比会发现结果1.width-结果1.left = 544
    结果1.height-结果1.top = 319结果2.width-结果2.left=542
    结果2.height-结果2.top=319因此有理由猜测
    Rectangle 把 GetWindowRect返回的 right 和 bottom 当做 width 和 top处理了.
      

  3.   

              Rectangle formRect = new Rectangle(0, 0, 0, 0); 
    C++ 可以:
    formRect.OffsetRect(-formRect.left,-formRect.top);
    把左上角 设为 0
      

  4.   

    C#的Rectangle和WindowsAPI的RECT结构不一样
      

  5.   


    这个说法是正确的,可以这样选择,也可以重新定义个与RECT一样的结构体
      

  6.   

    上个回复错了,这个说法是正确的,可以这样选择,也可以重新定义个与RECT一样的结构体