截图工具

//调用
 CSnapScreen snap(this);
    snap.SetTipBackground(::LoadBitmap(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDB_TIPBG)), CRect(12, 32, 12, 12));
    snap.SetTipText(
        STRING(IDS_SNAP_INTRODUCIONT1, "按下鼠标左键并拖动选择截取范围。\n\n按下[ESC]或鼠标右键退出。")
        , STRING(IDS_SNAP_INTRODUCIONT2, "使用活动矩形调整截取范围。\n\n按下[ENTER]或双击选择区域内部确定截取。\n\n按下[ESC]或鼠标右键重新选取。"));
    snap.SetSizeInfoPattern(STRING(IDS_SIZEINFO, "起点坐标: %d, %d\n选取尺寸: %d x %d"));
    snap.SetColors(RGB(0, 128, 255), RGB(0, 0, 0), RGB(0, 128, 255));

    ServicePTR<IMainView> pMainView(m_pContext, UC_SERVICE_MAINVIEW);
    if (pMainView.get())
    {
        pMainView->SetIsCapture(TRUE);
    }

    // 获取截图
    HBITMAP hBmp = snap.Snap();
    if (pMainView.get())
    {
        pMainView->SetIsCapture(FALSE);
    }
    if (hBmp == NULL)
    {
        m_RichEditInput.SetFocus();
        return;
    }

    // 点对点
    if (m_pChatSession != NULL && m_pChatSession->GetType() != IChatSession::ST_TEAM)
    {
            m_RichEditInput.InsertBitmap(-1, hBmp);
    }

      // 将图片保存到剪切板
      HWND hWnd = GetSafeHwnd(); // 获取安全窗口句柄
      ::OpenClipboard(hWnd); // 打开剪贴板
      ::EmptyClipboard(); // 清空剪贴板
      ::SetClipboardData(CF_BITMAP, hBmp); // 将内存中的数据放置到剪贴板
      ::CloseClipboard(); // 关闭剪贴板

    // 清空资源
    ::DeleteObject(hBmp);
    hBmp = NULL;

    m_RichEditInput.SetFocus();












// 内容摘要:截屏控制类

#pragma once

#include "SnapScreenWnd.h"

/// <summary>

/// 类名称:CSnapScreen
/// 内容摘要:截屏控制类

/// </summary>
class CSnapScreen
{
public:
      // 构造函数
    CSnapScreen(CWnd* pParentWnd = NULL);
      // 析构函数
    virtual ~CSnapScreen();

      // 截取屏幕图片
    HBITMAP Snap(BOOL bFullScreen = FALSE);

      /// <summary>
      /// 设置提示背景
      /// </summary>
      /// <remarks>
      /// 实现流程:
      ///     1、设置提示背景
      /// </remarks>
      /// <param name="hBitmap">位图句柄</param>
      /// <param name="rcMargin">边界区域</param>
      /// <returns>返回:无
      /// </returns>
    inline void SetTipBackground(HBITMAP hBitmap, LPRECT rcMargin)
    {
        m_wndSnap.SetTipBackground(hBitmap, rcMargin);
    }

      /// <summary>
      /// 设置提示文本
      /// </summary>
      /// <remarks>
      /// 实现流程:
      ///     1、设置提示文本
      /// </remarks>
      /// <param name="lpTipText1">提示文本</param>
      /// <param name="lpTipText2">提示文本</param>
      /// <returns>返回:无
      /// </returns>
    inline void SetTipText(LPCTSTR lpTipText1, LPCTSTR lpTipText2)
    {
        m_wndSnap.SetTipText(lpTipText1, lpTipText2);
    }

      /// <summary>
      /// 设置大小信息式样
      /// </summary>
      /// <remarks>
      /// 实现流程:
      ///     1、设置大小信息式样
      /// </remarks>
      /// <param name="lpSizeInfoPattern">大小信息式样</param>
      /// <returns>返回:无
      /// </returns>
    inline void SetSizeInfoPattern(LPCTSTR lpSizeInfoPattern)
    {
        m_wndSnap.SetSizeInfoPattern(lpSizeInfoPattern);
    }

      /// <summary>
      /// 设置颜色
      /// </summary>
      /// <remarks>
      /// 实现流程:
      ///     1、设置颜色
      /// </remarks>
      /// <param name="clrTracker">追踪者颜色</param>
      /// <param name="clrTipText">提示文本颜色</param>
      /// <param name="clrSizeInfo">大小信息颜色</param>
      /// <returns>返回:无
      /// </returns>
    inline void SetColors(COLORREF clrTracker, COLORREF clrTipText, COLORREF clrSizeInfo)
    {
        m_wndSnap.SetColors(clrTracker, clrTipText, clrSizeInfo);
    }

protected:
      // 截屏窗口类对象
    CSnapScreenWnd m_wndSnap;
};



// 内容摘要:截屏窗口类
#pragma once

#include "SnapTracker.h"
#include "ModalWnd.h"
#include "DrawAssist.h"


/// <summary>
/// 类编号:
/// 类名称:CSnapScreenWnd
/// 内容摘要:截屏窗口类

/// </summary>
class CSnapScreenWnd : public CModalWnd
{
      DECLARE_DYNAMIC(CSnapScreenWnd)

public:
      // 构造函数
      CSnapScreenWnd(CWnd* pParentWnd = NULL);
      // 析构函数
      virtual ~CSnapScreenWnd();

    // 设置提示背景
    void SetTipBackground(HBITMAP hBitmap, LPRECT rcMargin);
      // 设置提示文本
    void SetTipText(LPCTSTR lpTipText1, LPCTSTR lpTipText2);
      // 设置大小信息式样
    void SetSizeInfoPattern(LPCTSTR lpSizeInfoPattern);
      // 设置颜色
    void SetColors(COLORREF clrTracker, COLORREF clrTipText, COLORREF clrSizeInfo);

      // 截取屏幕转化为位图
    static HBITMAP CopyScreenToBitmap(LPRECT lpRect = NULL);
      // 截取屏幕
    HBITMAP SnapScreen();

    // 使图片变暗
    HBITMAP FadeBitmap(HBITMAP hBmp, int nTrans);
    void DrawSelectArea(CBufferDC& dc);


protected:
    HBITMAP m_hResult;          // 截取的图像

    CBitmap m_bmpTipBg;         // 操作提示背景
    CRect   m_rcTipMargin;      // 操作提示文字位置
    CString m_csTipText1;       // 操作提示
    CString m_csTipText2;       // 操作提示
    CString m_csSizeInfoPatt;   // 尺寸信息
    COLORREF m_clrTipText;      // 操作提示文字颜色
    COLORREF m_clrSizeInfo;     // 尺寸信息颜色

    HBITMAP m_hScreenBmp;       // 屏幕图像
    HBITMAP m_hBackground;      // 背景图像
    int     m_nScreenX;         // 屏幕宽度
    int     m_nScreenY;         // 屏幕高度

    BOOL    m_bDragged;         // 已经进行拖动操作
    BOOL    m_bDragging;        // 正在拖动
    BOOL    m_bShowSizeInfo;    // 显示尺寸信息
    BOOL    m_bShowZoomer;      // 显示放大镜
    CPoint  m_ptStart;              // 截取矩形左上角
    CRect   m_rcTip;            // 操作提示位置
    BOOL    m_bSizing;          // 是否在拖动大小

    CSnapTracker m_tracker;     // 橡皮筋类

    BOOL    m_bMoveArea;        // 是否移动选择区
    CPoint  m_ptStartMove;
    CRect   m_rcGragging;       // 拖动前的矩形区
    int     m_nHitType;

      // 绘制尺寸信息
    void DrawSizeInfo(CDC* pDC, CRect& rect); 
      // 绘制操作提示
    void DrawToolTip(CDC* pDC);     
      // 绘制放大镜
    void DrawZoomer(CDC* pDC);
      // 确定截取
    void ConfirmSnap();                        

      // 预翻译消息
    virtual BOOL PreTranslateMessage(MSG* pMsg);

protected:
    afx_msg void OnPaint();                                                // 绘制
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);                   // 鼠标移动选中区域
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);                 // 单击鼠标左键
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);                   // 释放鼠标左键
    afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);               // 双击鼠标左键
    afx_msg void OnRButtonUp(UINT nFlags, CPoint point);                   // 释放鼠标右键
    afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);     // 设置光标
    DECLARE_MESSAGE_MAP()
};

// 内容摘要:截屏窗口类

/*****************************************************************************
*                                  #include                                  *
*****************************************************************************/
#include "stdafx.h"
#include <afxpriv.h>
#include "SnapScreenWnd.h"

#ifdef _DEBUG
# define new DEBUG_NEW
# undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// CSnapScreenWnd

const int       TRACKER_INIT_SIZE   = 4;
const int       TRACKER_INFO_SPACE  = 5;
const COLORREF  COLOR_TRACKER       = RGB(10, 100, 130);
const COLORREF  COLOR_TIPTEXT       = RGB(0, 0, 0);
const COLORREF  COLOR_SIZEINFO      = RGB(0, 0, 0);
const CSize     DEFAULT_TIP_SIZE    = CSize(200, 120);
const int       TIP_POSITION        = 20;
const int       TIP_SPACE           = 8;
const LPCTSTR   SIZEINFO_PATTERN    = _T("Start Point:\t%d, %d\nSelected Size:\t%d x %d");
const LPCTSTR   TIP_TEXT_1          = _T("Click and hold on left button, then drag to select target region.\n\nPress [ESC] key or click right button to cancel.");
const LPCTSTR   TIP_TEXT_2          = _T("Adjust target region with the rectangle tracker.\n\nPress [ENTER] key or double click selected region to confirm.\n\nPress [ESC] key or click right button to restart.");
const int       ZOOMER_SIZE         = 32;
const int       ZOOMER_RATIO        = 4;

/*****************************************************************************
*                               类实现                                      *
*****************************************************************************/
IMPLEMENT_DYNAMIC(CSnapScreenWnd, CModalWnd)

/// <summary>
/// 构造函数
/// </summary>
/// <remarks>
/// 实现流程:
///     初始化对象
/// </remarks>
/// <param name="pParentWnd">父窗口对象指针</param>
/// <returns>返回:无
/// </returns>
CSnapScreenWnd::CSnapScreenWnd(CWnd* pParentWnd /*=NULL*/)
    : CModalWnd(pParentWnd)
    , m_rcTipMargin(TIP_SPACE, TIP_SPACE, TIP_SPACE, TIP_SPACE)
    , m_clrTipText(COLOR_TIPTEXT)
    , m_clrSizeInfo(COLOR_SIZEINFO)
    , m_csSizeInfoPatt(SIZEINFO_PATTERN)
    , m_csTipText1(TIP_TEXT_1)
    , m_csTipText2(TIP_TEXT_2)
    , m_bDragging(FALSE)
    , m_bDragged(FALSE)
    , m_bShowSizeInfo(FALSE)
    , m_bShowZoomer(TRUE)
    , m_ptStart(0, 0)
    , m_bMoveArea(FALSE)
    , m_bSizing(FALSE)
    , m_nHitType(-1)
{
    m_hScreenBmp    = CopyScreenToBitmap(NULL);
    m_hBackground   = FadeBitmap(CopyScreenToBitmap(NULL), 2);

    m_nScreenX      = ::GetSystemMetrics(SM_CXSCREEN);
    m_nScreenY      = ::GetSystemMetrics(SM_CYSCREEN);

    m_tracker.m_nStyle = CRectTracker::solidLine | CRectTracker::resizeInside |
                         CRectTracker::dottedLine | CRectTracker::hatchedBorder;
    m_tracker.m_rect.SetRect(-1, -1, -1, -1);
    m_tracker.SetRectColor(COLOR_TRACKER);
}

/// <summary>
/// 析构函数
/// </summary>
/// <remarks>
/// 实现流程:删除背景对象
/// </remarks>
/// <returns>返回:无
/// </returns>
CSnapScreenWnd::~CSnapScreenWnd()
{
    if (m_hBackground)
    {
        ::DeleteObject(m_hBackground);
    }
    if (m_hScreenBmp)
    {
        ::DeleteObject(m_hScreenBmp);
    }
}

BEGIN_MESSAGE_MAP(CSnapScreenWnd, CWnd)
    ON_WM_PAINT()
    ON_WM_MOUSEMOVE()
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
    ON_WM_LBUTTONDBLCLK()
    ON_WM_RBUTTONUP()
    ON_WM_SETCURSOR()
END_MESSAGE_MAP()

/// <summary>
/// 绘制
/// </summary>
/// <remarks>
/// 实现流程:
///     1、绘制背景
///     2、已经进行拖动操作,进行橡皮筋等的绘制
///     3、绘制放大镜
///     4、绘制操作提示
/// </remarks>
/// <returns>返回:无
/// </returns>
void CSnapScreenWnd::OnPaint()
{
    CPaintDC dc(this);

    CBufferDC dcBuffer(dc);


    // 绘制背景
    HDC hMemDC = ::CreateCompatibleDC(dcBuffer.GetSafeHdc());
    HBITMAP hOldBmp = (HBITMAP)::SelectObject(hMemDC, m_hBackground);
    ::BitBlt(dcBuffer.GetSafeHdc(), 0, 0, m_nScreenX, m_nScreenY, hMemDC, 0, 0, SRCCOPY);
    ::SelectObject(hMemDC, hOldBmp);
    ::DeleteDC(hMemDC);

    // 画选择区域
    DrawSelectArea(dcBuffer);

      // 已经进行拖动操作
    if (m_bDragged)
    {
        // 绘制橡皮筋
        m_tracker.Draw(&dcBuffer);

        // 绘制尺寸信息
        if (m_bShowSizeInfo)
        {
            CRect rect;
            m_tracker.GetTrueRect(&rect);

            DrawSizeInfo(&dcBuffer, rect);
        }


    }

      // 绘制放大镜
    if (m_bShowZoomer)
    {
        DrawZoomer(&dcBuffer);
    }

    // 绘制操作提示
    DrawToolTip(&dcBuffer);

}

/// <summary>
/// 绘制尺寸信息
/// </summary>
/// <remarks>
/// 实现流程:
///     1、设置字体
///     2、设置画布参数
///     3、计算文字尺寸
///     4、获取当前坐标
///     5、绘制尺寸信息
/// </remarks>
/// <param name="pDC">设备上下文类对象指针</param>
/// <param name="rect">相关区域</param>
/// <returns>返回:无
/// </returns>
void CSnapScreenWnd::DrawSizeInfo(CDC* pDC, CRect& rect)
{
    // 设置字体
    LOGFONT lfIcon;
    ::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIcon), &lfIcon, 0);
    CFont font;
    font.CreateFontIndirect(&lfIcon);
    CFontDC dcFont(pDC, &font, m_clrSizeInfo);

    // 设置画布参数
    CPenDC dcPen(pDC->GetSafeHdc(), m_clrSizeInfo);
    CBrush* pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
    CBrushDC dcBrush(pDC, pBrush);
    int nOldBkMode = pDC->SetBkMode(TRANSPARENT);

    // 计算文字尺寸
    CString csText;
    csText.Format(m_csSizeInfoPatt, rect.left, rect.top, rect.Width(), rect.Height());
    CRect rcTemp(0, 0, 0, 0);
    pDC->DrawText(csText, -1, &rcTemp, DT_CALCRECT | DT_LEFT | DT_TOP | DT_EXPANDTABS);
    CSize szText(rcTemp.Width(), rcTemp.Height());

    // 当前坐标
    CPoint ptStart;
    GetCursorPos(&ptStart);

    CRect rcInfo(ptStart.x + TRACKER_INFO_SPACE, ptStart.y - TRACKER_INFO_SPACE * 3 - szText.cy,
                 ptStart.x + TRACKER_INFO_SPACE * 3 + szText.cx, ptStart.y - TRACKER_INFO_SPACE);
      // right 大于m_nScreenX
    if (rcInfo.right > m_nScreenX)
    {
        CRect rcTemp(rcInfo);
        rcTemp.right = ptStart.x - TRACKER_INFO_SPACE;
        rcTemp.left = ptStart.x - TRACKER_INFO_SPACE * 3 - szText.cx;
        rcInfo = rcTemp;
    }
      // top小于
    if (rcInfo.top < 0)
    {
        CRect rcTemp(rcInfo);
        rcTemp.top = ptStart.y + TRACKER_INFO_SPACE;
        rcTemp.bottom = ptStart.y + TRACKER_INFO_SPACE * 3 + szText.cy;
        rcInfo = rcTemp;
    }

    pDC->Rectangle(&rcInfo);
    rcInfo.OffsetRect(TRACKER_INFO_SPACE, TRACKER_INFO_SPACE);
    pDC->DrawText(csText, -1, &rcInfo, DT_LEFT | DT_TOP | DT_EXPANDTABS);

    pDC->SetBkMode(nOldBkMode);
}

/// <summary>
/// 绘制操作提示
/// </summary>
/// <remarks>
/// 实现流程:
///     1、获取提示背景尺寸
///     2、光标位置
///     3、绘制背景
///     4、设置字体
///     5、绘制提示文字
/// </remarks>
/// <param name="pDC">设备上下文类对象指针</param>
/// <returns>返回:无
/// </returns>
void CSnapScreenWnd::DrawToolTip(CDC* pDC)
{
    static int nPosID = 0;

    CSize szTip(DEFAULT_TIP_SIZE);
      // 获取提示背景尺寸
    if (m_bmpTipBg.GetSafeHandle())
    {
        BITMAP bm;
        m_bmpTipBg.GetObject(sizeof(BITMAP), &bm);
        szTip.cx = bm.bmWidth;
        szTip.cy = bm.bmHeight;
    }

    CRect rcTip[2];
    rcTip[0] = CRect(CPoint(TIP_POSITION, TIP_POSITION), szTip);
    rcTip[1] = CRect(CPoint(m_nScreenX - TIP_POSITION - szTip.cx, TIP_POSITION), szTip);

    CPoint ptCursor;
    ::GetCursorPos(&ptCursor);
      // 光标位置
    if (rcTip[nPosID].PtInRect(ptCursor))
    {
        nPosID = !nPosID;
    }
    CRect rcDest(rcTip[nPosID]);

    // 绘制背景
      // 图片
    if (m_bmpTipBg.GetSafeHandle())
    {
        CDC dcBg;
        dcBg.CreateCompatibleDC(pDC);
        CBitmap* bmpOld = dcBg.SelectObject(&m_bmpTipBg);
        pDC->BitBlt(rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(),
            &dcBg, 0, 0, SRCCOPY);
        dcBg.SelectObject(bmpOld);
    }
      // 非图片
    else
    {
        CPen pen(PS_SOLID, 1, RGB(0, 0, 0));
        CPenDC dcPen(pDC, &pen);
        CBrushDC dcBrush(pDC->GetSafeHdc(), RGB(255, 255, 255));
        pDC->Rectangle(&rcDest);
    }

    // 设置字体
    LOGFONT lfIcon;
    ::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIcon), &lfIcon, 0);
    CFont font;
    font.CreateFontIndirect(&lfIcon);
    CFontDC dcFont(pDC, &font, m_clrTipText);

    // 绘制提示文字
    int nOldBkMode = pDC->SetBkMode(TRANSPARENT);
    CString csTipText = (m_bDragged && !m_bDragging) ? m_csTipText2 : m_csTipText1;
    rcDest.DeflateRect(&m_rcTipMargin);
    pDC->DrawText(csTipText, &rcDest, DT_LEFT | DT_TOP | DT_WORDBREAK);
    pDC->SetBkMode(nOldBkMode);
}

/// <summary>
/// 绘制放大镜
/// </summary>
/// <remarks>
/// 实现流程:
///     1、绘制放大镜
/// </remarks>
/// <param name="pDC">设备上下文类对象指针</param>
/// <returns>返回:无
/// </returns>
void CSnapScreenWnd::DrawZoomer(CDC* pDC)
{
    return;

    static int nPosID = 0;

    CSize szZoomer((ZOOMER_SIZE + 3) * ZOOMER_RATIO, (ZOOMER_SIZE + 3) * ZOOMER_RATIO);
    CRect rcZoomer[2];
    rcZoomer[0] = CRect(CPoint(TIP_POSITION, m_nScreenY - TIP_POSITION - szZoomer.cy), szZoomer);
    rcZoomer[1] = CRect(CPoint(m_nScreenX - TIP_POSITION - szZoomer.cx, m_nScreenY - TIP_POSITION - szZoomer.cy), szZoomer);

    CPoint ptCursor;
    ::GetCursorPos(&ptCursor);
      // 光标位置
    if (rcZoomer[nPosID].PtInRect(ptCursor))
    {
        nPosID = !nPosID;
    }

      // 绘制放大镜
    CRect rcDest(rcZoomer[nPosID]);
    pDC->FillSolidRect(&rcDest, RGB(0, 0, 0));
    rcDest.DeflateRect(ZOOMER_RATIO, ZOOMER_RATIO);

    HDC hBgDC = ::CreateCompatibleDC(pDC->GetSafeHdc());
    HBITMAP hOldBgBmp = (HBITMAP)::SelectObject(hBgDC, m_hBackground);
    HDC hZoomerDC = ::CreateCompatibleDC(hBgDC);
    HBITMAP hZoomerBmp = ::CreateCompatibleBitmap(hBgDC, ZOOMER_SIZE + 1, ZOOMER_SIZE + 1);
    HBITMAP hOldZoomerBmp = (HBITMAP)::SelectObject(hZoomerDC, hZoomerBmp);

    ptCursor.Offset(-ZOOMER_SIZE / 2, -ZOOMER_SIZE / 2);
    ::BitBlt(hZoomerDC, 0, 0, ZOOMER_SIZE + 1, ZOOMER_SIZE + 1,
        hBgDC, ptCursor.x, ptCursor.y, SRCCOPY);

    CPenDC dcPen(hZoomerDC, RGB(0, 0, 0));
    CPoint ptCenter(ZOOMER_SIZE / 2, ZOOMER_SIZE / 2);
    ::MoveToEx(hZoomerDC, ptCenter.x - 3, ptCenter.y, NULL);
    ::LineTo(hZoomerDC, ptCenter.x + 4, ptCenter.y);
    ::MoveToEx(hZoomerDC, ptCenter.x, ptCenter.y - 3, NULL);
    ::LineTo(hZoomerDC, ptCenter.x, ptCenter.y + 4);

    ::StretchBlt(pDC->GetSafeHdc(), rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(),
        hZoomerDC, 0, 0, ZOOMER_SIZE + 1, ZOOMER_SIZE + 1, SRCCOPY);

      // 清除对象
    ::SelectObject(hBgDC, hOldBgBmp);
    ::DeleteDC(hBgDC);
    ::SelectObject(hZoomerDC, hOldZoomerBmp);
    ::DeleteDC(hZoomerDC);
    ::DeleteObject(hZoomerBmp);
}

/// <summary>
/// 单击鼠标左键
/// </summary>
/// <remarks>
/// 实现流程:
///     1、第一次画矩形
/// </remarks>
/// <param name="nFlags">设备上下文类对象指针</param>
/// <param name="point">设备上下文类对象指针</param>
/// <returns>返回:无
/// </returns>
void CSnapScreenWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
    m_nHitType = m_tracker.HitTest(point);
    if (m_nHitType < 0)
    {
            //第一次画矩形
        if (!m_bDragged)
        {
            m_ptStart = point;
            m_bDragging = TRUE;
            m_bDragged = TRUE;
            m_bShowSizeInfo = TRUE;
            m_tracker.m_rect.SetRect(point.x, point.y,
                point.x + TRACKER_INIT_SIZE, point.y + TRACKER_INIT_SIZE);

            Invalidate(FALSE);
        }
    }
      // 显示
    else if( CSnapTracker::hitMiddle == m_nHitType )
    {
        m_bShowSizeInfo = TRUE;
        m_bShowZoomer = TRUE;
        Invalidate(FALSE);
        if (m_bDragged)
        {
            m_bMoveArea   = TRUE;
            m_ptStartMove = point;
            //m_tracker.Track(this, point, TRUE);
            Invalidate(FALSE);
        }
    }
    else
    {
        m_rcGragging = m_tracker.m_rect;

        m_bShowSizeInfo = TRUE;
        m_bShowZoomer = TRUE;
        m_bSizing = TRUE;
        m_bDragging = TRUE;
        Invalidate(FALSE);
    }

    CWnd::OnLButtonDown(nFlags, point);
}

/// <summary>
/// 鼠标移动选中区域
/// </summary>
/// <remarks>
/// 实现流程:
///     1、鼠标移动选中区域
/// </remarks>
/// <param name="nFlags">动作标识</param>
/// <param name="point">消息对象指针</param>
/// <returns>返回:无
/// </returns>
void CSnapScreenWnd::OnMouseMove(UINT nFlags, CPoint point)
{
      // 未进行拖动
    if (!m_bDragged && !m_bDragging)
    {
        Invalidate(FALSE);
    }
    else if( m_bMoveArea )
    {
        m_tracker.m_rect.OffsetRect( point.x - m_ptStartMove.x,point.y - m_ptStartMove.y );
        m_ptStartMove = point;
        Invalidate(FALSE);
    }
       //拖动中
    else if ( m_bDragging && m_bSizing)
    {
        switch( m_nHitType )
        {
        case CSnapTracker::hitTopLeft: // 左上角,以右下角为基准坐标
            m_tracker.m_rect.SetRect(m_rcGragging.right, m_rcGragging.bottom, point.x, point.y);
            break;
        case CSnapTracker::hitTopRight: // 右上角,以左下角为基准坐标
            m_tracker.m_rect.SetRect(m_rcGragging.left, m_rcGragging.bottom, point.x, point.y);
            break;
        case CSnapTracker::hitBottomRight: // 右下角
            m_tracker.m_rect.SetRect(m_rcGragging.left, m_rcGragging.top, point.x, point.y);
            break;
        case CSnapTracker::hitBottomLeft: // 左下角
            m_tracker.m_rect.SetRect(m_rcGragging.right, m_rcGragging.top, point.x, point.y);
            break;
        case CSnapTracker::hitTop: // 上边
            m_tracker.m_rect.SetRect(m_rcGragging.left, m_rcGragging.bottom, m_rcGragging.right, point.y);
            break;
        case CSnapTracker::hitRight: // 右边
            m_tracker.m_rect.SetRect(m_rcGragging.left, m_rcGragging.top, point.x, m_rcGragging.bottom);
            break;
        case CSnapTracker::hitBottom: // 底边
            m_tracker.m_rect.SetRect(m_rcGragging.left, m_rcGragging.top, m_rcGragging.right, point.y);
            break;
        case CSnapTracker::hitLeft: // 左边
            m_tracker.m_rect.SetRect(m_rcGragging.right, m_rcGragging.top, point.x, m_rcGragging.bottom);
            break;

        }
        Invalidate(FALSE);
    }
    else if( m_bDragging )
    {
        m_tracker.m_rect.SetRect(m_ptStart.x,m_ptStart.y, point.x, point.y);

        Invalidate(FALSE);
    }

    CWnd::OnMouseMove(nFlags, point);
}

/// <summary>
/// 释放鼠标左键
/// </summary>
/// <remarks>
/// 实现流程:
///     1、释放鼠标左键
/// </remarks>
/// <param name="nFlags">动作标识</param>
/// <param name="point">鼠标位置</param>
/// <returns>返回:无
/// </returns>
void CSnapScreenWnd::OnLButtonUp(UINT nFlags, CPoint point)
{
    BOOL bDragging = m_bDragging;
    m_bShowSizeInfo = FALSE;
    m_bShowZoomer = FALSE;
    m_bDragging = FALSE;
    m_bMoveArea = FALSE;
    m_bSizing   = FALSE;
      // 拖动中释放鼠标
    if (bDragging)
    {
        Invalidate(FALSE);
        m_tracker.SetCursor(this, HTCLIENT);
    }

    CWnd::OnLButtonUp(nFlags, point);
}


/// <summary>
/// 双击鼠标左键
/// </summary>
/// <remarks>
/// 实现流程:
///     1、双击鼠标左键确认截屏
/// </remarks>
/// <param name="nFlags">动作标识</param>
/// <param name="point">鼠标位置</param>
/// <returns>返回:无
/// </returns>
void CSnapScreenWnd::OnLButtonDblClk(UINT nFlags, CPoint point)
{
       //当前鼠标位置在选中区域
    if (m_tracker.HitTest(point) == CRectTracker::hitMiddle)     
    {
            // 确认截屏
        ConfirmSnap();
    }

    CWnd::OnLButtonDblClk(nFlags, point);
}

/// <summary>
/// 释放鼠标右键
/// </summary>
/// <remarks>
/// 实现流程:
///     1、释放鼠标右键
/// </remarks>
/// <param name="nFlags">动作标识</param>
/// <param name="point">鼠标位置</param>
/// <returns>返回:无
/// </returns>
void CSnapScreenWnd::OnRButtonUp(UINT nFlags, CPoint point)
{
      // 已经进行拖动操作
    if (m_bDragged)
    {
        m_bDragged = FALSE;
        m_bShowZoomer = TRUE;
        m_tracker.m_rect.SetRect(-1, -1, -1, -1);
        Invalidate(FALSE);
        SetCursor(::LoadCursor(0, IDC_CROSS));
    }
      // 结束截屏
    else
    {
        EndModalLoop(0);
    }

    CWnd::OnRButtonUp(nFlags, point);
}

/// <summary>
/// 设置光标
/// </summary>
/// <remarks>
/// 实现流程:
///     1、设置光标
/// </remarks>
/// <param name="pWnd">包含光标的窗口对象</param>
/// <param name="nHitTest">光标位置</param>
/// <param name="message">鼠标消息成员</param>
/// <returns>返回:无
/// </returns>
BOOL CSnapScreenWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
      // 根据鼠标坐标位置设置光标
    if (pWnd == this && m_tracker.SetCursor(this, nHitTest)
        && !m_bDragging && m_bDragged)
    {
        return TRUE;
    }

    SetCursor(::LoadCursor(0, (m_bDragged && !m_bDragging) ? IDC_ARROW : IDC_CROSS));
    return TRUE;
}

/// <summary>
/// 确定截取
/// </summary>
/// <remarks>
/// 实现流程:
///     1、确定截取
/// </remarks>
/// <returns>返回:无
/// </returns>
void CSnapScreenWnd::ConfirmSnap()
{
    CRect rcDest;
    m_tracker.GetTrueRect(&rcDest);
    rcDest &= CRect(0, 0, m_nScreenX, m_nScreenY);

    // 确定截取
    HDC hBgDC = ::CreateCompatibleDC(0);
    HBITMAP hBgOldBmp = (HBITMAP)::SelectObject(hBgDC, m_hScreenBmp);
    HDC hDestDC = ::CreateCompatibleDC(0);
    m_hResult = ::CreateCompatibleBitmap(hBgDC, rcDest.Width(), rcDest.Height());
    HBITMAP hDestOldBmp = (HBITMAP)::SelectObject(hDestDC, m_hResult);

    ::BitBlt(hDestDC, 0, 0, rcDest.Width(), rcDest.Height(), hBgDC, rcDest.left, rcDest.top, SRCCOPY);

    ::SelectObject(hBgDC, hBgOldBmp);
    ::DeleteDC(hBgDC);
    ::SelectObject(hDestDC, hDestOldBmp);
    ::DeleteDC(hDestDC);

      // 结束截屏
    EndModalLoop(IDOK);
}

/// <summary>
/// 截取屏幕转化为位图
/// </summary>
/// <remarks>
/// 实现流程:
///     1、截取全屏
/// </remarks>
/// <param name="lpRect">消息对象指针</param>
/// <returns>返回:无
/// </returns>
HBITMAP CSnapScreenWnd::CopyScreenToBitmap(LPRECT lpRect /*=NULL*/)
{
    CRect rcSrc(0, 0, ::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN));
      // 输入区域不为空
    if( NULL != lpRect )
    {
        CRect rcInput;
        rcInput.SetRect(lpRect->left,lpRect->top,lpRect->right,lpRect->bottom);
        rcInput.NormalizeRect();
        if (!rcInput.IsRectEmpty())
        {
            rcSrc = rcInput;
        }
    }

      // 转化为位图
    HDC hScreenDC = ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
    HDC hMemoryDC = ::CreateCompatibleDC(hScreenDC);
    HBITMAP hBitmap = ::CreateCompatibleBitmap(hScreenDC, rcSrc.Width(), rcSrc.Height());
    HBITMAP hOldBmp = (HBITMAP)::SelectObject(hMemoryDC, hBitmap);
    ::BitBlt(hMemoryDC, 0, 0, rcSrc.Width(), rcSrc.Height(), hScreenDC, rcSrc.left, rcSrc.top, SRCCOPY);
    ::SelectObject(hMemoryDC, hOldBmp);
    ::DeleteDC(hScreenDC);
    ::DeleteDC(hMemoryDC);

    return hBitmap;
}

/// <summary>
/// 预翻译消息
/// </summary>
/// <remarks>
/// 实现流程:
///     1、预翻译消息
/// </remarks>
/// <param name="pMsg">消息对象指针</param>
/// <returns>返回:无
/// </returns>
BOOL CSnapScreenWnd::PreTranslateMessage(MSG* pMsg)
{
      // 键盘按下事件
    if (pMsg->message == WM_KEYDOWN)
    {
            // 判断所按键
        switch (pMsg->wParam)
        {
        case VK_ESCAPE:
                  // 取消选中
            if (m_bDragged)
            {
                m_bDragged = FALSE;
                m_bDragging = FALSE;
                m_tracker.m_rect.SetRect(-1,-1,-1,-1);
                Invalidate(FALSE);
                        return TRUE;
            }
                  // 取消截屏
            else
            {
                EndModalLoop(IDCANCEL);
                        return TRUE;
            }
            break;

        case VK_RETURN:
                  // 确认截屏
            if (m_bDragged && !m_bDragging)
            {
                ConfirmSnap();
            }
        }
    }

    return CWnd::PreTranslateMessage(pMsg);
}

/// <summary>
/// 设置提示背景
/// </summary>
/// <remarks>
/// 实现流程:
///     1、设置提示背景
/// </remarks>
/// <param name="hBitmap">位图句柄</param>
/// <param name="rcMargin">边界间距</param>
/// <returns>返回:无
/// </returns>
void CSnapScreenWnd::SetTipBackground(HBITMAP hBitmap, LPRECT rcMargin)
{
    m_bmpTipBg.DeleteObject();
    m_bmpTipBg.Attach(hBitmap);
    m_rcTipMargin = rcMargin;
}

/// <summary>
/// 设置提示文本
/// </summary>
/// <remarks>
/// 实现流程:
///     1、设置提示文本
/// </remarks>
/// <param name="lpTipText1">提示文本</param>
/// <param name="lpTipText2">提示文本</param>
/// <returns>返回:无
/// </returns>
void CSnapScreenWnd::SetTipText(LPCTSTR lpTipText1, LPCTSTR lpTipText2)
{
    m_csTipText1 = lpTipText1;
    m_csTipText2 = lpTipText2;
}

/// <summary>
/// 设置大小信息式样
/// </summary>
/// <remarks>
/// 实现流程:
///     1、设置大小信息式样
/// </remarks>
/// <param name="lpSizeInfoPattern">大小信息式样</param>
/// <returns>返回:无
/// </returns>
void CSnapScreenWnd::SetSizeInfoPattern(LPCTSTR lpSizeInfoPattern)
{
    m_csSizeInfoPatt = lpSizeInfoPattern;
}

/// <summary>
/// 设置颜色
/// </summary>
/// <remarks>
/// 实现流程:
///     1、设置颜色
/// </remarks>
/// <param name="clrTracker">tracker颜色</param>
/// <param name="clrTipText">提示文本颜色</param>
/// <param name="clrSizeInfo">尺寸信息颜色</param>
/// <returns>返回:无
/// </returns>
void CSnapScreenWnd::SetColors(COLORREF clrTracker, COLORREF clrTipText, COLORREF clrSizeInfo)
{
    m_tracker.SetRectColor(clrTracker);
    m_clrTipText    = clrTipText;
    m_clrSizeInfo   = clrSizeInfo;
}


/**
    使窗口变暗
    hBmp需要变灰的图片句柄
    nTrans 转换尺度 2~8   数字也大越暗
*/
HBITMAP CSnapScreenWnd::FadeBitmap(HBITMAP hBmp, int nTrans)
{
    BITMAP btm;
    GetObject(hBmp, sizeof(BITMAP), &btm);

    int nSize = btm.bmWidthBytes * btm.bmHeight;
    nSize = btm.bmWidth * btm.bmHeight * btm.bmBitsPixel / 8;

    BYTE* lpData = (BYTE*)malloc(sizeof(BYTE) * nSize);

    GetBitmapBits(hBmp, nSize, lpData);   
    for(int i = 0; i < nSize; i++)
    {
        lpData[i] = lpData[i] / nTrans;
    }

    SetBitmapBits(hBmp, nSize, lpData);

    free(lpData);

    return hBmp;
}


#if 0

// 使图片变灰,(黑白色)
HBITMAP CSnapScreenWnd::FadeBitmap(HBITMAP hBmp, int nTrans)
{
    HBITMAP hRetBmp = NULL;
    if (hBmp)
    {
        HDC hBufferDC = CreateCompatibleDC(NULL);
        HGDIOBJ hPrevBufObject = SelectObject(hBufferDC, hBmp);

        HDC hDirectDC = CreateCompatibleDC(NULL);     // DC for working            
        if (hDirectDC)
        {
            BITMAP bm;
            GetObject(hBmp, sizeof(bm), &bm);
            BITMAPINFO bmInfo;
            ZeroMemory(&bmInfo,sizeof(bmInfo));
            bmInfo.bmiHeader.biSize       = sizeof(BITMAPINFOHEADER);
            bmInfo.bmiHeader.biWidth      = bm.bmWidth;
            bmInfo.bmiHeader.biHeight     = bm.bmHeight;
            bmInfo.bmiHeader.biPlanes     =  1;
            bmInfo.bmiHeader.biBitCount   = 32;       
            UINT* ptPixels;         
            HBITMAP hDirectBitmap = CreateDIBSection(hDirectDC,
                (BITMAPINFO*)&bmInfo,
                DIB_RGB_COLORS,(void**)&ptPixels, NULL, 0);
            if (hDirectBitmap)
            {
                // hDirectBitmap放入hDirectDC中处理
                HGDIOBJ hPrevBufDirObject = SelectObject(hDirectDC, hDirectBitmap);
                // 当前将原hBmp即屏幕的所有像素写入到hDirectDC
                // 即需要对像素灰度处理的DC
                BitBlt(hDirectDC,0,0,bm.bmWidth,bm.bmHeight,hBufferDC,0,0,SRCCOPY);     

                int iAlpha = (int)(255.0 * nTrans / 100.0);

                int nSize = bm.bmWidth * bm.bmHeight;
                for (int i=0; i<nSize; i++)
                {             
                    // 0.212671 * R + 0.715160 * G + 0.072169 * B
                    int iSrcR = (ptPixels[i]) & 0x00ff0000 >> 16;
                    int iSrcG = ptPixels[i] & 0x0000ff00 >> 8;
                    int iSrcB = ptPixels[i] & 0x000000ff;

                    /**
                        调整合成颜色的基数
                        int iGrey = (iSrcR * 54 + iSrcG * 182 + iSrcB * 19) >> 8;
                    */                    
                    int iGrey = (iSrcR * 0 + iSrcG * 0 + iSrcB * 0) >> 8;

                    COLORREF Col =iGrey ; //RGB(iGrey, iGrey, iGrey) ;
                    ptPixels[i] = RGB(
                        (GetBValue( Col ) * iAlpha + iSrcB * (255 - iAlpha)) >> 8,
                        (GetGValue( Col ) * iAlpha + iSrcG * (255 - iAlpha)) >> 8,
                        (GetRValue( Col ) * iAlpha + iSrcR * (255 - iAlpha)) >> 8 );
                }
                SelectObject(hDirectDC,hPrevBufDirObject);        
                hRetBmp = hDirectBitmap;
            }
            DeleteDC(hDirectDC);
        }
        SelectObject(hBufferDC, hPrevBufObject);
        DeleteDC(hBufferDC);
    }
    return hRetBmp;
}


#endif

void CSnapScreenWnd::DrawSelectArea(CBufferDC& dcBuffer)
{
    CRect rcDest;
    m_tracker.GetTrueRect(&rcDest);
    rcDest &= CRect(0, 0, m_nScreenX, m_nScreenY);


    HDC hMemDC = ::CreateCompatibleDC(dcBuffer.GetSafeHdc());
    HBITMAP hOldBmp = (HBITMAP)::SelectObject(hMemDC, m_hScreenBmp);
    ::BitBlt(dcBuffer.GetSafeHdc(), rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(),
                hMemDC, rcDest.left, rcDest.top, SRCCOPY);
    ::SelectObject(hMemDC, hOldBmp);
    ::DeleteDC(hMemDC);
}

/// <summary>
/// 截取选中屏幕
/// </summary>
/// <remarks>
/// 实现流程:
///     1、显示截取屏幕界面
///     2、返回确认截屏后所得位图句柄
/// </remarks>
/// <returns>返回:位图句柄
/// </returns>
HBITMAP CSnapScreenWnd::SnapScreen()
{
    m_hResult = NULL;
      // 显示截取屏幕界面
    DoModal(WS_EX_TOPMOST, NULL, NULL, WS_VISIBLE | WS_POPUP & ~WS_BORDER,
        0, 0, m_nScreenX, m_nScreenY, m_pParentWnd->GetSafeHwnd(), NULL);

      
      // 返回确认截屏后所得位图句柄
    return m_hResult;
}
posted @ 2011-11-29 23:03  Wait...  阅读(387)  评论(0编辑  收藏  举报