这个截图工具能实现最主要的截图功能,并保存为bmp图片。
编写环境是vs2005,使用Unicode,基于对话框。
没什么难度,直接看代码
项目名称为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); }