⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scwinthumbs.cpp

📁 Source code for EMFexplorer 1.0
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
*	This file is part of the EMFexplorer projet.
*	Copyright (C) 2004 Smith Charles.
*
*	This library is free software; you can redistribute it and/or
*	modify it under the terms of the GNU Lesser General Public
*	License as published by the Free Software Foundation; either
*	version 2.1 of the License, or (at your option) any later version.
*
*   This library is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*   Lesser General Public License for more details.
*
*   You should have received a copy of the GNU Lesser General Public
*   License along with this library; if not, write to the Free Software
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
*
*	Extension: for commercial use, apply the Equity Public License, which
*	adds to the normal terms of the GLPL a condition of donation to the author.
*   If you are interested in support for this source code,
*   contact Smith Charles <smith.charles@free.fr> for more information.
*/


#include "stdafx.h"
#include "SCWinThumbs.h"

#include "SCGDIUtils.h"
#include <math.h>

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

#define SC_PIX_TXTLINE		32

#define MIN_MARGIN			16
#define SHADOW_WDT			2
#define COL_SPACE			(MIN_MARGIN - (1+1+SHADOW_WDT))
#define ROW_SPACE			COL_SPACE

#define SC_CTL_SYSBKGN		LTGRAY_BRUSH			
#define SC_THUMB_SYSBKGN	COLOR_WINDOW

#define SC_THUMBNUM_COLOR	RGB(255, 255, 255)			
#define SC_THUMBNUM_WIDTH	MIN_MARGIN
#define SC_THUMBNUM_HEIGHT	MIN_MARGIN

#define SC_CURSEL_COLOR		RGB(0, 0, 255)
#define SC_CURSEL_VSTROKES	3
#define SC_CURSEL_HSTROKES	3

//	#define SC_UNSCALED_THUMBS
//	#define SC_FULL_DCPROTRECTION


/////////////////////////////////////////////////////////////////////////////
// CSCWinThumbs

CSCWinThumbs::CSCWinThumbs():
	m_pIThumbsHolder(NULL),
	m_ThumbsMinSize(32,32),
	m_ThumbsSize(32,32),
	m_iCurSel(-1),
	m_bAdjusting(FALSE),
	m_uiNbThumbs(0),
	m_bShowNum(TRUE),
	m_uiNbRows(1), 
	m_uiNbCols(1),
	m_iMarginX(0),
	m_iMarginY(0),
	m_iWorldCx(0),
	m_iWorldCy(0),
	m_pFont(NULL),
	m_bProgessDraw(TRUE),
	m_bLastSeen(FALSE)
{
}

CSCWinThumbs::~CSCWinThumbs()
{
	if (m_pFont)
		delete m_pFont;
}

void CSCWinThumbs::SCReset()
{
	m_iCurSel = -1;
	m_uiNbThumbs = 0;
	m_uiNbRows = 1; 
	m_uiNbCols = 1;
	m_iMarginX = 0;
	m_iMarginY = 0;
	m_iWorldCx = 0;
	m_iWorldCy = 0;
}

BEGIN_MESSAGE_MAP(CSCWinThumbs, CWnd)
	//{{AFX_MSG_MAP(CSCWinThumbs)
	ON_WM_PAINT()
	ON_WM_ERASEBKGND()
	ON_WM_HSCROLL()
	ON_WM_VSCROLL()
	ON_WM_SIZE()
	ON_WM_KEYDOWN()
	ON_WM_LBUTTONDOWN()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSCWinThumbs utilities

void CSCWinThumbs::SCInitCtl()
{
	CRect rc;
	GetClientRect(&rc);
	m_WorkMemDC.SCPrepareSurface(rc.Width(), rc.Height(), NULL);
	SCSizeScrollBars(rc.Width(), rc.Height());
	SCComputeRowsCols();
}

void CSCWinThumbs::SCSetThumbsHolder(I_SCThumbsHolder* pHolder, int iNbThumbs)
{
	SCReset();
	m_pIThumbsHolder = pHolder;
	m_uiNbThumbs = iNbThumbs;
	SCComputeRowsCols();
}

void CSCWinThumbs::SCPaint(CPaintDC &dc)
{
	CRect rcClient;
	GetClientRect(rcClient);
	int cx = rcClient.Width();
	int cy = rcClient.Height();
	ASSERT(m_WorkMemDC.m_hDC); // you must init it
	if (!m_WorkMemDC.m_hDC)
	{
		dc.PatBlt(0, 0, cx, cy, BLACKNESS);
		return;
	}

	{// paint non covered region
		CBrush brush;
		brush.CreateStockObject(SC_CTL_SYSBKGN);
		m_WorkMemDC.FillRect(&rcClient, &brush);
	}

	if (!m_pIThumbsHolder || (0==m_uiNbThumbs))
	{
		dc.StretchBlt(0, 0,	cx, cy,	&m_WorkMemDC, 0, 0, cx, cy, SRCCOPY);
		return;
	}
	
	COLORREF crBkColor = GetSysColor(SC_THUMB_SYSBKGN);
	CBrush BkBrush;
	BkBrush.CreateSolidBrush(crBkColor);

	int xScroll  = GetScrollPos(SB_HORZ);
	int yScroll  = GetScrollPos(SB_VERT);
	m_WorkMemDC.SetWindowOrg(xScroll, yScroll);
	int iWdt = m_ThumbsSize.cx; 
	int iHgt = m_ThumbsSize.cy; 
	int iImgCx = iWdt + COL_SPACE;
	int iImgCy = iHgt + ROW_SPACE;
	long uiThumbIdx;
	int iRowStart = yScroll/iImgCy;
	int iRowStop = 1+(yScroll+cy)/iImgCy;
	if (iRowStop>m_uiNbRows)
		iRowStop=m_uiNbRows;
	
	int iColStart = xScroll/iImgCx;
	int iColStop = 1+(xScroll+cx)/iImgCx;
	if (iColStop>m_uiNbCols)
		iColStop=m_uiNbCols;
	
	int xDest = m_iMarginX + iColStart*iImgCx;
	int yDest = m_iMarginY + iRowStart*iImgCy;
	for (int iRow = iRowStart; (iRow<iRowStop); iRow++)
	{
		// draw visible rows
		for (int iCol = iColStart; (iCol<iColStop); iCol++)
		{
			uiThumbIdx = iRow*m_uiNbCols + iCol;
			if (uiThumbIdx>=m_uiNbThumbs)
				break; // a row may be incomplete
			
			// draw visible columns
			CRect rcElem(xDest, yDest, xDest + iWdt, yDest + iHgt);

			// thumb background
			m_WorkMemDC.FillRect(&rcElem, &BkBrush);

			// thumb image
			PSCThumbImage pImage = m_pIThumbsHolder->SCGetThumbImage(uiThumbIdx);
			if (pImage)
			{
#ifdef SC_UNSCALED_THUMBS
				GReal fScaleXY = (GReal)pImage->GetWidth()/(GReal)pImage->GetHeight();
				GReal height = iHgt;
				GReal width = height*fScaleXY;
				if (width>iWdt)
				{
					width = (GReal)iWdt;
					height = width/fScaleXY;
				}
#else
				GReal height = (GReal)pImage->GetHeight();
				GReal width =  (GReal)pImage->GetWidth();
#endif
				GReal xPos = xDest + (iWdt - width)/2;
				GReal yPos = yDest + (iHgt - height)/2;

#ifdef SC_FULL_DCPROTRECTION
				// Normally, DrawImage shouldn't be able to write outside rcElem.
				// But with a metafile, maybe it could.
				int iState = m_WorkMemDC.SaveDC();
				m_WorkMemDC.IntersectClipRect(&rcElem);
#endif
				GGraphics graphics(m_WorkMemDC.GetSafeHdc());
				graphics.DrawImage(pImage, xPos, yPos, width, height);

#ifdef SC_FULL_DCPROTRECTION
				m_WorkMemDC.RestoreDC(iState);
#endif
			}
			
			// shadow
			SCDrawFrameAndShadow(&m_WorkMemDC, xDest, yDest, iWdt, iHgt, SHADOW_WDT, crBkColor);
			
			// thumb number
			if (m_bShowNum)
				SCDrawNumber(xDest, yDest, uiThumbIdx);

			// if we are on the current thumb, show selection
			if (uiThumbIdx==m_iCurSel)
			{
				CBrush Brush;
				Brush.CreateSolidBrush(SC_CURSEL_COLOR);
				
				CRgn Rgn;
				Rgn.CreateRectRgnIndirect(&rcElem);
				m_WorkMemDC.FrameRgn(&Rgn, &Brush, SC_CURSEL_VSTROKES, SC_CURSEL_HSTROKES);
				
				Rgn.DeleteObject();
				Brush.DeleteObject();
			}
			if (m_bProgessDraw && !m_bLastSeen)
			{// show progressively
				dc.StretchBlt(0, 0, cx, cy, &m_WorkMemDC, xScroll, yScroll, cx, cy, SRCCOPY);
			}
			xDest += iImgCx;
		}
		yDest += iImgCy;
		xDest = m_iMarginX;
	}
	m_WorkMemDC.SetWindowOrg(0, 0);

	dc.StretchBlt(0, 0,	cx, cy,	&m_WorkMemDC, 0, 0, cx, cy, SRCCOPY);
	if (uiThumbIdx==m_uiNbThumbs)
		m_bLastSeen = TRUE; // TODO: fix this or don't use it
	// Do not call CWnd::OnPaint()
}

void CSCWinThumbs::SCDrawNumber(int xDest, int yDest, UINT uiThumbIdx)
{
	CFont* pOldFont = (m_pFont) ? m_WorkMemDC.SelectObject(m_pFont) : NULL;
	COLORREF crOldColor = m_WorkMemDC.SetTextColor(SC_THUMBNUM_COLOR);
	int iOldBkMode = m_WorkMemDC.SetBkMode(TRANSPARENT);
	
	CRect rcNum(xDest, yDest, xDest + SC_THUMBNUM_WIDTH, yDest + SC_THUMBNUM_HEIGHT);
	CBrush brush;
	brush.CreateStockObject(BLACK_BRUSH);
	m_WorkMemDC.FillRect(&rcNum, &brush);
	
	CString strNum;
	strNum.Format(_T("%d"), uiThumbIdx);
	CSize size = m_WorkMemDC.GetTextExtent(strNum);
	m_WorkMemDC.TextOut(rcNum.left + (rcNum.Width()- size.cx)/2,
						rcNum.top + (rcNum.Height()- size.cy)/2,
						strNum, strNum.GetLength());
	
	m_WorkMemDC.SetBkMode(iOldBkMode);
	if (pOldFont)
		m_WorkMemDC.SelectObject(pOldFont);
	m_WorkMemDC.SetTextColor(crOldColor);
}

void CSCWinThumbs::SCInitializeScrollBars(int width, int height)
{
    RECT        rClient;
    SCROLLINFO  ScrollInfo;

    // Get windows client size.
    GetClientRect(&rClient);

    // If client size is equel to dib size, then add one to client size
    // so that we don't show scroll bars.
    // However, if client size is less than dib size, subtract scroll bar
    // size form client size so that page size will be correct when
    // scroll bars are shown.
    if (rClient.bottom == height)
        ++rClient.bottom;
    else if (rClient.bottom < height)
        rClient.bottom -= GetSystemMetrics (SM_CYHSCROLL);
    if (rClient.right == width)
        ++rClient.right;
    else if (rClient.right < width)
        rClient.right -= GetSystemMetrics (SM_CXVSCROLL);

    // Initialize vertical scroll bar.
    ScrollInfo.cbSize = sizeof(SCROLLINFO);
    ScrollInfo.fMask = SIF_ALL;
    ScrollInfo.nMin = 0;
    ScrollInfo.nMax = height;
    ScrollInfo.nPage = rClient.bottom;
    SetScrollInfo(SB_VERT, &ScrollInfo, TRUE);

    // Initialize horizontal scroll bar.
    ScrollInfo.nMax = width;
    ScrollInfo.nPage = rClient.right;
    SetScrollInfo(SB_HORZ, &ScrollInfo, TRUE);
}

BOOL CSCWinThumbs::ScrollChildWindow(int nScrollBar, UINT wScrollCode, int iCount /*=1*/)
{
    int         nPosition;
    int         nHorzScroll = 0;
    int         nVertScroll = 0;
    SCROLLINFO  ScrollInfo;

    // Get current scroll information.
	ZeroMemory(&ScrollInfo, sizeof(SCROLLINFO));
    ScrollInfo.cbSize = sizeof(SCROLLINFO);
    ScrollInfo.fMask = SIF_ALL;
    if (!GetScrollInfo(nScrollBar, &ScrollInfo))
	{
		int error = GetLastError();
		return FALSE;
	}
    nPosition = ScrollInfo.nPos;

    // Modify scroll information based on requested
    // scroll action.
    switch (wScrollCode)
    {
        case SB_LINEDOWN:
            ScrollInfo.nPos += SC_PIX_TXTLINE*iCount;
            break;

        case SB_LINEUP:
            ScrollInfo.nPos -= SC_PIX_TXTLINE*iCount;
            break;

        case SB_PAGEDOWN:
            ScrollInfo.nPos += ScrollInfo.nPage*iCount;
            break;

        case SB_PAGEUP:
            ScrollInfo.nPos -= ScrollInfo.nPage*iCount;
            break;

        case SB_TOP:
            ScrollInfo.nPos = ScrollInfo.nMin;
            break;

        case SB_BOTTOM:
            ScrollInfo.nPos = ScrollInfo.nMax;
            break;

            // Don't do anything.
        case SB_THUMBTRACK:
			return TRUE;

        case SB_THUMBPOSITION:
            ScrollInfo.nPos = ScrollInfo.nTrackPos;
            break;

        case SB_ENDSCROLL:
            default:
            return FALSE;
    }

    // Make sure that scroll position is in range.
    if (0 > ScrollInfo.nPos)
        ScrollInfo.nPos = 0;
    else if (ScrollInfo.nMax - (int) ScrollInfo.nPage + 1 < ScrollInfo.nPos)
        ScrollInfo.nPos = ScrollInfo.nMax  - ScrollInfo.nPage + 1;

    // Set new scroll position.
    ScrollInfo.fMask = SIF_POS;
    SetScrollInfo(nScrollBar, &ScrollInfo, TRUE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -