代码基本从网上搜集而来,整理成以下文件: 
包括屏幕截图(和屏幕上看到的一致); 
以及控件截图(只要该控件在本窗口内显示完全且不被其他控件遮挡就可正确截图)

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Linq;
  5. using System.Runtime.InteropServices;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Windows.Forms;
  9. namespace LC
  10. {
  11. class ScreenCapture
  12. {
  13. #region 抓取屏幕
  14. /// <summary>
  15. /// 抓取屏幕(层叠的窗口)
  16. /// </summary>
  17. /// <param name="x">左上角的横坐标</param>
  18. /// <param name="y">左上角的纵坐标</param>
  19. /// <param name="width">抓取宽度</param>
  20. /// <param name="height">抓取高度</param>
  21. /// <returns></returns>
  22. public static Bitmap captureScreen(int x, int y, int width, int height)
  23. {
  24. Bitmap bmp = new Bitmap(width, height);
  25. using (Graphics g = Graphics.FromImage(bmp))
  26. {
  27. g.CopyFromScreen(new Point(x, y), new Point(0, 0), bmp.Size);
  28. g.Dispose();
  29. }
  30. //bit.Save(@"capture2.png");
  31. return bmp;
  32. }
  33. /// <summary>
  34. ///  抓取整个屏幕
  35. /// </summary>
  36. /// <returns></returns>
  37. public static Bitmap captureScreen()
  38. {
  39. Size screenSize = Screen.PrimaryScreen.Bounds.Size;
  40. return captureScreen(0,0,screenSize.Width,screenSize.Height);
  41. }
  42. #endregion
  43. #region 使用BitBlt方法抓取控件,无论控件是否被遮挡
  44. /// <summary>
  45. /// 控件(窗口)的截图,控件被其他窗口(而非本窗口内控件)遮挡时也可以正确截图,使用BitBlt方法
  46. /// </summary>
  47. /// <param name="control">需要被截图的控件</param>
  48. /// <returns>该控件的截图,控件被遮挡时也可以正确截图</returns>
  49. public static Bitmap captureControl(Control control)
  50. {
  51. //调用API截屏
  52. IntPtr hSrce = GetWindowDC(control.Handle);
  53. IntPtr hDest = CreateCompatibleDC(hSrce);
  54. IntPtr hBmp = CreateCompatibleBitmap(hSrce, control.Width, control.Height);
  55. IntPtr hOldBmp = SelectObject(hDest, hBmp);
  56. if (BitBlt(hDest, 0, 0, control.Width, control.Height, hSrce, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt))
  57. {
  58. Bitmap bmp = Image.FromHbitmap(hBmp);
  59. SelectObject(hDest, hOldBmp);
  60. DeleteObject(hBmp);
  61. DeleteDC(hDest);
  62. ReleaseDC(control.Handle, hSrce);
  63. // bmp.Save(@"a.png");
  64. // bmp.Dispose();
  65. return bmp;
  66. }
  67. return null;
  68. }
  69. //         /// <summary>
  70. //         /// 有问题!!!!!用户区域坐标不对啊
  71. //         /// 控件(窗口)的用户区域截图,控件被其他窗口(而非本窗口内控件)遮挡时也可以正确截图,使用BitBlt方法
  72. //         /// </summary>
  73. //         /// <param name="control">需要被截图的控件</param>
  74. //         /// <returns>控件(窗口)的用户区域截图</returns>
  75. //         public static Bitmap captureClientArea(Control control)
  76. //         {
  77. //
  78. //             Size sz = control.Size;
  79. //             Rectangle rect = control.ClientRectangle;
  80. //
  81. //
  82. //             //调用API截屏
  83. //             IntPtr hSrce = GetWindowDC(control.Handle);
  84. //             IntPtr hDest = CreateCompatibleDC(hSrce);
  85. //             IntPtr hBmp = CreateCompatibleBitmap(hSrce, rect.Width, rect.Height);
  86. //             IntPtr hOldBmp = SelectObject(hDest, hBmp);
  87. //             if (BitBlt(hDest, 0, 0, rect.Width, rect.Height, hSrce, rect.X, rect.Y, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt))
  88. //             {
  89. //                 Bitmap bmp = Image.FromHbitmap(hBmp);
  90. //                 SelectObject(hDest, hOldBmp);
  91. //                 DeleteObject(hBmp);
  92. //                 DeleteDC(hDest);
  93. //                 ReleaseDC(control.Handle, hSrce);
  94. //                 // bmp.Save(@"a.png");
  95. //                 // bmp.Dispose();
  96. //                 return bmp;
  97. //             }
  98. //             return null;
  99. //
  100. //         }
  101. #endregion
  102. #region 使用PrintWindow方法抓取窗口,无论控件是否被遮挡
  103. /// <summary>
  104. /// 窗口的截图,窗口被遮挡时也可以正确截图,使用PrintWindow方法
  105. /// </summary>
  106. /// <param name="control">需要被截图的窗口</param>
  107. /// <returns>窗口的截图,控件被遮挡时也可以正确截图</returns>
  108. public static Bitmap captureWindowUsingPrintWindow(Form form)
  109. {
  110. return GetWindow(form.Handle);
  111. }
  112. private static Bitmap GetWindow(IntPtr hWnd)
  113. {
  114. IntPtr hscrdc = GetWindowDC(hWnd);
  115. Control control = Control.FromHandle(hWnd);
  116. IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, control.Width, control.Height);
  117. IntPtr hmemdc = CreateCompatibleDC(hscrdc);
  118. SelectObject(hmemdc, hbitmap);
  119. PrintWindow(hWnd, hmemdc, 0);
  120. Bitmap bmp = Bitmap.FromHbitmap(hbitmap);
  121. DeleteDC(hscrdc);//删除用过的对象
  122. DeleteDC(hmemdc);//删除用过的对象
  123. return bmp;
  124. }
  125. #endregion
  126. #region  DLL calls
  127. [DllImport("gdi32.dll")]
  128. static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int
  129. wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, CopyPixelOperation rop);
  130. [DllImport("gdi32.dll")]
  131. static extern IntPtr DeleteDC(IntPtr hDc);
  132. [DllImport("gdi32.dll")]
  133. static extern IntPtr DeleteObject(IntPtr hDc);
  134. [DllImport("gdi32.dll")]
  135. static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
  136. [DllImport("gdi32.dll")]
  137. static extern IntPtr CreateCompatibleDC(IntPtr hdc);
  138. [DllImport("gdi32.dll")]
  139. static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);
  140. [DllImport("user32.dll")]
  141. public static extern IntPtr GetDesktopWindow();
  142. [DllImport("user32.dll")]
  143. public static extern IntPtr GetWindowDC(IntPtr ptr);
  144. [DllImport("user32.dll")]
  145. public static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, UInt32 nFlags);
  146. [DllImport("user32.dll")]
  147. static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc);
  148. #endregion
  149. }
  150. }

整理的C#屏幕截图,控件截图程序的更多相关文章

  1. DevExpress XtraReports 入门六 控件以程序方式创建一个 交叉表 报表

    原文:DevExpress XtraReports 入门六 控件以程序方式创建一个 交叉表 报表 本文只是为了帮助初次接触或是需要DevExpress XtraReports报表的人群使用的,为了帮助 ...

  2. ActiveX 控件导入程序

    ActiveX 控件导入程序将 ActiveX 控件的 COM 类型库中的类型定义转换为 Windows 窗体控件. http://msdn.microsoft.com/zh-cn/library/8 ...

  3. 使用SplashScreenManager控件定制程序加载页面

    需要devexpress版本在12.0及以上才支持 https://www.cnblogs.com/wuhuacong/p/6112461.html 在DevExpress程序中使用SplashScr ...

  4. C# WinForm 技巧:控件截图

    Point screenPoint = 控件.PointToScreen(new Point()); Rectangle rect = new Rectangle(screenPoint, chart ...

  5. 【iOS】控件截图、MP4格式视频流和m3u8格式视频流截取某一帧功能的实现

    最近开发遇到一个点击按钮实现直播视频流截屏的功能,去网上查了一下资料,总结了一下iOS中截屏相关的知识,然后自己做了个demo. demo主要实现了3种截屏方法,分别对应三种不同的应用场景. 1.im ...

  6. Winform DevExpress控件库(二) 使用SplashScreenManager控件定制程序加载页面

    SplashScreenManager控件:主要作用是显示在进行耗时操作时的等待界面: 位于 工具箱 -> Navigation & Layout(导航栏与布局类控件) 目录下: 在工具 ...

  7. WPF控件截图

    //截图         RenderTargetBitmap RenderVisaulToBitmap(Visual vsual, int width, int height)         { ...

  8. WPF 控件截图位置不正确的问题

    用WPF的RenderTargetBitmap可以截取控件内容到一张图片上,但是实际使用的时候经常出现截取的位置不正确的问题.今天是第二次解决这个问题,所以记录下,免得再忘了. RenderTarge ...

  9. Delphi实现拍照控件的程序代码

    完整的delphi拍照控件代码,实现利用摄像头进行拍照的功能.需要TVideoCap控件支持. procedure Tfrm1.Button2Click(Sender: TObject); Var j ...

随机推荐

  1. 笔记:加 ly 不一定是副词

    笔记:加 ly 不一定是副词 加 ly 变副词,但有些单词以 ly 结尾,长得像副词,却是形容词. costly = cost + ly a costly item. 一件昂贵的物品. lovely ...

  2. inotify 同步脚本

    #!/bin/bash path1=/home/htoa/tomcat/webapps/ROOT/htoa/ ip=192.168.30.13 /usr/bin/inotifywait -mrq -- ...

  3. MySQL的varchar类型注意事项

    前几天就在工作中发现这样一个问题:当某个字段的类型为varchar时,字段保存的值类似'100,200,300'  和 '100' 或 '100,400'.写SQL语句的时候就会犯这样的错误,例如: ...

  4. [转载]Linux 内核list_head 学习(一)

    在Linux内核中,提供了一个用来创建双向循环链表的结构 list_head.虽然linux内核是用C语言写的,但是list_head的引入,使得内核数据结构也可以拥有面向对象的特性,通过使用操作li ...

  5. mybatis 学习六 MyBatis主配置文件

    在定义sqlSessionFactory时需要指定MyBatis主配置文件: <bean id="sqlSessionFactory" class="org.myb ...

  6. stdin和STDIN_FILENO的区别

    STDIN_FILENO与stdin的区别: STDIN_FILENO: 1).数据类型:int 2).层次:系统级的API,是一个文件句柄,定义在<unistd.h>中. 3).相应的函 ...

  7. SUSE 设置IP地址、网关、DNS

    说明: ip:172.18.4.107 子网掩码:255.255.255.0 网关:172.18.4.254 dns:172.18.0.6 1.设置ip地址 vi /etc/sysconfig/net ...

  8. Oracle 11g oracle 用户密码过期问题 (ZT)

    http://www.blogjava.net/freeman1984/archive/2013/04/23/398301.html Oracle 11g 之前默认的用户时是没有密码过期的限制的,在O ...

  9. java线程面试题及答案

    1)2017Java面试题及答案:什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务 ...

  10. 部署和调优 2.9 mysql主从配置-3

    测试 先给主mysql解锁 > unlock tables; 删除一个表 > use db1; > show tables; > drop table help_categor ...