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

一、根据窗口句柄获取窗口截图

先创建一个测试窗口程序A,显示如下:

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

1     TestBox.Text = new WindowInteropHelper(this).Handle.ToString();

如上图所示,1774674是此窗口的句柄值。

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

1     var windowIntPtr = new IntPtr(1774674);
2 var bitmapImage = GetWindowShotCut(windowIntPtr);
3 TestImage.Source = bitmapImage;

截图方法及详细操作如下:

1     private BitmapImage GetWindowShotCut(IntPtr intPtr)
2 {
3 var image = WindowCaptureHelper.GetShotCutImage(intPtr);
4 var bitmapImage = BitmapConveters.ConvertToBitmapImage(image);
5 return bitmapImage;
6 }

WindowCaptureHelper:

 1     public class WindowCaptureHelper
2 {
3 [DllImport("user32.dll")]
4 private static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rectangle rect);
5 [DllImport("gdi32.dll")]
6 private static extern IntPtr CreateCompatibleDC(IntPtr hdc);
7 [DllImport("gdi32.dll")]
8 private static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
9 [DllImport("gdi32.dll")]
10 private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
11 [DllImport("gdi32.dll")]
12 private static extern int DeleteDC(IntPtr hdc);
13 [DllImport("user32.dll")]
14 private static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, int nFlags);
15 [DllImport("user32.dll")]
16 private static extern IntPtr GetWindowDC(IntPtr hwnd);
17
18 public static Bitmap GetShotCutImage(IntPtr hWnd)
19 {
20 var hscrdc = GetWindowDC(hWnd);
21 var windowRect = new Rectangle();
22 GetWindowRect(hWnd, ref windowRect);
23 int width = Math.Abs(windowRect.Width- windowRect.X);
24 int height = Math.Abs(windowRect.Height- windowRect.Y);
25 var hbitmap = CreateCompatibleBitmap(hscrdc, width, height);
26 var hmemdc = CreateCompatibleDC(hscrdc);
27 SelectObject(hmemdc, hbitmap);
28 PrintWindow(hWnd, hmemdc, 0);
29 var bmp = Image.FromHbitmap(hbitmap);
30 DeleteDC(hscrdc);
31 DeleteDC(hmemdc);
32 return bmp;
33 }
34 }

BitmapConveters:

 1     public class BitmapConveters
2 {
3 [DllImport("gdi32")]
4 static extern int DeleteObject(IntPtr o);
5 public static BitmapSource ConvertToBitMapSource(Bitmap bitmap)
6 {
7 IntPtr intPtrl = bitmap.GetHbitmap();
8 BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(intPtrl,
9 IntPtr.Zero,
10 Int32Rect.Empty,
11 BitmapSizeOptions.FromEmptyOptions());
12 DeleteObject(intPtrl);
13 return bitmapSource;
14 }
15 public static BitmapImage ConvertToBitmapImage(Bitmap bitmap)
16 {
17 using (MemoryStream stream = new MemoryStream())
18 {
19 bitmap.Save(stream, ImageFormat.Bmp);
20 stream.Position = 0;
21 BitmapImage result = new BitmapImage();
22 result.BeginInit();
23 result.CacheOption = BitmapCacheOption.OnLoad;
24 result.StreamSource = stream;
25 result.EndInit();
26 result.Freeze();
27 return result;
28 }
29 }
30 }

截图后显示如下:

二、窗口截图失败

窗口A在特定场景下,我们截到的窗口内容是黑色的:

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

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

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

官方大佬说,这是他们的一个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)

C# 根据窗口句柄获取窗口截图的更多相关文章

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

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

  2. selenium常用操作,查找元素,操作Cookie,获取截图,获取窗口信息,切换,执行js代码

    目录: 1. 常用操作 2. 查找元素 3. 操作Cookie 4. 获取截图 5. 获取窗口信息 6. 切换 7. 执行JS代码 简介 selenium.webdriver.remote.webdr ...

  3. C# 非顶端窗口截图 - 用于查找指定窗口并截图

    原文地址:http://blog.csdn.net/u013096568/article/details/53400389 panel上可以通过DrawToBitmap截图,不管是否在屏幕外是否有遮挡 ...

  4. ATL中窗口句柄与窗口过程的关联方法

    ATL中采用了一种动态生成机器指令的方式进行窗口句柄与窗口对象进行关联,以是详细分析: CWindowImpl会在第一次调用Create时注册窗口类,该窗口类是的信息是在CWindowImpl的子类中 ...

  5. C#获取窗口,模拟按键操作

    C#获取窗口,模拟按键操作,实现计算器模拟操作.首先引用. using System.Runtime.InteropServices; 使用DllImport引入两个函数: // Get a hand ...

  6. (转载博文)MFC 窗口句柄获取

    句柄获取方法(获取该窗口的句柄后,即可向该窗口类类发送消息.处理程序):0.获取所在类窗口的句柄: this->m_hwnd 1.主窗口的句柄: 无论在主窗口类内,还是子窗口类内,获取主窗口句柄 ...

  7. Ocr答题辅助神器 OcrAnswerer4.x,通过百度OCR识别手机文字,支持屏幕窗口截图和ADB安卓截图,支持四十个直播App,可保存题库

    http://www.cnblogs.com/Charltsing/p/OcrAnswerer.html 联系qq:564955427 最新版为v4.1版,开放一定概率的八窗口体验功能,请截图体验(多 ...

  8. VC++的窗口句柄和窗口ID

    原文地址:VC++的窗口句柄和窗口ID作者:放放 句柄是窗口资源的标识,它标识资源在系统中所占用的内存块,应用程序通过窗口句柄对窗口进行操作.除了窗口句柄之外,任何一种资源都有它自己的句柄,比如光标句 ...

  9. Selenium3 + Python3自动化测试系列十二——窗口截图与关闭浏览器

    窗口截图 自动化用例是由程序去执行的,因此有时候打印的错误信息并不十分明确.如果在脚本执行出错的时候能对当前窗口截图保存,那么通过图片就可以非常直观地看出出错的原因.WebDriver提供了截图函数g ...

随机推荐

  1. CGAL的demo运行的步骤

    首先使用CMake,找到demo的源文件目录,并且指定生成文件目录: 点击configur,done 点击generate,done 找到build目录中的.sln 文件,打开 ALL_BUILD 生 ...

  2. C# 动态操作 控件位置绑定 [ Anchor ] 属性

    注: 1.此类属于非常用类,只因本人需要编写的...顺便刷贴一下 2.对于初学,其中的枚举使用可以为你加深一点印象 以下为操作类代码: public class AchCtrer { #region ...

  3. 实验3 C语言分支语句和循环语句编程应用

    任务一 #include<math.h> #include<stdio.h> int main() { float a,b,c,x1,x2; float delta,real, ...

  4. FIRE2023:殁亡漫谈

    FIRE2023:殁亡漫谈 读书的时候,想到殁亡,脑海涌出一则喜欢的遗言: 钱花完了,我走了.签名 如果可能牵涉到旁人(比如殁在旅馆里),就再立一则: 我的殁与店家无关. 签名 然后放下Kindle, ...

  5. PHP 二维按照某个字段对数组排序

    function arraySort($arr, $keys, $type = 'asc') {//二维按照某个字段对数组排序 $keysvalue = $new_array = array(); f ...

  6. SQL中获取多条记录拼接成字符串

    declare @aa nvarchar(200) set @aa=(select STUFF((select ','+LTRIM(list.TempName1) from (select TempN ...

  7. What is UDS Service 0x10 - Diagnostic Session Control ?

    Why need the UDS Service 0x10? ECU在正常工作时会处于某一个会话模式下,上电后会自动进入默认会话模式,所以ECU启动后我们不需要输入0x10 01来进入该会话模式.EC ...

  8. SHELL-反弹shell

    什么是shell? 在我们深入了解发送和接收 shell 的复杂性之前,了解 shell 实际上是什么很重要.用最简单的术语来说,shell 就是我们在与命令行环境 (CLI) 交互时使用的工具.换句 ...

  9. java 中文繁简体转换工具 opencc4j 使用介绍 1.8.0

    Opencc4j Opencc4j 支持中文繁简体转换,考虑到词组级别. 在线体验 Features 特点 严格区分「一简对多繁」和「一简对多异」. 完全兼容异体字,可以实现动态替换. 严格审校一简对 ...

  10. 基于深度学习的智能PCB板缺陷检测系统(Python+清新界面+数据集)

    摘要:智能PCB板缺陷检测系统用于智能检测工业印刷电路板(PCB)常见缺陷,自动化标注.记录和保存缺陷位置和类型,以辅助电路板的质检.本文详细介绍智能PCB板缺陷检测系统,在介绍算法原理的同时,给出P ...