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

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

先创建一个测试窗口程序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. 虚拟机文件丢失,虚拟机无法启动,通过xx-flat.vmdk和xx-delta.vmdk恢复虚拟机

    突然掉电,导致虚拟机文件夹里面的文件丢失,只剩余-flat.vmdk和-delta.vmdk文件,其他文件全部丢失,文件格式原本为"文件"格式.新建虚拟机无法直接使用此文件夹里面的 ...

  2. redis linux源码安装

    1.官网下载安装包 2.解压 3.确认GCC环境 4.make 5.修改conf配置文件守护进程daemonize yes和默认密码requirepass password 5.启动 安装目录src/ ...

  3. verilog 概念版

    一.MCU芯片的定义 MCU芯片是指微控制单元(MicrocontrollerUnit:MCU),又称单片微型计算机或者单片机,是把中央处理器的频率与规格做适当缩减,并将内存.计数器.USB.A/D转 ...

  4. 关于Windows10纯净启动的相关修改流程

    关于纯净启动的相关流程 自动登录 打开命令提示符运行control userpasswords2后回车 在弹出的用户账户窗口中,取消勾选"要使用本计算机,用户必须输入用户名和密码" ...

  5. syn flood

    from scapy.all import * import random # 生成随机的IP def randomIP(): ip = ".".join(map(str, (ra ...

  6. 狂神说SpringBoot笔记之编写一个http接口

    编写一个http接口 1.1.在主程序的同级目录下,新建一个controller包,一定要在同级目录下,否则识别不到 2.代码 1 package com.example.app01.demo.api ...

  7. 什么是RPA?

    RPA是Robotic Process Automation(机器人流程自动化)的简称,是以软件机器人及人工智能为基础的业务过程自动化科技.它让软件机器人自动处理大量重复的.基于规则的工作流程任务,能 ...

  8. 针对于Sql server突然连接不到服务器的解决方法

    问题叙述 点击连接之后,总是会弹出一个错误弹窗: 方法解决 快捷键Win+R,输入services.msc,进入到服务界面: 找到SQL 代理(DEV) 将手动打开改成自动 再连接试一次 连上啦! ( ...

  9. 跳出思维的“盒子”,聊聊 RTE 应用创新大赛的那些作品

    由声网Agora 与环信联合主办的"RTE 2021 编程挑战赛"已圆满落幕.在今年的大赛中,来自行业中不同领域的专家参与了决赛评选,包括 Linux 中国技术社区技术负责人 白宦 ...

  10. C#多线程开发-处理异步操作中的异常

    C#多线程开发-处理子线程中的异常 在平时的多线程开发中,对于异常的处理是至关重要的,千万不能马虎.如果在实际的项目中,对于某些线程中的异常没有处理,会直接导致整个程序崩溃,软件无法使用. 其中需要说 ...