• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    屏幕抓圖程序DIY

    發布: 2007-7-14 21:11 | 作者: 佚名    | 來源: 網絡轉載     | 查看: 99次 | 進入軟件測試論壇討論

    領測軟件測試網 屏幕抓圖程序的關鍵有兩點:一是應該知道鼠標在屏幕上有準確位置;二是應該知道欲抓圖的窗口句柄;三是如何對抓到的圖片進行保存的問題。對于問題一,很簡單,利用SetCapture函數便能夠追蹤鼠標的移動(包括在屏幕抓圖程序窗口之外的窗口)。應該注意的是,SetCapture的具體功能并不像MSDN中所說的那樣:調用SetCapture一次直到使用ReleaseCapture終止鼠標捕獲前都會起到對鼠標的捕獲作用,實際上,在使用過程中,你會發現,在進行了一次鼠標捕獲之后,SetCapture便失去了作用,這可能是SetCapture函數的一個Bug。所以,在編程時,最好能夠不斷地調用SetCapture函數,以保證SetCapture能夠對鼠標進行正確無誤的捕獲。對于問題二,這時會用到一個平時我們不常用的函數:WindowFromPoint,這個函數能夠找出鼠標當前位置所對應的窗口句柄。具體用法可以參見MSDN,這里不做詳細敘述。同時,用過SnagIT有朋友都知道,在選擇抓圖窗口時,鼠標的在位置的窗口都會出現加粗的紅色邊框(如圖一所示),以提醒目前所選擇的窗口,這個功能實現起來有些復雜,下面仔細來看看詳細說明。

    在GDI中,最常見的一個概念就設備環境(DC),每一個窗口都相應的具有自己的DC。如果能夠調用到窗口的DC,那么,我們便能夠在窗口上的任何位置繪圖。然而,在屏幕抓圖程序中,由于用戶所選擇的窗口是不固定的,所以,要想得到鼠標所在處的窗口的DC,不是很容易。能不能夠隨心所欲地在屏幕上進行繪圖但又不僅限于特定的窗口?可以,別忘了,GetDC能夠做到這點!GetDC我們都用得太多了,都快習慣了GetDC的函數申明:HDC GetDC( HWND hWnd),hWnd是DC對應的窗口句柄,當hWnd為空的,該函數返回的是整個屏幕的設備環境句柄!這就意味著我們可以在屏幕上進行任意繪圖。在鼠標所在處的窗口進行繪圖時,繪圖本身的目只是為了提醒用戶目前所選擇的窗口,所以,在進行繪圖時,必須得保證不會破壞窗口原有的畫面。這點很好辦,將窗口的DC繪圖模式設為R2_NOTXORPEN(將畫筆顏色與屏幕顏色進行異或后,再將屏幕顏取反),這樣,在同一個地方進行兩次繪圖后(對同一像素進行兩次異或運算,像素值并不會發生變化),窗口的畫面并不會發生任何變化!
    從上面的說明可以看出,制作屏幕抓圖程序應分三步走:
    1、 啟用鼠標捕獲
    2、 在鼠標所在處的窗口進行繪圖,提醒抓圖的目標
    3、 選定目標窗口時,將目標窗口的畫面保存為自定義的位圖(在本文中,我將畫面保存至剪貼板上),并終止鼠標捕獲
    下面我們就按照上面的思路進行編程操作。首先新建一個基于對話框的項目ScreenCapture,然后準備好一個外形為相機的光標文件(*.cur),將之引入資源管理器(IDC_CAMERA)。接著在CscreenCaptureDlg類中加入兩個全局變量:
    HWND hwndCapture;
    CRect rectCapture;


    然后通過類向導加入對WM_MOUSEMOVE及WM_LBUTTONUP事件的響應函數,基響應函數代碼如下:
    void CScreenCaptureDlg::OnMouseMove(UINT nFlags, CPoint point)  
    {  

    //如果用戶將鼠標左鍵按住不放,則開始抓取圖片
    if(nFlags==MK_LBUTTON)
    {
    //隱藏程序窗口,以免影響在抓取時的“視野”
    ShowWindow(SW_HIDE);
    //裝入“照相機”鼠標,開始追蹤鼠標的移動
    HCURSOR cur=LoadCursor(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDC_CAMERA ));
    SetCursor(cur);
    SetCapture();
    //獲得鼠標所在處的窗口句柄
    ClientToScreen(&point);
    hwndCapture=(HWND)::WindowFromPoint(point);
    //取得屏幕的設備環境句柄,以便在屏幕的任何位置繪圖
    HDC hDC=::GetDC(NULL);
    //建立一紅色的畫筆
    HPEN hPen =CreatePen(PS_INSIDEFRAME,6, RGB(255,0,0));
    //將繪圖模式設為R2_NOTXORPEN,在繪圖時可以不破壞原有的背景
    int nMode =SetROP2(hDC, R2_NOTXORPEN);
    HPEN hpenOld= (HPEN)SelectObject(hDC, hPen);
    //得到鼠標所在處的窗口的區域
    ::GetWindowRect(hwndCapture,&rectCapture);
    //在鼠標所在處的窗口四周畫一紅色的矩形,做為選定時的提醒
    POINT pt[5];
    pt[0] = CPoint(rectCapture.left, rectCapture.top);
    pt[1] = CPoint(rectCapture.right,rectCapture.top);
    pt[2] = CPoint(rectCapture.right,rectCapture.bottom);
    pt[3] = CPoint(rectCapture.left, rectCapture.bottom);
    pt[4] = CPoint(rectCapture.left, rectCapture.top);

    ::Polyline(hDC,pt,5);  
    //延時后再重繪紅色的矩形,這樣就不會破壞原有內容
    Sleep(100);
    ::Polyline(hDC,pt,5);
    ::SelectObject(hDC,hpenOld);
    ::ReleaseDC(NULL,hDC);

    }


    CDialog::OnMouseMove(nFlags, point);
    }

    void CScreenCaptureDlg::OnLButtonUp(UINT nFlags, CPoint point)  

    {  
    //得到鼠標所在處的窗口的區域寬、高  
    int nWidth=rectCapture.Width();
    int nHeight=rectCapture.Height();
    HDC hdcScreen, hMemDC;  
    HBITMAP hBitmap, hOldBitmap;  
    //建立一個屏幕設備環境句柄
    hdcScreen = CreateDC("DISPLAY", NULL, NULL, NULL);
    hMemDC = CreateCompatibleDC(hdcScreen);
    //建立一個與屏幕設備環境句柄兼容、與鼠標所在處的窗口的區域等大的位圖
    hBitmap = CreateCompatibleBitmap(hdcScreen, nWidth, nHeight);
    // 把新位圖選到內存設備描述表中
    hOldBitmap =(HBITMAP)SelectObject(hMemDC, hBitmap);
    // 把屏幕設備描述表拷貝到內存設備描述表中
    BitBlt(hMemDC, 0, 0, nWidth, nHeight, hdcScreen,rectCapture.left,rectCapture.top,SRCCOPY);
    //取回鼠標所在處的窗口屏幕位圖的句柄
    hBitmap =(HBITMAP)SelectObject(hMemDC, hOldBitmap);
    DeleteDC(hdcScreen);
    DeleteDC(hMemDC);

    // 返回位圖句柄
    //打開剪貼板,并將位圖拷到剪貼板上
    OpenClipboard() ;
    EmptyClipboard();
    SetClipboardData(CF_BITMAP, hBitmap);
    //關閉剪貼板
    CloseClipboard();

    MessageBox("屏幕內容已經拷到剪貼板上!");
    //終止鼠標捕獲
    ReleaseCapture();
    //恢復窗口顯示模式
    ShowWindow(SW_NORMAL);

    }
    說明:在本程序中,如果用戶在對話框中按住鼠標左鍵不放,那么,程序便開始“抓圖”,當選擇好抓圖的目標后,松開鼠標左鍵,這時,抓圖的目標窗口的畫面就自動保存至剪貼板中了。如果你想將位置保存到一個BMP文件,你可以到http://www.cideguru.com中查找具體文檔。
    瞧,屏幕抓圖程序的制作是不是良簡單?你也可以對該程序進行改良,加入個性化的界面或功能,我想其運用效果并比會比專業的屏幕抓圖程序差。在我的主頁 “國稅之家”(http://nationaltax.home.chinaren.com)的“個人世界”中,就有一個做好的屏幕抓圖程序,試一試?

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備10010545號-5
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>