Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在C语言中截取全尺寸窗口的屏幕截图#_C#_Screenshot_Fullscreen_Winapi - Fatal编程技术网

C# 如何在C语言中截取全尺寸窗口的屏幕截图#

C# 如何在C语言中截取全尺寸窗口的屏幕截图#,c#,screenshot,fullscreen,winapi,C#,Screenshot,Fullscreen,Winapi,我正在尝试在C#.net中创建一个应用程序,用于捕获当前活动窗口的屏幕截图,包括必须使用滚动条滚动的区域。要非常清楚,我希望代码采取的活动窗口,包括该地区是不显示,只有通过使用滚动条显示屏幕截图 public class ScreenShot { /// <summary> /// Captures the screenshot of the entire desktop /// </summary> /// <returns>

我正在尝试在C#.net中创建一个应用程序,用于捕获当前活动窗口的屏幕截图,包括必须使用滚动条滚动的区域。要非常清楚,我希望代码采取的活动窗口,包括该地区是不显示,只有通过使用滚动条显示屏幕截图

public class ScreenShot
{
    /// <summary>
    /// Captures the screenshot of the entire desktop
    /// </summary>
    /// <returns>Image object containing the screenshot of the desktop</returns>
    private Image CaptureDesktop()
    {
        return CaptureWindow(User32.GetDesktopWindow());
    }

    public Image CaptureAciveWindow()
    {
        return CaptureWindow(User32.GetForegroundWindow());
    }

    /// <summary>
    /// An Internal method, that captures the screenshot of any given Application window, given its Handle.
    /// </summary>
    /// <param name="handle">The handle of the window you want to Capture</param>
    /// <returns>An Image object containing the screenshot of the active application window</returns>
    private Image CaptureWindow(IntPtr handle)
    {
        // get te hDC of the target window
        IntPtr hdcSrc = User32.GetWindowDC(handle);
        // get the size
        User32.RECT windowRect = new User32.RECT();
        User32.GetWindowRect(handle, ref windowRect);
        int width = windowRect.right - windowRect.left;
        int height = windowRect.bottom - windowRect.top;
        // create a device context we can copy to
        IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
        // create a bitmap we can copy it to,
        // using GetDeviceCaps to get the width/height
        IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
        // select the bitmap object
        IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
        // bitblt over
        GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
        // restore selection
        GDI32.SelectObject(hdcDest, hOld);
        // clean up 
        GDI32.DeleteDC(hdcDest);
        User32.ReleaseDC(handle, hdcSrc);
        // get a .NET image object for it
        Image img = Image.FromHbitmap(hBitmap);
        // free up the Bitmap object
        GDI32.DeleteObject(hBitmap);

        return img;
    }

    /// <summary>
    /// Helper class containing Gdi32 API functions
    /// </summary>
    private class GDI32
    {
        public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter

        [DllImport("gdi32.dll")]
        public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest,
            int nWidth, int nHeight, IntPtr hObjectSource,
            int nXSrc, int nYSrc, int dwRop);
        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth,
            int nHeight);
        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
        [DllImport("gdi32.dll")]
        public static extern bool DeleteDC(IntPtr hDC);
        [DllImport("gdi32.dll")]
        public static extern bool DeleteObject(IntPtr hObject);
        [DllImport("gdi32.dll")]
        public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
    }

    /// <summary>
    /// Helper class containing User32 API functions
    /// </summary>
    private class User32
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        }

        [DllImport("user32.dll")]
        public static extern IntPtr GetDesktopWindow();
        [DllImport("user32.dll")]
        public static extern IntPtr GetWindowDC(IntPtr hWnd);
        [DllImport("user32.dll")]
        public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
        [DllImport("user32.dll")]
        public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
        /// <summary>
        /// Gets the Handle for current active window
        /// </summary>
        /// <returns>Active windows Handle</returns>
        [DllImport("user32.dll")]
        public static extern IntPtr GetForegroundWindow();
    }
}
公共类截图
{
/// 
///捕获整个桌面的屏幕截图
/// 
///包含桌面截图的图像对象
私有图像捕获桌面()
{
返回CaptureWindow(User32.GetDesktopWindow());
}
公共图像捕获活动窗口()
{
返回CaptureWindow(User32.GetForegroundWindow());
}
/// 
///一个内部方法,它捕获任何给定应用程序窗口的屏幕截图,给定其句柄。
/// 
///要捕获的窗口的句柄
///包含活动应用程序窗口屏幕截图的图像对象
私有图像捕获窗口(IntPtr句柄)
{
//获取目标窗口的te hDC
IntPtr hdcSrc=User32.GetWindowDC(句柄);
//知道尺寸了吗
User32.RECT windowRect=新的User32.RECT();
User32.GetWindowRect(句柄,ref windowRect);
int width=windowRect.right-windowRect.left;
int height=windowRect.bottom-windowRect.top;
//创建可以复制到的设备上下文
IntPtr hdcDest=GDI32.CreateCompatibleDC(hdcSrc);
//创建一个我们可以复制到的位图,
//使用GetDeviceCaps获取宽度/高度
IntPtr hBitmap=GDI32.CreateCompatibleBitmap(hdcSrc,宽度,高度);
//选择位图对象
IntPtr hOld=GDI32。选择对象(hdcDest、hBitmap);
//结束
BitBlt(hdcDest,0,0,宽度,高度,hdcSrc,0,0,GDI32.SRCCOPY);
//恢复选择
GDI32.选择对象(hdcDest,保持);
//清理
GDI32.DeleteDC(hdcDest);
User32.ReleaseDC(句柄,hdcSrc);
//为它获取一个.NET图像对象
图像img=图像。来自hBitmap(hBitmap);
//释放位图对象
GDI32.DeleteObject(hBitmap);
返回img;
}
/// 
///包含Gdi32 API函数的帮助器类
/// 
私有类GDI32
{
public const int SRCCOPY=0x00CC0020;//BitBlt dwRop参数
[DllImport(“gdi32.dll”)]
公共静态外部bool BitBlt(IntPtr hObject、intnxtest、intnydest、,
int nWidth、int nHeight、IntPtr hObjectSource、,
int nXSrc、int nYSrc、int dwRop);
[DllImport(“gdi32.dll”)]
公共静态外部IntPtr CreateCompatibleBitmap(IntPtr hDC,int nWidth,
内特(右);
[DllImport(“gdi32.dll”)]
公共静态外部IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport(“gdi32.dll”)]
公共静态外部布尔删除DC(IntPtr hDC);
[DllImport(“gdi32.dll”)]
公共静态外部bool DeleteObject(IntPtr-hObject);
[DllImport(“gdi32.dll”)]
公共静态外部IntPtr SelectObject(IntPtr hDC、IntPtr hObject);
}
/// 
///包含user32api函数的Helper类
/// 
私有类User32
{
[StructLayout(LayoutKind.Sequential)]
公共结构矩形
{
公共int左;
公共int top;
公共权利;
公共int底部;
}
[DllImport(“user32.dll”)]
公共静态外部IntPtr GetDesktopWindow();
[DllImport(“user32.dll”)]
公共静态外部IntPtr GetWindowDC(IntPtr hWnd);
[DllImport(“user32.dll”)]
公共静态外部IntPtr ReleaseDC(IntPtr hWnd、IntPtr hDC);
[DllImport(“user32.dll”)]
公共静态外部IntPtr GetWindowRect(IntPtr hWnd,ref RECT RECT);
/// 
///获取当前活动窗口的句柄
/// 
///活动窗口句柄
[DllImport(“user32.dll”)]
公共静态外部IntPtr GetForegroundWindow();
}
}

您在这里做出的假设不一定是正确的:在未卷取的区域已经有东西在等待。应用程序可以构建特定高度或宽度的滚动条,并且在用户实际拖动滚动条之前,不会向曲面实际渲染任何内容。您要捕获的图像仅存在于“潜在”中。这可以用来提高性能—考虑及时加载,或减少内存使用。这是一种相当普遍的技术,因此你所要求的并没有真正意义。

如果你试图获取屏幕外的内容,那么
WM\u PRINT
可能会起作用
BitBlt
肯定不会

见:


不使用任何Win32 API调用,只使用.NET 2.0 at即可捕获屏幕内容。

您需要将整个窗口/窗体重新绘制到图形对象上。有关如何实现这一点的(简单)示例,请参见。您需要对项目中需要的所有控件实施支持。此外,如果在示例应用程序中调整窗口大小(模糊一些控件)并进行测试打印,您将看到主窗体(只是另一个控件)是在其他控件上绘制的,这不是真正的问题,但看起来不是很好-如果有问题,您可以删除对绘制主窗体的支持


或者,如果使用或切换到WPF,您可以使用PrintDialog.PrintVisual()打印控件(包括主窗口)。

WM\u print也不起作用,我想没有可能的解决方案。确定可能是我必须同意您的意见