這個截圖工具能實現最主要的截圖功能,並保存爲bmp圖片。框架
編寫環境是vs2005,使用Unicode,基於對話框。ide
沒什麼難度,直接看代碼函數
項目名稱爲CutOut
工具
// CutOutDlg.h : 頭文件 // #pragma once #include <atlimage.h> // CCutOutDlg 對話框 class CCutOutDlg : public CDialog { // 構造 public: CCutOutDlg(CWnd* pParent = NULL); // 標準構造函數 // 對話框數據 enum { IDD = IDD_CUTOUT_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 實現 protected: HICON m_hIcon; // 生成的消息映射函數 virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() private: CDC m_DC; CBitmap m_bDeskTopBitmap; int m_x; int m_y; afx_msg void OnLButtonDown(UINT nFlags, CPoint point); POINT m_StartPt; POINT m_EndPt; CRectTracker m_rectTracker; afx_msg void OnRButtonDown(UINT nFlags, CPoint point); afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); CBitmap m_bSaveBitmap; afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); };
// CutOutDlg.cpp : 實現文件 // #include "stdafx.h" #include "CutOut.h" #include "CutOutDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // 用於應用程序「關於」菜單項的 CAboutDlg 對話框 class CAboutDlg : public CDialog { public: CAboutDlg(); // 對話框數據 enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 實現 protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() // CCutOutDlg 對話框 CCutOutDlg::CCutOutDlg(CWnd* pParent /*=NULL*/) : CDialog(CCutOutDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); //橡皮筋默認位置 //m_rectTracker.m_rect = CRect(200,200,400,400); //初始化橡皮筋的style m_rectTracker.m_nStyle = CRectTracker::solidLine|CRectTracker::resizeOutside; } void CCutOutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CCutOutDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_WM_LBUTTONDOWN() ON_WM_RBUTTONDOWN() ON_WM_SETCURSOR() ON_WM_LBUTTONDBLCLK() ON_WM_LBUTTONUP() END_MESSAGE_MAP() // CCutOutDlg 消息處理程序 BOOL CCutOutDlg::OnInitDialog() { CDialog::OnInitDialog(); // 將「關於...」菜單項加入到系統菜單中。 // IDM_ABOUTBOX 必須在系統命令範圍內。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 設置此對話框的圖標。當應用程序主窗體不是對話框時,框架將本身主動 // 運行此操做 SetIcon(m_hIcon, TRUE); // 設置大圖標 SetIcon(m_hIcon, FALSE); // 設置小圖標 // TODO: 在此加入額外的初始化代碼 ////////////////////////////////////////////////////////////////////////// //得到整個屏幕的大小 m_x = GetSystemMetrics(SM_CXSCREEN); m_y = GetSystemMetrics(SM_CYSCREEN); //以當前桌面窗體建立一個DC CClientDC dc(GetDesktopWindow()); //建立一個兼容桌面窗體的dc並關聯bitmap m_DC.CreateCompatibleDC(&dc); m_bDeskTopBitmap.CreateCompatibleBitmap(&dc,m_x,m_y); m_DC.SelectObject(&m_bDeskTopBitmap); //講窗體dc內容傳輸到應用程序的dc m_DC.BitBlt(0,0,m_x,m_y,&dc,0,0,SRCCOPY); //窗體最大化顯示 ShowWindow(SW_SHOWMAXIMIZED); return TRUE; // 除非將焦點設置到控件,不然返回 TRUE } void CCutOutDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // 假設向對話框加入最小化button,則需要如下的代碼 // 來繪製該圖標。對於使用文檔/視圖模型的 MFC 應用程序, // 這將由框架本身主動完畢。 void CCutOutDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用於繪製的設備上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使圖標在工做矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 繪製圖標 dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } ////////////////////////////////////////////////////////////////////////// //每次重繪都顯示應用程序窗體出現以前截到的窗體 CClientDC dc(this); dc.BitBlt(0,0,m_x,m_y,&m_DC,0,0,SRCCOPY); //顯示橡皮筋 m_rectTracker.Draw(&dc); } //當用戶拖動最小化窗體時系統調用此函數取得光標顯示。 // HCURSOR CCutOutDlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon); } void CCutOutDlg::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此加入消息處理程序代碼和/或調用默認值 m_StartPt = point; m_rectTracker.Track(this,m_StartPt,TRUE); Invalidate(); CDialog::OnLButtonDown(nFlags, point); } void CCutOutDlg::OnRButtonDown(UINT nFlags, CPoint point) { // TODO: 在此加入消息處理程序代碼和/或調用默認值 //右鍵按下,獲取橡皮筋圈住的區域,並傳輸到窗體左上角,實現預覽 CClientDC dc(this); CRect re(m_rectTracker.m_rect); dc.BitBlt(0,0,re.Width(),re.Height(),&dc,re.left,re.top,SRCCOPY); CDialog::OnRButtonDown(nFlags, point); } BOOL CCutOutDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { // TODO: 在此加入消息處理程序代碼和/或調用默認值 //設置鼠標的圖標 if (m_rectTracker.SetCursor(this,nHitTest)) { return FALSE; } //不在橡皮筋內部及邊界就顯示默認的箭頭 return CDialog::OnSetCursor(pWnd, nHitTest, message); } void CCutOutDlg::OnLButtonDblClk(UINT nFlags, CPoint point) { // TODO: 在此加入消息處理程序代碼和/或調用默認值 //右鍵雙擊橡皮筋內部,保存圖片 if (m_rectTracker.m_rect.PtInRect(point)) { //保存橡皮筋圈住的區域到內存dc CClientDC dc(this); CRect re(m_rectTracker.m_rect); m_bSaveBitmap.CreateCompatibleBitmap(&dc,re.Width(),re.Height()); CDC tempDc; tempDc.CreateCompatibleDC(&dc); tempDc.SelectObject(&m_bSaveBitmap); tempDc.BitBlt(0,0,re.Width(),re.Height(),&dc,re.left,re.top,SRCCOPY); //彈出一個對話框,保存爲bmp格式 CFileDialog fDlg(FALSE,_T("bmp"),NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,_T("*.bmp"),this); if (fDlg.DoModal()==IDOK) { CString bmpfile = fDlg.GetPathName(); //用CImage保存圖片 ATL::CImage img; img.Attach(m_bSaveBitmap); img.Save(bmpfile); img.Detach(); //截圖後退出程序 PostQuitMessage(0); } } CDialog::OnLButtonDblClk(nFlags, point); } void CCutOutDlg::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: 在此加入消息處理程序代碼和/或調用默認值 //左鍵按下獲取座標,實現拖拽鼠標畫框 m_EndPt = point; m_rectTracker.m_rect = CRect(m_StartPt,m_EndPt); Invalidate(); CDialog::OnLButtonUp(nFlags, point); }