关于屏幕截取

有时候需要将一个窗口实时截取出窗口画面,常用的

BitBlt

可以将源设备区域像素拷贝到目标区域,而在窗口挡住或者隐藏的情况下就无能为力了,这个时候可以用

PrintWindow

不论是窗口被隐藏,或者被挡住都能截出想要的区域

示例: 

    IntPtr hscrdc = GetWindowDC(hWnd);
              Control control = Control.FromHandle(hWnd);
              IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, control.Width, control.Height);
              IntPtr hmemdc = CreateCompatibleDC(hscrdc);
              SelectObject(hmemdc, hbitmap);
              bool re= PrintWindow(hWnd, hmemdc, 0);
              Bitmap bmp = null;
              if(re)
              {
                 bmp = Bitmap.FromHbitmap(hbitmap);                  
              }

更进一步,如果需要截一张两个窗口贴在一个资源窗口上的情况又当如何呢?当窗口都隐藏时又当如何呢?

这个时候思路如下:

1.用窗口DC创建两个内存兼容DC,使用CreateCompatibleDC;

2.创建两个位图,使用CreateCompatibleBitmap,分别定向到这两个内存DC,使用selectbitmap;

3.BitBlt到两个兼容DC的位图上,如果窗口隐藏、遮挡则使用PrintWindow,将窗口绘到重定向的DC的位图上;

4.如果需要将一个窗口覆盖住另一个窗口的一部分,则使用StretchBlt将一个DC上的区域贴到另一个DC上即可。

重点:

StretchBlt需要在PrintWindow之后调用,否则由于PrintWindow最终使用WM_PAINT可能会在刷新窗口时将已经贴在上边的部分刷没掉。

涉及到的DC和位图较多,不能用错。

原文地址:https://www.cnblogs.com/ice-arrow/p/11981046.html