Click here to Skip to main content
15,881,852 members
Articles / Web Development / HTML

Screen Snaper SideBar Gadget

Rate me:
Please Sign up or sign in to vote.
4.63/5 (18 votes)
1 Dec 2011CPOL2 min read 117.6K   4.7K   74  
Screen Snaper is perfect to quickly share a picture-perfect representation of anything on your screen.
 /*---------------------------------------------------------------------------
|                                  DCUtility                                  |
|--------------------------------------+--------------------------------------|
|    SolutionName : ScreenSnaperGadget                                        |
|    ProjectName  : Helper                                                    |
|    FileName     : WinCapture.cpp                                            |
|    CreationDate : 2007-03-07                                                |
|    Author       : Dany Cantin                                               |
|    Comments     : dcutility@hotmail.com                                     |
|--------------------------------------+--------------------------------------|
|                             Screen Capture Tool                             |
|                         Windows Vista SideBar Gadget                        |
|--------------------------------------+--------------------------------------|
|                          Copyright � 2007 DCUtility                         |
|                              All rights reserved.                           |
 ---------------------------------------------------------------------------*/

#include "stdafx.h"
#include "Helper.h"
#include "WinCapture.h"
#include "OptionsDlg.h"

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

#define SLEEP_TRACKED_INTERVAL  30
#define ID_TIMER_FRAME_RECT     2
#define TIMER_FRAME_RECT_ELAPSE 350
#define VK_PLUS                 187
#define VK_MINUS                189
#define PIXEL_INCREMENTAL_MOVE  10

#define SetRegInt AfxGetApp()->WriteProfileInt
#define GetRegInt AfxGetApp()->GetProfileInt

CWinCapture::CWinCapture(CWnd* pParent /*=NULL*/)
    : CDialog(CWinCapture::IDD, pParent)
{
    //{{AFX_DATA_INIT(CWinCapture)
    //}}AFX_DATA_INIT

    m_CaptureType           = CT_DESKTOP;
    
    m_CMWDrawMode           = (CDrawUtil::eDrawMode)GetRegInt("WinCapture",
                                                              "CMWDrawMode",
                                                              CDrawUtil::DM_RECTANGLE);
    m_bCMWShowPos           = GetRegInt("WinCapture", "bCMWShowPos", TRUE);
    m_nCMWPenWidth          = GetRegInt("WinCapture", "nCMWPenWidth", 3);
    m_nCMWRectRoundWidth    = GetRegInt("WinCapture", "nCMWRectRoundWidth", 25);
    m_CMRDrawMode           = (CDrawUtil::eDrawMode)GetRegInt("WinCapture",
                                                              "CMRDrawMode",
                                                              CDrawUtil::DM_RECTANGLE);
    m_bCMRShowPos           = GetRegInt("WinCapture", "bCMRShowPos", TRUE);
    m_nCMRPenWidth          = GetRegInt("WinCapture", "nCMRPenWidth", 1);
    m_nCMRRectRoundWidth    = GetRegInt("WinCapture", "nCMRRectRoundWidth", 25);
    m_Backcolor             = GetRegInt("WinCapture", "Backcolor", RGB(255, 0, 255));
    m_bPlaySound            = GetRegInt("WinCapture", "bPlaySound", TRUE);
    m_bShowHelp             = GetRegInt("WinCapture", "ShowHelper", TRUE);
        
    m_pOldMemBitmap         = NULL;
    m_FirstDownClick        = FALSE;
    m_bEndSelection         = FALSE;
    m_ShiftKeyPressed       = FALSE;
    m_bRestoreCursorArrow   = FALSE;
    m_bShowCursor           = TRUE;
}

BOOL CWinCapture::DestroyWindow() 
{
    SuspendTimer();
    
    if (m_pOldMemBitmap)
        m_MemDC.SelectObject(m_pOldMemBitmap);

    m_pWinCaptureHelper.DestroyWindow();

    SetRegInt("WinCapture", "CMWDrawMode", m_CMWDrawMode);
    SetRegInt("WinCapture", "bCMWShowPos", m_bCMWShowPos);
    SetRegInt("WinCapture", "nCMWPenWidth", m_nCMWPenWidth);
    SetRegInt("WinCapture", "nCMWRectRoundWidth", m_nCMWRectRoundWidth);
    SetRegInt("WinCapture", "CMRDrawMode", m_CMRDrawMode);
    SetRegInt("WinCapture", "bCMRShowPos", m_bCMRShowPos);
    SetRegInt("WinCapture", "nCMRPenWidth", m_nCMRPenWidth);
    SetRegInt("WinCapture", "nCMRRectRoundWidth", m_nCMRRectRoundWidth);
    SetRegInt("WinCapture", "Backcolor", m_Backcolor);
    SetRegInt("WinCapture", "bPlaySound", m_bPlaySound);

    return CDialog::DestroyWindow();
}

void CWinCapture::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CWinCapture)
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CWinCapture, CDialog)
    //{{AFX_MSG_MAP(CWinCapture)
    ON_WM_ERASEBKGND()
    ON_WM_MOUSEMOVE()
    ON_WM_TIMER()
    ON_WM_SETCURSOR()
    ON_WM_LBUTTONDOWN()
    ON_WM_RBUTTONDOWN()
    ON_COMMAND(ID_POP_DISMISS, OnPopDismiss)
    ON_COMMAND(ID_POP_ACCEPT, OnPopAccept)
    ON_COMMAND(ID_POP_ABORT, OnPopAbort)
    ON_COMMAND(ID_POP_SWITCH_DESKTOP, OnPopSwitchDesktop)
    ON_COMMAND(ID_POP_SWITCH_WINDOW, OnPopSwitchWindow)
    ON_COMMAND(ID_POP_SWITCH_REGION, OnPopSwitchRegion)
    ON_COMMAND(ID_POP_OPTIONS, OnPopOptions)
    ON_COMMAND(ID_POP_TOGGLE_HELP, OnPopToggleHelp)
    ON_COMMAND(ID_POP_RESET_REGION, OnPopResetRegion)
    ON_COMMAND(ID_POP_TOGGLE_CURSOR, OnPopToggleCursor)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CWinCapture::OnInitDialog() 
{
    CDialog::OnInitDialog();
    
    m_WindowHelper.GetAllVisibleWindows();

    m_DesktopSize = CSize(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
    
    CWindowDC dc(NULL);
    m_MemBitmap.CreateCompatibleBitmap(&dc, m_DesktopSize.cx, m_DesktopSize.cy);
    m_MemDC.CreateCompatibleDC(&dc);
    m_pOldMemBitmap = m_MemDC.SelectObject(&m_MemBitmap);
    m_MemDC.BitBlt(0, 0, m_DesktopSize.cx, m_DesktopSize.cy, &dc, 0, 0, SRCCOPY);

    if (m_CaptureType == CT_DESKTOP) {
        m_rcSnap.SetRect(0, 0, m_DesktopSize.cx, m_DesktopSize.cy);
        OnOK();
    }
    else {
        SetCursorPos(m_DesktopSize.cx / 2, m_DesktopSize.cy / 2);

        SetWindowPos(&wndTopMost, 0,0, m_DesktopSize.cx, m_DesktopSize.cy, SWP_SHOWWINDOW);    
    
        m_pWinCaptureHelper.Create(IDD_DIALOG_SNAP_HELPER, this);
        m_pWinCaptureHelper.SetDesktopInfo(&m_MemDC, m_DesktopSize);
    
        if (m_CaptureType == CT_WINDOW)
            SetTimer(ID_TIMER_FRAME_RECT, TIMER_FRAME_RECT_ELAPSE, NULL);

        if (m_bShowHelp)
            m_pWinCaptureHelper.ShowWindow(SW_SHOW);
    }

    return TRUE;
}

BOOL CWinCapture::OnEraseBkgnd(CDC* pDC) 
{
    SetWindowPos(&wndTopMost, 0,0, m_DesktopSize.cx, m_DesktopSize.cy, SWP_SHOWWINDOW);    

    if (m_bEndSelection || m_CaptureType == CT_DESKTOP) {
        pDC->BitBlt(0, 0, m_DesktopSize.cx, m_DesktopSize.cy, &m_MemDC, 0, 0, SRCCOPY);    
        OnOK();
    }

    if (m_CaptureType == CT_WINDOW) {
        CMemDCEx MemDC(pDC);
        MemDC.BitBlt(0, 0, m_DesktopSize.cx, m_DesktopSize.cy, &m_MemDC, 0, 0, SRCCOPY);    
        m_DrawUtil.DrawFrame(&MemDC, m_rcSnap, m_bCMWShowPos, m_CMWDrawMode, m_nCMWPenWidth,
                             CPoint(m_nCMWRectRoundWidth, m_nCMWRectRoundWidth));
    }
    else if (m_CaptureType == CT_REGION) {
        
        if (!m_FirstDownClick) {
            pDC->BitBlt(0, 0, m_DesktopSize.cx, m_DesktopSize.cy, &m_MemDC, 0, 0, SRCCOPY);    
            m_DrawUtil.DrawSreenCross(pDC, m_CurrentPoint, m_DesktopSize);
        }
        else {
            CMemDCEx MemDC(pDC);
            MemDC.BitBlt(0, 0, m_DesktopSize.cx, m_DesktopSize.cy, &m_MemDC, 0, 0, SRCCOPY);    
            m_DrawUtil.DrawFrame(&MemDC, m_rcSnap, m_bCMRShowPos, m_CMRDrawMode, m_nCMRPenWidth,
                                 CPoint(m_nCMRRectRoundWidth, m_nCMRRectRoundWidth));
        }    
    }

    return TRUE;
}

BOOL CWinCapture::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
    UNREFERENCED_PARAMETER(pWnd);
    UNREFERENCED_PARAMETER(nHitTest);
    UNREFERENCED_PARAMETER(message);
    
    if (m_bShowCursor || m_bRestoreCursorArrow) {

        if (m_bRestoreCursorArrow) {
            SetCursor(LoadCursor(NULL, IDC_ARROW));
        }
        else if (m_CaptureType == CT_WINDOW) {
            SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR_WINDOW));
        }
        else if (m_CaptureType == CT_REGION) {

            if (!m_FirstDownClick)
                SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR_CROSS));
            else
                SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR_TRACKER));
        }
    }
    else
        SetCursor(NULL);

    return TRUE;
}

void CWinCapture::OnTimer(UINT_PTR nIDEvent) 
{
    if (m_CaptureType != CT_WINDOW)
        SuspendTimer();
    else if (nIDEvent == ID_TIMER_FRAME_RECT)
        FlashFrameRect();
    else 
        CDialog::OnTimer(nIDEvent);
}

void CWinCapture::FlashFrameRect()
{
    CClientDC dc(this);
    m_DrawUtil.DrawFrame(&dc, m_rcSnap, m_bCMWShowPos, m_CMWDrawMode, m_nCMWPenWidth,
                         CPoint(m_nCMWRectRoundWidth, m_nCMWRectRoundWidth));
}

void CWinCapture::OnLButtonDown(UINT nFlags, CPoint point) 
{
    if (m_CaptureType == CT_WINDOW) {

        SuspendTimer();
        m_bEndSelection = TRUE;
        Invalidate();
        UpdateHelperState(FALSE, FALSE);
    }
    else if (m_CaptureType == CT_REGION) {
    
        m_FirstDownClick = !m_FirstDownClick;

        if (!m_FirstDownClick) {

            m_bEndSelection = TRUE;
            Invalidate();
            UpdateHelperState(FALSE, FALSE); 
        }
        else {
            m_LastPoint = point;
        }
    }

    CDialog::OnLButtonDown(nFlags, point);
}

void CWinCapture::OnMouseMove(UINT nFlags, CPoint point) 
{ 
    SetWindowPos(&wndTopMost, 0,0, m_DesktopSize.cx, m_DesktopSize.cy, SWP_SHOWWINDOW);    
    
    BOOL bTraked = m_pWinCaptureHelper.TrackPos(
                       &m_MemDC,
                       point,
                       (m_CaptureType == CT_REGION && !m_FirstDownClick)?TRUE:FALSE
                   );
    
    if (m_CaptureType == CT_WINDOW) {

        CRect rc = m_WindowHelper.GetWindowRectFromPoint(point);
    
        if (m_rcSnap != rc || bTraked) {

            m_rcSnap = rc;
            if (bTraked)
                Sleep(SLEEP_TRACKED_INTERVAL);

            Invalidate();
        }
    }
    else if (m_CaptureType == CT_REGION) {

        if (m_FirstDownClick) {
            m_rcSnap.SetRect(m_LastPoint.x, m_LastPoint.y,
                             point.x, point.y);
            m_rcSnap.NormalizeRect();
        }

        Invalidate();
    }
    
    m_CurrentPoint = point;

    CDialog::OnMouseMove(nFlags, point);
}

CBitmap* CWinCapture::GetSnapBitmap(BOOL& bPlaySound)
{
    bPlaySound = m_bPlaySound;

    if (m_rcSnap.IsRectEmpty())
        return NULL;

    if (m_CaptureType == CT_DESKTOP) {
        return m_DrawUtil.CopyBitmap(&m_MemBitmap);
    }

    CWindowDC dc(NULL);
    m_MemDC.DeleteDC();
    m_MemBitmap.DeleteObject();

    if (!m_MemDC.CreateCompatibleDC(&dc))
        return NULL;
    
    if (!m_MemBitmap.CreateCompatibleBitmap(&dc, m_rcSnap.Width(), m_rcSnap.Height()))
        return NULL;

    m_pOldMemBitmap = m_MemDC.SelectObject(&m_MemBitmap);
    
    CDrawUtil::eDrawMode DrawMode = CDrawUtil::DM_RECTANGLE;
    int       nRectRoundWidth      = 0;
    int       nPenWidth;

    if (m_CaptureType == CT_WINDOW) {
        DrawMode        = m_CMWDrawMode;
        nPenWidth       = m_nCMWPenWidth;
        nRectRoundWidth = m_nCMWRectRoundWidth;
    }
    else if (m_CaptureType == CT_REGION) {
        DrawMode        = m_CMRDrawMode;
        nPenWidth       = m_nCMRPenWidth;
        nRectRoundWidth = m_nCMRRectRoundWidth;
    }

    if (DrawMode != CDrawUtil::DM_RECTANGLE && m_CaptureType != CT_DESKTOP) {
        
        CRect rcSnap = CRect(0, 0, m_rcSnap.Width(), m_rcSnap.Height());
        CRgn  rgn;

        if (DrawMode == CDrawUtil::DM_ELLIPSE)
            rgn.CreateEllipticRgnIndirect(rcSnap);
        else
            rgn.CreateRoundRectRgn(0, 0, rcSnap.Width(), rcSnap.Height(),
                                   nRectRoundWidth, nRectRoundWidth);

        m_MemDC.FillSolidRect(rcSnap, m_Backcolor);
        m_MemDC.SelectClipRgn(&rgn);
        m_MemDC.BitBlt(0, 0, m_rcSnap.Width(), m_rcSnap.Height(), &dc,
                       m_rcSnap.left, m_rcSnap.top, SRCCOPY);
        rgn.DeleteObject();
    }
    else
        m_MemDC.BitBlt(0, 0, m_rcSnap.Width(), m_rcSnap.Height(), &dc,
                       m_rcSnap.left, m_rcSnap.top, SRCCOPY);

    m_MemDC.SelectObject(&m_pOldMemBitmap);
    m_MemDC.DeleteDC();

    return m_DrawUtil.CopyBitmap(&m_MemBitmap);
}

BOOL CWinCapture::PreTranslateMessage(MSG* pMsg) 
{
    if(pMsg->message == WM_KEYDOWN) {

        CPoint pt = m_CurrentPoint;

        switch (pMsg->wParam) {
        case VK_RETURN:
            return TRUE;
            break;
        case VK_ADD:
        case VK_PLUS:
            m_pWinCaptureHelper.DoZoomFactor(TRUE);
            break;
        case VK_SUBTRACT:
        case VK_MINUS:
            m_pWinCaptureHelper.DoZoomFactor(FALSE);
            break;
        case VK_F1:
            UpdateHelperState();
            break;
         case VK_SPACE:
            OnLButtonDown(MK_LBUTTON, m_CurrentPoint);
            break;
        case VK_UP:
            pt.y -= (m_ShiftKeyPressed)?PIXEL_INCREMENTAL_MOVE:1;
            SetCursorPos(pt.x, pt.y);
            OnMouseMove(0, pt);
            break;
        case VK_DOWN:
            pt.y += (m_ShiftKeyPressed)?PIXEL_INCREMENTAL_MOVE:1;
            SetCursorPos(pt.x, pt.y);
            OnMouseMove(0, pt);
            break;
        case VK_LEFT:
            pt.x -= (m_ShiftKeyPressed)?PIXEL_INCREMENTAL_MOVE:1;
            SetCursorPos(pt.x, pt.y);
            OnMouseMove(0, pt);
            break;
        case VK_RIGHT:
            pt.x += (m_ShiftKeyPressed)?PIXEL_INCREMENTAL_MOVE:1;
            SetCursorPos(pt.x, pt.y);
            OnMouseMove(0, pt);
            break;
        case VK_SHIFT:
            m_ShiftKeyPressed = TRUE;
            break;
        }
    }
    else if(pMsg->message == WM_KEYUP) {

        switch (pMsg->wParam) {
        case VK_SHIFT:
            m_ShiftKeyPressed = FALSE;
            break;
        }        
    }

    return CDialog::PreTranslateMessage(pMsg);
}


void CWinCapture::OnRButtonDown(UINT nFlags, CPoint point) 
{
    CMenu Menu;

    if (m_CaptureType == CT_WINDOW) {
        Menu.LoadMenu(IDR_MENU_WINDOW_MODE);
    }
    else if (m_CaptureType == CT_REGION) {
        Menu.LoadMenu(IDR_MENU_REGION_MODE);

        if (!m_FirstDownClick) {
            Menu.EnableMenuItem(ID_POP_RESET_REGION, MF_BYCOMMAND|MF_GRAYED);
        }
    }
    else
        return;

    CMenu* pMenu = Menu.GetSubMenu(0);
    pMenu->SetDefaultItem(ID_POP_ACCEPT);
    pMenu->CheckMenuItem(ID_POP_TOGGLE_CURSOR,
                         MF_BYCOMMAND|(m_bShowCursor)?MF_CHECKED:MF_UNCHECKED);
    pMenu->CheckMenuItem(ID_POP_TOGGLE_HELP,
                         MF_BYCOMMAND|(m_pWinCaptureHelper.IsWindowVisible())?MF_CHECKED:MF_UNCHECKED);
    
    if (m_CaptureType == CT_REGION && !m_FirstDownClick)
        pMenu->EnableMenuItem(ID_POP_RESET_REGION, MF_BYCOMMAND|MF_GRAYED);
    
    ShowArrowCursor(TRUE, CPoint(10, 10));
    SuspendTimer();
    pMenu->TrackPopupMenu(TPM_RIGHTBUTTON, point.x+1, point.y+1, this, NULL);
    ShowArrowCursor(FALSE);
    SuspendTimer(FALSE);

    CDialog::OnRButtonDown(nFlags, point);
}

void CWinCapture::OnPopDismiss() {}

void CWinCapture::OnPopAccept() 
{
    OnLButtonDown(MK_LBUTTON, m_CurrentPoint);
}

void CWinCapture::OnPopAbort() 
{
    OnCancel();    
}

void CWinCapture::OnPopSwitchDesktop() 
{
    SuspendTimer();
    m_CaptureType = CT_DESKTOP;
    m_rcSnap.SetRect(0, 0, m_DesktopSize.cx, m_DesktopSize.cy);
    UpdateHelperState(FALSE, FALSE);
}

void CWinCapture::OnPopSwitchWindow() 
{
    m_CaptureType = CT_WINDOW;
    Invalidate();
    SuspendTimer(FALSE);
}

void CWinCapture::OnPopSwitchRegion() 
{
    OnPopResetRegion();
}

void CWinCapture::OnPopResetRegion() 
{
    SuspendTimer();
    m_FirstDownClick = FALSE;
    m_CaptureType    = CT_REGION;
}

void CWinCapture::OnPopToggleCursor() 
{
    m_bShowCursor = !m_bShowCursor;    
}

void CWinCapture::OnPopOptions() 
{
    COptionsDlg Dlg;
    
    if (m_CaptureType == CT_WINDOW) {

        Dlg.SetParams(this,
                      m_CMWDrawMode,
                      m_nCMWRectRoundWidth,
                      m_nCMWPenWidth,
                      m_Backcolor,
                      m_bCMWShowPos,
                      m_bPlaySound,
                      m_bShowHelp);
    }
    else if (m_CaptureType == CT_REGION) {

        Dlg.SetParams(this,
                      m_CMRDrawMode,
                      m_nCMRRectRoundWidth,
                      m_nCMRPenWidth,
                      m_Backcolor,
                      m_bCMRShowPos,
                      m_bPlaySound,
                      m_bShowHelp);
    }

    ShowArrowCursor(TRUE, CPoint(-1, -1));
    SuspendTimer();
    
    if (Dlg.DoModal() == IDOK) {

        if (m_CaptureType == CT_WINDOW) {

            Dlg.GetParams(m_CMWDrawMode,
                          m_nCMWRectRoundWidth,
                          m_nCMWPenWidth,
                          m_Backcolor,
                          m_bCMWShowPos,
                          m_bPlaySound,
                          m_bShowHelp);
        }
        else if (m_CaptureType == CT_REGION) {

            Dlg.GetParams(m_CMRDrawMode,
                          m_nCMRRectRoundWidth,
                          m_nCMRPenWidth,
                          m_Backcolor,
                          m_bCMRShowPos,
                          m_bPlaySound,
                          m_bShowHelp);
        }
    }

    ShowArrowCursor(FALSE);
    SuspendTimer(FALSE);
}

void CWinCapture::OnPopToggleHelp() 
{
    UpdateHelperState();
}


void CWinCapture::ShowArrowCursor(BOOL bShowArrow, CPoint pt)
{
    m_bRestoreCursorArrow = bShowArrow;

    if (pt != CPoint(-1, -1)) {
        SetCursorPos(m_CurrentPoint.x+pt.x , m_CurrentPoint.y+pt.y);
    }
}

void CWinCapture::SuspendTimer(BOOL bSuspend)
{
    if (m_CaptureType == CT_WINDOW) {
        if (bSuspend) {
            KillTimer(ID_TIMER_FRAME_RECT);
        }
        else {
            SetTimer(ID_TIMER_FRAME_RECT, TIMER_FRAME_RECT_ELAPSE, NULL);
        }
    }
}

void CWinCapture::UpdateHelperState(BOOL bShow, BOOL bSave)
{
    BOOL bVisible = m_pWinCaptureHelper.IsWindowVisible();

    if (bShow)
        m_pWinCaptureHelper.ShowWindow((!bVisible)?SW_SHOW:SW_HIDE);
    else
        m_pWinCaptureHelper.ShowWindow(SW_HIDE);

    if (bVisible || !bShow) {
        Sleep(SLEEP_TRACKED_INTERVAL);
        Invalidate();
    }

    if (bSave) {
        m_bShowHelp = m_pWinCaptureHelper.IsWindowVisible();
        SetRegInt("WinCapture", "ShowHelper", m_bShowHelp);
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO
Canada Canada

Comments and Discussions