国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

C#中三種截屏方式總結(jié)

2019-11-17 04:20:49
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

昨天寫(xiě)自動(dòng)化測(cè)試的CASE的時(shí)候,碰到一個(gè)疑難雜癥,調(diào)用截圖的函數(shù)去截取一個(gè)Popup窗口,但是總是把背景程序給截下來(lái),Popup窗口就跟看不到一樣。本來(lái)以為是同步的問(wèn)題,也就是以為先截圖再點(diǎn)擊彈出Popup窗口了。后來(lái)加了N個(gè)Thread.Sleep來(lái)測(cè)試,發(fā)現(xiàn)根本不是因?yàn)檫@個(gè)原因,而是截圖的函數(shù)截不下來(lái)這個(gè)窗口。

這個(gè)為啥呢,只好把截圖的函數(shù)代碼翻出來(lái)看,以前是用這種方式的:
BitBlt(dcImage, 0, 0, (int)(rect.Width), (int)(rect.Height), dcScreen, (int)(rect.Left), (int)(rect.Top), TernaryRasterOperations.SRCCOPY);

憑直覺(jué)感覺(jué)應(yīng)該是因?yàn)檫@種通過(guò)DC的方式對(duì)WPF程序支持有問(wèn)題,但是又覺(jué)得奇怪就是截取其它的WPF組件和窗口都沒(méi)有問(wèn)題,偏偏Popup窗口不行。

前些天聽(tīng)說(shuō)另外一種截屏的方法,這種方法連被遮擋的窗口都可以截,于是就Google一大把,找打了PRintWindow函數(shù),于是就有了第二種解決方案,代碼如下:

IntPtr hdc = Native.GetWindowDC(this.Handle);
if (hdc != IntPtr.Zero)
{
    IntPtr hdcMem = Native.CreateCompatibleDC(hdc);
    if (hdcMem != IntPtr.Zero)
    {
        IntPtr hbitmap = Native.CreateCompatibleBitmap(hdc, (int)(Rect.Width), (int)(Rect.Height));
        if (hbitmap != IntPtr.Zero)
        {
            Native.SelectObject(hdcMem, hbitmap);
            Native.PrintWindow(this.Handle, hdcMem, 0);

            Native.DeleteObject(hbitmap);
            Bitmap bmp = Bitmap.FromHbitmap(hbitmap);
            bmp.Save(sPath);
       }
        Native.DeleteObject(hdcMem);
    }
    Native.ReleaseDC(this.Handle, hdc);
}

就是拿到窗口的句柄,通過(guò)PrintWindow API來(lái)截取窗口。

但是更讓人氣憤的事情出現(xiàn)了,截出來(lái)的窗口中,只要是用到WPF組件的地方,全部是黑塊兒,只有MFC的窗口框架和按鈕可以正常被截取。

于是乎,就無(wú)奈的繼續(xù)分析這個(gè)問(wèn)題,我記得WPF是沒(méi)有走GDI,而是通過(guò)Directx渲染的,那就是說(shuō)DC的方式和PrintWindow的方式都不靠譜,但是截Directx的貌似還比較復(fù)雜。

突然想起來(lái),平常報(bào)bug的時(shí)候都是按PrintScreen,然后再處理一下的,那應(yīng)該P(yáng)rintScreen按鍵是管用的,看來(lái)只能曲線救國(guó)了。但是那樣就得走剪切板了,貌似會(huì)破壞剪切板的數(shù)據(jù),不過(guò)如果我在截取前保存一下數(shù)據(jù),在截取后再恢復(fù)一下剪切板數(shù)據(jù),那就沒(méi)有問(wèn)題了。

于是就有了第三種解決方案(暫時(shí)還沒(méi)有加恢復(fù)剪切板數(shù)據(jù)的代碼):

const uint KEYEVENTF_EXTENDEDKEY = 0x1;
const uint KEYEVENTF_KEYUP = 0x2;
const byte VK_SNAPSHOT = 0x2C;
Native.keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY, UIntPtr.Zero);
Native.keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, UIntPtr.Zero);

IDataObject iObj = Clipboard.GetDataObject();
if (iObj.GetDataPresent(DataFormats.Bitmap, true))
{
    Bitmap bmpScreen = iObj.GetData(DataFormats.Bitmap, true) as Bitmap;
    Bitmap bmpOutput = new Bitmap((int)this.Rect.Width, (int)this.Rect.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
    Graphics g = Graphics.FromImage(bmpOutput);
    Rectangle destRectangle = new Rectangle(0, 0, (int)this.Rect.Width, (int)this.Rect.Height);
    g.DrawImage(bmpScreen,destRectangle,  (int)this.Rect.X, (int)this.Rect.Y, (int)this.Rect.Width, (int)this.Rect.Height, GraphicsUnit.Pixel);
    bmpOutput.Save(sPath, System.Drawing.Imaging.ImageFormat.Bmp);
}

測(cè)試可用,只好先用著了

不過(guò)還有幾個(gè)問(wèn)題,先寫(xiě)下來(lái),留待以后解決:

1. 針對(duì)第三種方案,既然可以按PrintScreen鍵截圖,那對(duì)應(yīng)的API是什么,總覺(jué)得發(fā)鍵盤(pán)消息沒(méi)有直接調(diào)API穩(wěn)定

2. 針對(duì)WPF截圖有沒(méi)有更好的解決方案


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 屏南县| 温泉县| 枣阳市| 台南市| 崇义县| 定结县| 乳源| 安化县| 佳木斯市| 阆中市| 巩留县| 墨玉县| 观塘区| 富蕴县| 大化| 龙山县| 横峰县| 依安县| 乌兰察布市| 千阳县| 安仁县| 寿阳县| 普兰店市| 鞍山市| 南平市| 宁晋县| 六枝特区| 如皋市| 崇州市| 麦盖提县| 无极县| 陕西省| 建始县| 尼勒克县| 通海县| 永登县| 静安区| 霞浦县| 霍邱县| 阿坝县| 威海市|