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

📄 scwinthumbs.cpp

📁 Source code for EMFexplorer 1.0
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    // Scroll window.
#if 0
	// scroll position is integrated to scpaint
    if (SB_VERT == nScrollBar)
        nVertScroll = nPosition - ScrollInfo.nPos;
    else
        nHorzScroll = nPosition - ScrollInfo.nPos;

	ScrollWindowEx(nHorzScroll, nVertScroll, NULL, NULL,
		NULL, NULL, SW_INVALIDATE);
#endif

	Invalidate();
	UpdateWindow();
    return TRUE;
}

void CSCWinThumbs::SCSizeScrollBars(int uiWindowWidth, int uiWindowHeight)
{
    // Only size for validte windows and dib info.
    // Don't SCSizeScrollBars if in process of adjusting them.
    if (IsWindow(m_hWnd) &&
        !m_bAdjusting)
    {
        int         nScrollHeight = GetSystemMetrics (SM_CXVSCROLL);
        int         nScrollWidth = GetSystemMetrics (SM_CYHSCROLL);
        SCROLLINFO  VertScrollInfo;
        SCROLLINFO  HorzScrollInfo;

        // Make sure that we don't get into an infinite loop when updating scroll bars.
        m_bAdjusting = TRUE;

        // Get current vertical scroll info.
        VertScrollInfo.cbSize = sizeof(SCROLLINFO);
        VertScrollInfo.fMask = SIF_ALL;
        GetScrollInfo(SB_VERT, &VertScrollInfo);

        // Get current horizontal scroll info.
        HorzScrollInfo.cbSize = sizeof(SCROLLINFO);
        HorzScrollInfo.fMask = SIF_ALL;
        GetScrollInfo(SB_HORZ, &HorzScrollInfo);

        // Update vertical scroll info.
        VertScrollInfo.fMask = SIF_PAGE;
        VertScrollInfo.nPage = uiWindowHeight;
		SetScrollInfo(SB_VERT, &VertScrollInfo, TRUE);

        // Update horizontal scroll info.
        HorzScrollInfo.fMask = SIF_PAGE;
        HorzScrollInfo.nPage = uiWindowWidth;
		SetScrollInfo(SB_HORZ, &HorzScrollInfo, TRUE);

        m_bAdjusting = FALSE;
    }
}

inline int CSCWinThumbs::SCNbColsInSpace(int iWndCx, int iImgCx)
{
	ASSERT(iImgCx>0);

	int iNbCols = (iWndCx + COL_SPACE - 2*MIN_MARGIN) / iImgCx;
	if (iNbCols<=0)
		return 1;
	
	if (iNbCols>m_uiNbThumbs)
		return m_uiNbThumbs;
	
	return iNbCols;
}

inline int CSCWinThumbs::SCNbRowsInCols(int iNbCols)
{
	ASSERT(iNbCols>0);

	int iNbRows = m_uiNbThumbs / iNbCols;
	if (m_uiNbThumbs % iNbCols)
		iNbRows++;
	
	return iNbRows;
}


void CSCWinThumbs::SCComputeRowsCols()
{
	if (!m_uiNbThumbs)
	{
		SCInitializeScrollBars(m_iWorldCx, m_iWorldCy);
		Invalidate();
		return;
	}

	CSize OldSize = m_ThumbsSize;
	int iImgCx = m_ThumbsMinSize.cx + COL_SPACE;
	int iImgCy = m_ThumbsMinSize.cy + ROW_SPACE;
	ASSERT(iImgCx && iImgCy);

	CRect rc;
	GetClientRect(rc);
	int iWndCx = rc.Width();
	int iWndCy = rc.Height();
	
	float fTotalSurface = float(iWndCx - 2*MIN_MARGIN)*float(iWndCy - 2*MIN_MARGIN);
	float fImgSurface = float(iImgCx)*float(iImgCy)*m_uiNbThumbs;
	if (fTotalSurface > 1.1f*fImgSurface)
	{
		fImgSurface = fTotalSurface/m_uiNbThumbs;
		iImgCy = (int)sqrt(fImgSurface);
		iImgCx = MulDiv(iImgCy, m_ThumbsMinSize.cx, m_ThumbsMinSize.cy);

		for (;iImgCx>m_ThumbsMinSize.cx && iImgCy>m_ThumbsMinSize.cy;)
		{
			int iNbCols = SCNbColsInSpace(iWndCx, iImgCx);
			int iNbRows = SCNbRowsInCols(iNbCols);
			int iColsSpan = iNbCols*iImgCx - COL_SPACE + 2*MIN_MARGIN;
			int iRowsSpan = iNbRows*iImgCy - ROW_SPACE + 2*MIN_MARGIN;
			if ((iNbCols*iImgCx - COL_SPACE + 2*MIN_MARGIN)>iWndCx)
			{
				iImgCx -= 5;
				iImgCy = MulDiv(iImgCx, m_ThumbsMinSize.cy, m_ThumbsMinSize.cx);
			} else
			if ((iNbRows*iImgCy - ROW_SPACE + 2*MIN_MARGIN)>iWndCy)
			{
				iImgCy -= 5;
				iImgCx = MulDiv(iImgCy, m_ThumbsMinSize.cx, m_ThumbsMinSize.cy);
			}
			else
				break;
		}

		m_ThumbsSize.cx = iImgCx - COL_SPACE;
		m_ThumbsSize.cy = iImgCy - ROW_SPACE;
	} else
	{
		m_ThumbsSize = m_ThumbsMinSize;
	}

	m_uiNbCols = SCNbColsInSpace(iWndCx, iImgCx);
	m_uiNbRows = SCNbRowsInCols(m_uiNbCols);

	// try to set an y margin (if one row)
	int iRowsSpan = m_uiNbRows*iImgCy - ROW_SPACE; // space used by rows
	if (iRowsSpan<iWndCy)
		m_iWorldCy = iWndCy;
	else
		m_iWorldCy = MIN_MARGIN*2 + iRowsSpan;
	ASSERT(m_iWorldCy>=iWndCy);

	// compute world dimensions for scrollbars
	int iColsSpan = m_uiNbCols*iImgCx - COL_SPACE; // space used by cols
	if (iColsSpan<iWndCx)
		m_iWorldCx = iWndCx;
	else
		m_iWorldCx = MIN_MARGIN*2 + iColsSpan;
	ASSERT(m_iWorldCx>=iWndCx);

	// center
	m_iMarginX = (m_iWorldCx - iColsSpan)/2;
	m_iMarginY = (m_iWorldCy - iRowsSpan)/2;
	ASSERT(m_iMarginX>=0);
	ASSERT(m_iMarginY>=0);
	SCInitializeScrollBars(m_iWorldCx, m_iWorldCy);

	if (OldSize!=m_ThumbsSize)
		m_pIThumbsHolder->SCSetThumbsSize(m_ThumbsSize);
}

// Compute the thumb containing a client space point
int CSCWinThumbs::SCComputeHitTest(CPoint point) 
{
	if (0==m_uiNbThumbs)
		return -1;

	// Message handler code here and/or call default
	int xScroll  = GetScrollPos(SB_HORZ);
	int yScroll  = GetScrollPos(SB_VERT);
	int iWdt = m_ThumbsSize.cx;
	int iHgt = m_ThumbsSize.cy;
	int iImgCx = iWdt + COL_SPACE;
	int iImgCy = iHgt + ROW_SPACE;

	int iPosY = yScroll + point.y;
	int iPosX = xScroll + point.x;
	int iPgRow = (iPosY - m_iMarginY) / iImgCy;
	int iPgCol = (iPosX - m_iMarginX) / iImgCx;
	int iThumbNum = iPgRow*m_uiNbCols + iPgCol;
	ASSERT(iPgRow>=0 && iPgCol>=0);

	// check thumb/col/row number overflows
	if (iThumbNum>=m_uiNbThumbs || iPgCol>=m_uiNbCols || iPgRow>=m_uiNbRows)
		iThumbNum = -1;
	else
	// check left and top bands
	if ((0==iPgCol && point.x<=m_iMarginX)||
		(0==iPgRow && point.y<=m_iMarginY))
		iThumbNum = -1;
	else
	// check right and bottom bands, and between columns or rows
	if ((iPosX >= (m_iMarginX + iPgCol*iImgCx + iWdt))||
		(iPosY >= (m_iMarginY + iPgRow*iImgCy + iHgt)))
		iThumbNum = -1;

	return iThumbNum;
}


///
/// Tell the parent that selection has changed.
///
void CSCWinThumbs::SCNotifyParent()
{
	CWnd *pParent = GetParent();
	
	ASSERT(pParent);
	if (!pParent)
		return;

	NMHDR nmhdr;
	nmhdr.code = THN_SELCHANGE;
	nmhdr.hwndFrom = m_hWnd;
	nmhdr.idFrom = GetDlgCtrlID();
	pParent->SendMessage(WM_NOTIFY, (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
}

void CSCWinThumbs::SCEnsureCurThumbVisible()
{
	if (0==m_uiNbThumbs)
		return;

	CRect rc;
	GetClientRect(&rc);
	int cy = rc.Height();
	int xScroll  = GetScrollPos(SB_HORZ);
	int yScroll  = GetScrollPos(SB_VERT);

	// Get thumb top in client coordinates
	int xThumbLeft;
	int yThumbTop;
	SCGetThumbPos(m_iCurSel, xThumbLeft, yThumbTop);

	int iBottom = yThumbTop + m_ThumbsSize.cy;
	if (iBottom >= cy)
	{// make bottom visible
		int iDeltaY = iBottom - cy;
		int iQuant = iDeltaY / SC_PIX_TXTLINE;
		if (iQuant<=0)
			iQuant = 1;
		else
		if (iDeltaY % SC_PIX_TXTLINE)
			iQuant++;
		ScrollChildWindow(SB_VERT, SB_LINEDOWN, iQuant);
	} else
	{// make top visible
		if (yThumbTop <= 0)
		{
			int iDeltaY = -yThumbTop;
			int iQuant = iDeltaY / SC_PIX_TXTLINE;
			if (iQuant<=0)
				iQuant = 1;
			else
			if (iDeltaY % SC_PIX_TXTLINE)
				iQuant++;
			ScrollChildWindow(SB_VERT, SB_LINEUP, iQuant);
		} else
		{
			Invalidate();
		}
	}
}

void CSCWinThumbs::SCGetThumbPos(int iThumbIdx, int& xThumbLeft, int& yThumbTop)
{
	ASSERT(iThumbIdx>=0 && iThumbIdx<m_uiNbThumbs);

	CSize ThSizeEx = m_ThumbsSize; // extended size of thumb
	ThSizeEx.cx += COL_SPACE;
	ThSizeEx.cy += ROW_SPACE;

	// remove scroll, and start with world margins
	yThumbTop = m_iMarginY - GetScrollPos(SB_VERT);
	xThumbLeft = m_iMarginX - GetScrollPos(SB_HORZ);

	// skip rows and cols
	yThumbTop  += (iThumbIdx / m_uiNbCols)*ThSizeEx.cy;
	xThumbLeft += (iThumbIdx % m_uiNbCols)*ThSizeEx.cx;
}

/////////////////////////////////////////////////////////////////////////////
// CSCWinThumbs message handlers

BOOL CSCWinThumbs::PreCreateWindow(CREATESTRUCT& cs) 
{
	cs.style |= WS_HSCROLL|WS_VSCROLL;
	return CWnd::PreCreateWindow(cs);
}

BOOL CSCWinThumbs::OnEraseBkgnd(CDC* pDC) 
{
	return TRUE;
	//return CWnd::OnEraseBkgnd(pDC);
}

void CSCWinThumbs::OnSize(UINT nType, int cx, int cy) 
{
	CWnd::OnSize(nType, cx, cy);
	
	// message handler code here
	ASSERT(cx && cy);
	if (!cx || !cy)
		return;

	m_WorkMemDC.SCPrepareSurface(cx, cy, NULL);
	SCSizeScrollBars(cx, cy);
	SCComputeRowsCols();
}

void CSCWinThumbs::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	SCPaint(dc);
}


void CSCWinThumbs::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	ScrollChildWindow(SB_HORZ, nSBCode);
	CWnd::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CSCWinThumbs::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	ScrollChildWindow(SB_VERT, nSBCode);
	CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
}

// Reading flow tracking
void CSCWinThumbs::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if (0==m_uiNbThumbs)
		return;

	switch(nChar)
	{
	case VK_RIGHT:
	case VK_DOWN:
		ScrollChildWindow(SB_VERT, SB_LINEDOWN); // temp
		break;

	case VK_LEFT:
	case VK_UP:
		ScrollChildWindow(SB_VERT, SB_LINEUP); // temp
		break;

//		case VK_DOWN:
//		case VK_UP:
//			break;

	case VK_HOME:
		ScrollChildWindow(SB_VERT, SB_TOP);
		break;

	case VK_END:
		ScrollChildWindow(SB_VERT, SB_BOTTOM);
		break;

	case VK_PRIOR: //VK_PAGE_UP:
		ScrollChildWindow(SB_VERT, SB_PAGEUP);
		break;

	case VK_NEXT: //VK_PAGE_DOWN:
		ScrollChildWindow(SB_VERT, SB_PAGEDOWN);
		break;
	}
	CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}


void CSCWinThumbs::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// Message handler code here and/or call default
	int iThumbNum = SCComputeHitTest(point);
	
	// location on thumb
	if (iThumbNum>=0 && iThumbNum!=m_iCurSel)
	{// move to this location
		m_iCurSel = iThumbNum;
		Invalidate();
		SCNotifyParent();
	}
	
	CWnd::OnLButtonDown(nFlags, point);
}

⌨️ 快捷键说明

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