C# 根据窗口句柄获取窗口截图

本文经原作者授权以原创方式二次分享,欢迎转载、分享。

C# 根据窗口句柄获取窗口截图

作者:唐宋元明清的博客

原文链接:    https://www.cnblogs.com/kybs0/p/15768990.html

  • 本章介绍如何通过句柄,截取指定窗口内容,以及截取失败的场景。

一、根据窗口句柄获取窗口截图
  • 先创建一个测试窗口程序A,显示如下:

  • 同时我们把此窗口的句柄显示到一个文本输入框内。

TestBox.Text = new WindowInteropHelper(this).Handle.ToString();
  • 如上图所示,1774674是此窗口的句柄值。

  • 然后,我们新建一个窗口程序B,对窗口A进行截图并展示。

var windowIntPtr = new IntPtr(1774674);
var bitmapImage = GetWindowShotCut(windowIntPtr);
TestImage.Source = bitmapImage;
  • 截图方法及详细操作如下:

private BitmapImage GetWindowShotCut(IntPtr intPtr)
{var image = WindowCaptureHelper.GetShotCutImage(intPtr);var bitmapImage = BitmapConveters.ConvertToBitmapImage(image);return bitmapImage;
}
  • WindowCaptureHelper代码如下:

public class WindowCaptureHelper{[DllImport("user32.dll")]private static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rectangle rect);[DllImport("gdi32.dll")]private static extern IntPtr CreateCompatibleDC(IntPtr hdc);[DllImport("gdi32.dll")]private static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);[DllImport("gdi32.dll")]private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);[DllImport("gdi32.dll")]private static extern int DeleteDC(IntPtr hdc);[DllImport("user32.dll")]private static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, int nFlags);[DllImport("user32.dll")]private static extern IntPtr GetWindowDC(IntPtr hwnd);public static Bitmap GetShotCutImage(IntPtr hWnd){var hscrdc = GetWindowDC(hWnd);var windowRect = new Rectangle();GetWindowRect(hWnd, ref windowRect);int width = Math.Abs(windowRect.Width- windowRect.X);int height = Math.Abs(windowRect.Height- windowRect.Y);var hbitmap = CreateCompatibleBitmap(hscrdc, width, height);var hmemdc = CreateCompatibleDC(hscrdc);SelectObject(hmemdc, hbitmap);PrintWindow(hWnd, hmemdc, 0);var bmp = Image.FromHbitmap(hbitmap);DeleteDC(hscrdc);DeleteDC(hmemdc);return bmp;}}
  • BitmapConveters:代码如下:

public class BitmapConveters{[DllImport("gdi32")]static extern int DeleteObject(IntPtr o);public static BitmapSource ConvertToBitMapSource(Bitmap bitmap){IntPtr intPtrl = bitmap.GetHbitmap();BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(intPtrl,IntPtr.Zero,Int32Rect.Empty,BitmapSizeOptions.FromEmptyOptions());DeleteObject(intPtrl);return bitmapSource;}public static BitmapImage ConvertToBitmapImage(Bitmap bitmap){using (MemoryStream stream = new MemoryStream()){bitmap.Save(stream, ImageFormat.Bmp);stream.Position = 0;BitmapImage result = new BitmapImage();result.BeginInit();result.CacheOption = BitmapCacheOption.OnLoad;result.StreamSource = stream;result.EndInit();result.Freeze();return result;}}}
  • 截图后显示如下:

二、窗口截图失败
  • 窗口A在特定场景下,我们截到的窗口内容是黑色的:

  • 截图获取失败了,窗口A做了什么处理?

  • 定位发现是属性AllowsTransparency="True"的锅,搜索了下,网上也有同样的反馈:

Taking a screenshot of windows with AllowsTransparency="True" (microsoft.com)[1]

c# - Capture transparent WPF Window for streaming - Stack Overflow[2]

.net - Transparent child window renders as black when screen sharing main window on Microsoft Teams - Stack Overflow[3]

有个Issue在跟进:    Screen capture semi-transparent windows? · Issue #334 · microsoft/WindowsCompositionSamples (github.com)[4]

官方大佬说,这是他们的一个BUG。在win10 2004更新版本中,已处理。

不过,我现在是win11,依然还有问题。。。我是在win10上直接更新到win11,可能原来那个win10企业LTSC版本有点win11更新只更新了UI?或者win11是基于原来旧分支开发的?等回复中...
Taking a screenshot of windows with AllowsTransparency="True" · Issue #358 · microsoft/WindowsCompositionSamples (github.com)[5]

github[6]

参考资料

[1]

Taking a screenshot of windows with AllowsTransparency=True: https://social.msdn.microsoft.com/Forums/office/en-US/3368f8f5-efb3-40cc-add5-f5311a74a954/taking-a-screenshot-of-windows-with-allowstransparencytrue

[2]

c# - Capture transparent WPF Window for streaming - Stack Overflow: https://stackoverflow.com/questions/50888023/capture-transparent-wpf-window-for-streaming

[3]

.net - Transparent child window renders as black when screen sharing main window on Microsoft Teams - Stack Overflow: https://stackoverflow.com/questions/65514472/transparent-child-window-renders-as-black-when-screen-sharing-main-window-on-mic

[4]

Screen capture semi-transparent windows? · Issue #334 · microsoft/WindowsCompositionSamples (github.com Screen capture semi-transparent windows? · Issue #334: https://github.com/microsoft/WindowsCompositionSamples/issues/334

[5]

Taking a screenshot of windows with AllowsTransparency=True · Issue #358 ·: https://github.com/microsoft/WindowsCompositionSamples/issues/358

[6]

github: https://github.com/Kybs0

技术群:添加小编微信并备注进群

小编微信:mm1552923

公众号:dotNet编程大全

C# 根据窗口句柄获取窗口截图相关推荐

  1. 根据获取的窗口句柄遍历窗口Edit控件

    网上说遍历窗口控件有两种方法: 1),使用EnumChildWindows,没有深究,     学习网址如下: http://blog.sina.com.cn/s/blog_60ac1c4b01011 ...

  2. 窗口截图(可指定HWND窗口句柄)

    方法一 BOOL SaveHwndToBmpFile(HWND hWnd, LPCTSTR lpszPath) {HWND hDesktop = ::GetDesktopWindow();ASSERT ...

  3. C# API之常用操作窗口类函数详解[查找所有窗口、获取目标句柄的类名、获取窗口文本、获取当前活动窗口、通过窗口句柄获取线程ID、获取指定窗口位置]

    /// <summary>/// 查找所有窗口(只要是在进程里面的)/// 如果不限制类名或者标题使用null代替/// </summary>/// <param nam ...

  4. 调用Windows api 窗口截图

    分别调用windows api函数及CVI自带函数,完成对GRAPH界面的截图 界面设计如下图,右侧为graph控件的位置信息,调用API函数是完成对于选择窗口的固定位置进行截图,调用CVI自带函数则 ...

  5. C#通过Windows API捕获窗,获取窗口文本(FindWindow、GetWindowText),附录:Windows窗口消息大全、Windows API大全

    文章目录 一.前言 二.使用Spy++工具分析窗口 三.C#通过Windows API捕获窗口,获取窗口文本 四.附录:Windows窗口消息 五.Windows API大全 1.API之网络函数 2 ...

  6. Qt应用窗口截图代码演示

      本篇介绍如何使用Qt进行屏幕或应用窗口截图.   QScreen类提供了很多与屏幕相关的API, 例如抓屏API: QPixmap grabWindow(WId window, int x = 0 ...

  7. python窗口截图_Python 脚本自动窗口截图

    利用Python自带的win32api和win32con.win32gui等模块,我们能执行许多windows下的自动化操作.比如两个窗口的自动点击操作,从软件中的窗口复制文本到txt中,甚至是截图操 ...

  8. 【Python】【pywin32】【指定窗口截图】

    python实现Windows下指定窗口截屏脚本 背景 源码 参考链接 背景 最近对python pywin32模块感兴趣,且想实现一个能够截取指定窗口图片的小功能.在各大论坛遨游一番后,有所收获,记 ...

  9. Window插件获取窗口坐标

    本帖最后由 兄弟工程师05 于 2013-3-22 09:01 编辑 Window插件获取窗口坐标[code]Call RunApp("notepad.exe") Delay 15 ...

最新文章

  1. insight切换窗口 source_Source Insight函数调用关系显示设置
  2. TCP/IP协议分析
  3. 在派生类中引发基类事件
  4. .Net Micro Framework SDK 2.5 发布
  5. 【转】idea激活搭建授权服务器
  6. Flask-SQLAlchemy 中如何不区分大小写查询?
  7. 美团NLP中心算法实习生招聘
  8. 【转】基于SQL的Web系统安全防范——SQL注入漏洞
  9. stl之deque双端队列容器
  10. SLAM_2021_F-LOAM:基于激光雷达的快速里程计和建图
  11. 同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式
  12. CMU 15-213 Introduction to Computer Systems学习笔记(16) Virtual Memory: Concepts
  13. 计算机应用bsp什么意思,bsp文件是什么?bsp文件怎么打开?
  14. 高德地图打开卫星地图(高德地图设置方法)
  15. yyyy-MM-dd 转化成 中国标准时间(Tue Dec 31 2019 00:00:00 GMT+0800 (中国标准时间))
  16. android双卡切换流量代码,双卡双待手机流量怎么切换 方法有哪些【图文】
  17. 16999元!华为Mate X终于发布了!附上手视频
  18. echarts pie饼图既显示内部又显示外部指示线
  19. 唯快不破:redis源码剖析04-sds动态字符串
  20. 杰克 - 鬼马海盗主角加勒比海盗系列的

热门文章

  1. Matplotlib绘图库入门(三):面积图
  2. android实现选择题功能,安卓系统的一些选择题
  3. Win10禁用各种后台更新的方法
  4. SimpleITK、Slicer读取图像信息
  5. 气象学与气候学-复习资料
  6. ipo 增量发行 存量发行
  7. 工业品物料,要如何做好管理?
  8. ISTQB认证工程师学习笔记(3)——静态测试(静态分析和评审)
  9. Java中级篇——Spring MVC 是什么(附加响应状态代码列举)
  10. YYGH-6-微信登录