屏幕截图程序(WTL)

来源:互联网 发布:java if else同时执行 编辑:程序博客网 时间:2024/04/30 13:29

分类: 屏幕 截图WTL CMemoryDC 双缓存 248人阅读 评论(0)收藏 举报

如果需要思路,请访问:http://hi.baidu.com/sumos/item/9aef19f4f02e0f5ac9f337bb

如果需要程序,请访问:http://download.csdn.net/detail/zhoujielunzhimi/4724327

如果需要源码,请看:

[cpp] view plaincopy
  1. #pragma once  
  2. #include <atlimage.h>  
  3.   
  4. class MainForm;  
  5.   
  6. CBitmap bmp_srcreen;    //用来保存全屏图片  
  7. MainForm *mf_ptr = NULL;  
  8.   
  9. //截屏窗口  
  10. class ScreenForm : public CWindowImpl<ScreenForm>  
  11. {  
  12. public:  
  13.     ScreenForm() : is_lbutton_down(false){}  
  14. protected:  
  15.     BEGIN_MSG_MAP(ScreenForm)  
  16.         MSG_WM_CREATE(OnCreate)  
  17.         MESSAGE_HANDLER(WM_KEYDOWN,OnKeyDown)  
  18.         MSG_WM_RBUTTONDOWN(OnRButtonDown)  
  19.         MSG_WM_SETCURSOR(OnSetCursor)  
  20.         MSG_WM_LBUTTONDOWN(OnLButtonDown)  
  21.         MSG_WM_MOUSEMOVE(OnMouseMove)  
  22.         MSG_WM_LBUTTONUP(OnLButtonUp)  
  23.         MSG_WM_ERASEBKGND(OnEraseBkgnd)  
  24.         MSG_WM_PAINT(OnPaint)  
  25.     END_MSG_MAP()  
  26. protected:  
  27.     int OnCreate(LPCREATESTRUCT)  
  28.     {  
  29.         CRect rc(0,0,0,0);  
  30.         SetWindowPos(HWND_TOPMOST,&rc,SWP_NOMOVE|SWP_NOSIZE);   //置顶  
  31.         return 0;  
  32.     }  
  33.     LRESULT OnKeyDown(UINT,WPARAM wp,LPARAM,BOOL&)  
  34.     {  
  35.         if(wp == VK_LWIN || wp == VK_RWIN || VK_ESCAPE) //左WIN + 右WIN + ESC  
  36.             OnRButtonDown(0,CPoint(0,0));  
  37.         return 0;  
  38.     }  
  39.     void OnRButtonDown(UINT nFlags, CPoint point)  
  40.     {  
  41.         DestroyWindow();  
  42.         ((CWindowImpl*)mf_ptr)->ShowWindow(SW_SHOW);  
  43.     }  
  44.     BOOL OnSetCursor(CWindow wnd, UINT nHitTest, UINT message)  
  45.     {  
  46.         static CCursor cursor = AtlLoadCursor(IDC_CURSOR1);  //载入光标资源:十 字形状  
  47.         ::SetCursor(cursor);  
  48.         return TRUE;  
  49.     }  
  50.     void OnLButtonDown(UINT nFlags, CPoint point)  
  51.     {  
  52.         is_lbutton_down = true;  
  53.         pt_old = point;  
  54.     }  
  55.     void OnMouseMove(UINT nFlags, CPoint point)  
  56.     {  
  57.         pt_end = point;  
  58.         Invalidate();     
  59.     }  
  60.     void OnLButtonUp(UINT nFlags, CPoint point)  
  61.     {  
  62.         is_lbutton_down = false;  
  63.         int ret = MessageBox("复制到剪贴板(OK)或保存为PNG图片(CANCEL)?","ASK",MB_OKCANCEL|MB_ICONQUESTION);  
  64.           
  65.         CDC dc1,dc2;  
  66.         dc1.CreateCompatibleDC(NULL);  
  67.         dc1.SelectBitmap(bmp_srcreen);  
  68.         CRect rc(pt_old.x,pt_old.y,pt_end.x,pt_end.y);  
  69.         dc2.CreateCompatibleDC(dc1);  
  70.         CBitmap bmp;    //dc1选择了全屏图片,dc2选择了截图区域  
  71.         bmp.CreateCompatibleBitmap(dc1,rc.Width(),rc.Height());  
  72.         dc2.SelectBitmap(bmp);  
  73.         dc2.BitBlt(0,0,rc.Width(),rc.Height(),dc1,pt_old.x,pt_old.y,SRCCOPY);  
  74.         if(ret == IDOK)  
  75.         {  
  76.             if(OpenClipboard()) //复制到剪贴板  
  77.             {  
  78.                 ::EmptyClipboard();  
  79.                 ::SetClipboardData(CF_BITMAP,bmp);  
  80.                 ::CloseClipboard();  
  81.             }  
  82.         }  
  83.         else  
  84.         {  
  85.             CImage img;  
  86.             img.Attach(bmp);  
  87.             img.Save("catch.png");  //保存为png,因为保存为bmp图片太大了  
  88.             img.Detach();  
  89.         }  
  90.   
  91.         OnRButtonDown(0,CPoint(0,0));  
  92.     }  
  93.     BOOL OnEraseBkgnd(CDCHandle dc)  
  94.     {         
  95.         return TRUE;  
  96.     }  
  97.     void OnPaint(CDCHandle)  
  98.     {  
  99.         CPaintDC dc(m_hWnd);  
  100.   
  101.         CRect rc;  
  102.         GetClientRect(&rc);  
  103.   
  104.         CMemoryDC mem(dc,rc);   //WTL提供的双缓存,析构时自动绘制  
  105.   
  106.         CBrush br;  
  107.         br.CreateSolidBrush(RGB(255,255,255));  
  108.   
  109.         mem.FillRect(&rc,br);   //把窗口底色刷白  
  110.   
  111.         if(bmp_srcreen.IsNull())  
  112.             return;  
  113.   
  114.         CDC dcMem;  
  115.         dcMem.CreateCompatibleDC(mem);  
  116.         dcMem.SelectBitmap(bmp_srcreen);  
  117.   
  118.         BLENDFUNCTION bf;  
  119.         bf.AlphaFormat = 0;  
  120.         bf.BlendFlags = 0;  
  121.         bf.BlendOp = AC_SRC_OVER;  
  122.         bf.SourceConstantAlpha = 100;  
  123.         //绘制半透明的全屏图像,类似win7自带的截图软件  
  124.         mem.AlphaBlend(0,0,rc.Width(),rc.Height(),dcMem,0,0,rc.Width(),rc.Height(),bf);  
  125.   
  126.         if(is_lbutton_down)  
  127.         {  
  128.             CRect rc_catch(pt_old.x,pt_old.y,pt_end.x,pt_end.y);  
  129.             //不透明的显示选择区域图像  
  130.             mem.BitBlt(pt_old.x,pt_old.y,rc_catch.Width(),rc_catch.Height(),dcMem,pt_old.x,pt_old.y,SRCCOPY);  
  131.             mem.Draw3dRect(&rc_catch,RGB(255,0,0),RGB(0,0,255));  
  132.         }  
  133.     }  
  134. private:  
  135.     CPoint pt_old;  
  136.     CPoint pt_end;  
  137.     bool is_lbutton_down;     
  138. };  
  139.   
  140. //主窗口  
  141. class MainForm : public CWindowImpl<MainForm>  
  142. {  
  143. protected:  
  144.     BEGIN_MSG_MAP(MainForm)  
  145.         MSG_WM_CLOSE(OnClose)  
  146.         MSG_WM_ERASEBKGND(OnEraseBkgnd)  
  147.         COMMAND_CODE_HANDLER(BN_CLICKED,OnClick)  
  148.     END_MSG_MAP()  
  149. protected:  
  150.     void OnClose()  
  151.     {  
  152.         DestroyWindow();  
  153.         ::PostMessage(NULL,WM_QUIT,0,0);  
  154.     }  
  155.     BOOL OnEraseBkgnd(CDCHandle dc)  //这不过是为主窗口加个背景图罢了  
  156.     {  
  157.         CRect rc;  
  158.         GetClientRect(&rc);  
  159.         CBitmap bk;  
  160.         bk.LoadBitmap(IDB_BITMAP1);  
  161.         CDC mem;  
  162.         mem.CreateCompatibleDC(dc);  
  163.         mem.SelectBitmap(bk);  
  164.         BITMAP bkInf;  
  165.         bk.GetBitmap(&bkInf);  
  166.         dc.StretchBlt(0,0,rc.Width(),rc.Height(),mem,0,0,bkInf.bmWidth,bkInf.bmHeight,SRCCOPY);  
  167.         return TRUE;  
  168.     }  
  169.     LRESULT OnClick(WORD,WORD id,HWND,BOOL&)  
  170.     {  
  171.         CRect rc;  
  172.         switch(id)  
  173.         {  
  174.         case IDC_CREATE :  
  175.             ShowWindow(SW_HIDE);  
  176.             Sleep(300);     //需要等待一下,否则会把主窗口图像也捕捉下来  
  177.             {  
  178.                 //捕捉屏幕  
  179.                 CRect rcDesk;  
  180.                 CWindow wndDesk = ::GetDesktopWindow();  
  181.                 wndDesk.GetClientRect(&rcDesk);  
  182.                 rc = rcDesk;  
  183.                 CDCHandle dcDesk = wndDesk.GetDC();  
  184.                 CDC dcMem;  
  185.                 dcMem.CreateCompatibleDC(dcDesk);  
  186.                 if(bmp_srcreen.IsNull() == FALSE)  
  187.                     bmp_srcreen.DeleteObject();  
  188.                 bmp_srcreen.CreateCompatibleBitmap(dcDesk,rcDesk.Width(),rcDesk.Height());  
  189.                 dcMem.SelectBitmap(bmp_srcreen);  
  190.                 dcMem.BitBlt(0,0,rcDesk.Width(),rcDesk.Height(),dcDesk,0,0,SRCCOPY);  
  191.                 wndDesk.ReleaseDC(dcDesk);  
  192.             }  
  193.             sf.Create(m_hWnd,rc,NULL,WS_VISIBLE|WS_POPUP);  
  194.             break;  
  195.         default:  
  196.             break;  
  197.         }  
  198.         return 0;  
  199.     }  
  200. public:  
  201.     void InitForm()  
  202.     {  
  203.         font_btn.CreatePointFont(110,"宋体");  
  204.         // 400 * 300  
  205.         btn_create.Create(m_hWnd,CRect(20,10,120,40),"新建",WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON,0,IDC_CREATE);  
  206.         btn_create.SetFont(font_btn);  
  207.     }  
  208. private:  
  209.     CButton btn_create;       
  210.     CFont font_btn;  
  211.     ScreenForm sf;  
  212.   
  213.     enum { IDC_CREATE = 10001 };  
  214. };  

截图中:背景是半透明,选中区域是不透明。



原创粉丝点击