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

📄 scemfimage.cpp

📁 Source code for EMFexplorer 1.0
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		m_iAngle += 360;
	ASSERT(m_iAngle>=0);
	SCComputeFitZoom();
	SCRefresh();	
}

void CSCEMFImage::SCRotateRight() 
{
	m_iAngle += 90;
	if (m_iAngle>=360)
		m_iAngle -= 360;
	ASSERT(m_iAngle>=0);
	SCComputeFitZoom();
	SCRefresh();	
}

///
/// Show or hide scrollbars as necessary.
///
void CSCEMFImage::InitializeScrollBars(int width, int height)
{
    RECT        rClient;
    SCROLLINFO  ScrollInfo;

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

    // If client size is equal 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_PAGE|SIF_RANGE;
    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);
}

///
/// Resize the scrollbars' page information.
///
void CSCEMFImage::SizeScrollBars(int uiWindowWidth, int uiWindowHeight)
{
	static BOOL m_bAdjusting = FALSE;
    // Only size for valid windows and dib info.
    // Don't SizeScrollBars 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;
    }
}

///
/// Scroll in answer to a scrollbar event.
///
BOOL CSCEMFImage::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);

    // 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;
}


//////////////////////////////////////////////////////////////////////////////////
// Scrolling events
//
void CSCEMFImage::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	ScrollChildWindow(SB_HORZ, nSBCode);
	CWnd::OnHScroll(nSBCode, nPos, pScrollBar);
}

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

//////////////////////////////////////////////////////////////////////////////////
// Page navigation events
//

void CSCEMFImage::SCGotoPage(int iPage) 
{
	if (!m_pEMFDoc || !m_pEMFDoc->SCGetNbPages())
		return;
	
	ASSERT(iPage>=1 && iPage<=(int)m_pEMFDoc->SCGetNbPages());

	// load
	m_hEmf = m_pEMFDoc->SCGetPageEMF(iPage-1);
	m_iCurPage = iPage;
	
	SCComputePageInfo(iPage);
	
	if (m_iFitMode!=SC_FIT_NONE)
		SCComputeFitZoom();
	
	SCComputeRowsCols();
	Invalidate();
}

void CSCEMFImage::SCGotoFirstPage() 
{
	SCComputeFitZoom();
	SCGotoPage(1);
}

void CSCEMFImage::SCGotoPrevPage() 
{
	SCGotoPage(m_iCurPage-1);
}

void CSCEMFImage::SCGotoNextPage() 
{
	SCGotoPage(m_iCurPage+1);
}

void CSCEMFImage::SCGotoLastPage() 
{
	SCGotoPage(SCGetNumPages());
}

//////////////////////////////////////////////////////////////////////////////////
// Creation/background events
//
int CSCEMFImage::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	return 0;
}

BOOL CSCEMFImage::OnEraseBkgnd(CDC* pDC) 
{
	return TRUE; // do not erase
	//return CWnd::OnEraseBkgnd(pDC);
}

//////////////////////////////////////////////////////////////////////////////////
// Other utilities
//
void CSCEMFImage::SCGetPageBlackBox(int iPage, CRect& rcElems)
{
	ASSERT(m_pEMFDoc);
	ASSERT(iPage);
	PSCEMFDocPage pDocPage = m_pEMFDoc->SCGetDocPage(iPage-1);

	ASSERT(pDocPage);
	pDocPage->SCGetPageBlackBox(rcElems);
}

void CSCEMFImage::SCGetPageSize(CSize& PgSize)
{
	if (m_pEMFDoc && m_pEMFDoc->SCGetNbPages())
		SCGetPageBlackBox((m_iCurPage) ? m_iCurPage: 1, m_rectPaper);
	else
		m_rectPaper.SetRectEmpty();
	m_rectPaper.InflateRect(m_rectMargins.left, m_rectMargins.top, m_rectMargins.right, m_rectMargins.bottom);

	// Note: the paper rectangle IS NOT rotated. It is considered as bound to the EMF.
	// So it rotates only when the playing DC is rotated.
	m_rectPaper.left = MulDiv(m_rectPaper.left, m_iCurZoom, SC_ZOOM100);
	m_rectPaper.right = MulDiv(m_rectPaper.right, m_iCurZoom, SC_ZOOM100);
	m_rectPaper.top = MulDiv(m_rectPaper.top, m_iCurZoom, SC_ZOOM100);
	m_rectPaper.bottom = MulDiv(m_rectPaper.bottom, m_iCurZoom, SC_ZOOM100);

	// Note: image dimensions ARE rotated
	PgSize.cx = m_rectPaper.Width();
	PgSize.cy = m_rectPaper.Height();
	switch (m_iAngle)
	{
	case 90:
	case 270:
		{// rotate
			SMC_ISWAP(PgSize.cx, PgSize.cy);
		}
		break;
	}
}

// number rows and columns by row
void CSCEMFImage::SCComputeRowsCols()
{
	CSize PgSize;
	SCGetPageSize(PgSize); // current page or nothing
	int iImgCx = PgSize.cx;
	int iImgCy = PgSize.cy;

	CRect rc;
	GetClientRect(rc);
	int iWndCx = rc.Width();
	int iWndCy = rc.Height();

	// try to set an y margin (for now, one row)
	if (iImgCy<iWndCy)
		m_iWorldCy = iWndCy;
	else
		m_iWorldCy = MIN_MARGIN*2 + iImgCy;
	ASSERT(m_iWorldCy>=iWndCy);

	// compute world dimensions for scrollbars
	if (iImgCx<iWndCx)
		m_iWorldCx = iWndCx;
	else
		m_iWorldCx = MIN_MARGIN*2 + iImgCx;
	ASSERT(m_iWorldCx>=iWndCx);

	// center
	m_iPgPosX = (m_iWorldCx - iImgCx)/2;
	m_iPgPosY = (m_iWorldCy - iImgCy)/2;
	ASSERT(m_iPgPosX>=0);
	ASSERT(m_iPgPosY>=0);
	InitializeScrollBars(m_iWorldCx, m_iWorldCy);
}

void CSCEMFImage::SCComputeFitZoom()
{
	if (!m_iCurPage || SC_FIT_NONE==m_iFitMode)
		return;

	// load page
	m_hEmf = m_pEMFDoc->SCGetPageEMF(m_iCurPage-1);
	if (!m_hEmf)
		return;

	// account for extra margins
	CRect rcElems;
	SCGetPageBlackBox(m_iCurPage, rcElems);
	CSize sizeEMF(rcElems.Width() + m_rectMargins.left + m_rectMargins.right + MIN_MARGIN*2,
		rcElems.Height() + m_rectMargins.top + m_rectMargins.bottom + MIN_MARGIN*2);
	// Rotate
	if ((90==m_iAngle || 270==m_iAngle))
	{
		SMC_ISWAP(sizeEMF.cx, sizeEMF.cy);
	}

	// Available client
	CRect rc;
	GetClientRect(rc);
	int iWndCx = rc.Width();
	int iWndCy = rc.Height();
#if 0
	// TODO: take care of the vertical scrollbar, if it would show
	if (SC_FIT_WIDTH==m_iFitMode)
	{
		// iWndCx -= GetSystemMetrics(SM_CXVSCROLL);
	}
#endif

	// scale
	float fScale;
	switch (m_iFitMode)
	{
	case SC_FIT_WIDTH:
		fScale = float(iWndCx)/float(sizeEMF.cx);
		break;

	case SC_FIT_PAGE:
		if (iWndCx>=iWndCy)
		{// attempt keep y, and reduce x
			fScale = float(iWndCy)/float(sizeEMF.cy);
			if (fScale*sizeEMF.cx > iWndCx)
				fScale = float(iWndCx)/float(sizeEMF.cx);
		} else
		{// attempt keep x, and reduce y
			fScale = float(iWndCx)/float(sizeEMF.cx);
			if (fScale*sizeEMF.cy > iWndCy)
				fScale = float(iWndCy)/float(sizeEMF.cy);
		}
		break;

	default:
		ASSERT(0);
		return;
	}

	m_iCurZoom = (int)(fScale*SC_ZOOM100);
	if (m_iCurZoom<SC_MIN_ZOOM)
		m_iCurZoom = SC_MIN_ZOOM;
	else
	if (m_iCurZoom>SC_MAX_ZOOM)
		m_iCurZoom = SC_MAX_ZOOM;
}

void CSCEMFImage::SCComputePageInfo(int iPage)
{
	ASSERT(m_pEMFDoc);
	ASSERT(iPage>=1 && iPage<=(int)m_pEMFDoc->SCGetNbPages());

	PSCEMFDocPage pDocPage = m_pEMFDoc->SCGetDocPage(iPage - 1);

	ASSERT(pDocPage);
	pDocPage->SCComputePageInfo(m_bReverseVideo, m_rectMargins);
}

/////////////////////////////////////////////////////////////////////////////
// CSCEMFImage printing

// Note: does not work!
void CSCEMFImage::SCPrintImage(CDC* pDC, CPrintInfo* pInfo, BOOL bFit/*=FALSE*/)
{
	if (!pDC)
		return;
	if (!m_pEMFDoc || !m_pEMFDoc->SCGetNbPages())
		return;

	// paper in logical coordinates
	CRect rcPaper = pInfo->m_rectDraw;
	int xDest = rcPaper.left;
	int yDest = rcPaper.top;

	HDC hDC = pDC->m_hDC;
	// We are going to seriously alter the DC (rotation, metafile playing, etc.).

⌨️ 快捷键说明

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