• MFC 之 截图工具


    这个截图工具能实现最主要的截图功能,并保存为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);
    }
    



  • 相关阅读:
    UVALive 5983 MAGRID DP
    2015暑假训练(UVALive 5983
    poj 1426 Find The Multiple (BFS)
    poj 3126 Prime Path (BFS)
    poj 2251 Dungeon Master 3维bfs(水水)
    poj 3278 catch that cow BFS(基础水)
    poj3083 Children of the Candy Corn BFS&&DFS
    BZOJ1878: [SDOI2009]HH的项链 (离线查询+树状数组)
    洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)
    洛谷P3065 [USACO12DEC]第一!First!(Trie树+拓扑排序)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/3885621.html
Copyright © 2020-2023  润新知