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

📄 scemfdoc.cpp

📁 Source code for EMFexplorer 1.0
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*
*	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 "SCEMFDoc.h"

#include "SCGenInclude.h"
#include SC_INC_COMMON(kSCProdDefs.h)
#include SC_INC_WINLIB(SCWinFile.h)
#include SC_INC_ERRLIB(wErr.h)
#include SC_INC_SHARED(SCZipFile.h)
#include SC_INC_WINLIB(SCRegistry.h)


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

#define SC_EMFX_TMPFONT_EXT		_T(".eft")
#define SC_EMFX_TMPFRES_EXT		_T(".efr")
#define SC_EMFX_TEMPSUBDIR		SC_PRODUCTNAME
#define SC_EMFX_CLIP_FNAME		_T("Clipboard")


SCEMFDoc::SCEMFDoc():
	m_uiNbFiles(0),
	m_bDocModified(FALSE),
	m_bForgedName(FALSE)
{
}

SCEMFDoc::~SCEMFDoc()
{
	SCCleanup(TRUE);
	SCDeleteLockedFontFiles(TRUE);
}

void SCEMFDoc::SCCleanup(BOOL bClosing /*=FALSE*/)
{
	UINT uiNbPages = m_uiNbFiles;
	m_uiNbFiles = 0; // Won't serve pages after this, as we are deleting them

	// Proceed with clean up
	for (UINT i=0; (i<uiNbPages); i++)
	{
		delete m_vDocPages[i];
	}
	m_vDocPages.clear();
	SCUnInstallFonts();
	m_strUniDocName.Empty();
	m_bForgedName = FALSE;
}

void SCEMFDoc::SCSetPageURL(UINT uiPage, LPCTSTR lpszURL)
{
	ASSERT(uiPage<m_uiNbFiles);
	if (uiPage<m_uiNbFiles)
		m_vDocPages[uiPage]->m_strCreditURL = lpszURL;
}

void SCEMFDoc::SCSetPageCredit(UINT uiPage, LPCTSTR lpszCredit)
{
	ASSERT(uiPage<m_uiNbFiles);
	if (uiPage<m_uiNbFiles)
		m_vDocPages[uiPage]->m_strCredit = lpszCredit;
}

void SCEMFDoc::SCSetPageComment(UINT uiPage, LPCTSTR lpszComment)
{
	ASSERT(uiPage<m_uiNbFiles);
	if (uiPage<m_uiNbFiles)
		m_vDocPages[uiPage]->m_strComment = lpszComment;
}

PSCEMFDocPage SCEMFDoc::SCGetDocPage(UINT uiPage, BOOL bGetCopy/*=FALSE*/)
{
	ASSERT(uiPage<m_uiNbFiles);
	PSCEMFDocPage pDocPage = NULL;
	if (uiPage<m_uiNbFiles)
	{
		ASSERT(m_vDocPages[uiPage]);
		if (bGetCopy)
		{
			pDocPage = new SCEMFDocPage(this);
			pDocPage->SCCopyFrom(*m_vDocPages[uiPage]);
		} else
			pDocPage = m_vDocPages[uiPage];
	}
	return pDocPage;
}

HENHMETAFILE SCEMFDoc::SCUnlockEMF(UINT uiPage, PSCEMFDocPage pShare/*=NULL*/)
{
	ASSERT(uiPage<m_uiNbFiles);
	PSCEMFDocPage pDocPage = m_vDocPages[uiPage];
	ASSERT(pDocPage);
	HENHMETAFILE hMemEMF = pDocPage->SCUnlockEMF();
	if (pShare)
		pShare->m_hEMF = hMemEMF;
	return hMemEMF;
}

void SCEMFDoc::SCForgeDocName(LPCTSTR lpszFname)
{// forge a doc name
	m_strUniDocName = lpszFname;
	int iPos = m_strUniDocName.ReverseFind(_T('.'));
	if (iPos!=-1)
		m_strUniDocName = m_strUniDocName.Left(iPos);
	m_strUniDocName += SC_DOC_EXTENSION;
	m_bForgedName = TRUE;
}

void SCEMFDoc::SCRemovePage(UINT uiPage)
{
	ASSERT(uiPage<m_uiNbFiles);

	delete m_vDocPages[uiPage];
	m_vDocPages.erase(m_vDocPages.begin() + uiPage);
	m_uiNbFiles--;
	if ((0==m_uiNbFiles) && m_bForgedName)
		SCCleanup();
	m_bDocModified = TRUE;
}

BOOL SCEMFDoc::SCReflow(DOCPAGEVECTOR& rvectReflow, INTVECTOR& rvectDescrip, LPCTSTR lpszDocDir, int iDlftCrdPage)
{
	UINT uiNbElems = rvectReflow.size();

	ASSERT(rvectDescrip.size()==uiNbElems);
	ASSERT(lpszDocDir);
	ASSERT(iDlftCrdPage<(int)uiNbElems);
	{
		CString strOldDocDir;
		TCHAR szDrive[_MAX_DRIVE];
		TCHAR szDir[_MAX_DIR];
		TCHAR szFname[_MAX_FNAME];
		TCHAR szExt[_MAX_EXT];
		SCSplitPath(m_strUniDocName, szDrive, szDir, szFname, szExt);
		
		strOldDocDir.Format(_T("%s%s"), szDrive, szDir);
		if (0!=strOldDocDir.CompareNoCase(lpszDocDir))
			m_strUniDocName.Format(_T("%s%s%s"), lpszDocDir, szFname, szExt);
	}

	PSCEMFDocPage pEPage;
	// Detach old EMFs
	for (UINT uiPage=0; (uiPage<uiNbElems); uiPage++)
	{
		int iIdx = rvectDescrip[uiPage];
		if (iIdx>=0)
		{
			ASSERT(iIdx<m_uiNbFiles);
			pEPage=m_vDocPages[iIdx];
			ASSERT(pEPage);
			if (pEPage)
				pEPage->SCDetachEMF();
		}
	}
	// Delete old objects
	for (uiPage=0; (uiPage<m_uiNbFiles); uiPage++)
	{
		if (pEPage=m_vDocPages[uiPage])
			delete pEPage;
	}
	m_vDocPages.clear();
	// Copy new objects
	m_vDocPages.resize(uiNbElems);
	m_vDocPages.assign(rvectReflow.begin(), rvectReflow.end());
	rvectReflow.clear();

	m_uiNbFiles = m_vDocPages.size();

	if (iDlftCrdPage<0)
	{
		m_Properties.strCreditURL.Empty();
		m_Properties.strCredit.Empty();
	} else
	{
		pEPage=m_vDocPages[iDlftCrdPage];
		m_Properties.strCreditURL = pEPage->m_strCreditURL;
		m_Properties.strCredit = pEPage->m_strCredit;
	}

	m_bDocModified = TRUE;
	return TRUE;
}

void SCEMFDoc::SCBeginAddFiles(UINT uiNbFiles, LPCTSTR lpszFName/*=NULL*/)
{
	SCCleanup();
	if (lpszFName)
		m_strUniDocName = lpszFName;
	
	// pages bank
	if (uiNbFiles)
	{
		m_vDocPages.resize(uiNbFiles);
		m_uiNbFiles = uiNbFiles;
		m_vDocPages.assign(m_uiNbFiles, NULL);
	}
}

void SCEMFDoc::SCEndAddFiles()
{
	SCInstallFonts();
}

void SCEMFDoc::SCSetDocDir(LPCTSTR lpszDocDir)
{
	DWORD dwLen = (lpszDocDir) ? _tcslen(lpszDocDir) : 0;
	ASSERT(dwLen);
	ASSERT(!m_strUniDocName.IsEmpty());
	CString strOldDocDir = SCMakeupDocDir(m_strUniDocName);

	ASSERT(strOldDocDir.IsEmpty()||
		strOldDocDir.CompareNoCase(lpszDocDir)==0);
	if (strOldDocDir.IsEmpty())
	{
		ASSERT(m_bForgedName);
		if (lpszDocDir[dwLen-1]!=_T('\\'))
			m_strUniDocName.Insert(0, _T('\\'));
		m_strUniDocName.Insert(0, lpszDocDir);
	}
	SCInstallFonts();
}

BOOL SCEMFDoc::SCAddFile(LPCTSTR lpszFname, UINT uiIdx, BOOL bCopy/*=TRUE*/, BOOL bDelayed/*=FALSE*/)
{
	ASSERT(uiIdx<m_uiNbFiles);
	if (uiIdx>=m_uiNbFiles)
		return FALSE;

	BOOL bError = FALSE;
	// check filetype
	UINT uiFyleType = SC_FSTATE_DELAYED; 
	if (!bDelayed)
	{
		uiFyleType = SCGetFileType(lpszFname, FALSE);
		switch (uiFyleType & SC_FTYPE_MASK)
		{
		case SC_FTYPE_EMF:
		case SC_FTYPE_WMF:
		case SC_FTYPE_EMZ:
		case SC_FTYPE_WMZ:
		case SC_FTYPE_IMG:
		case SC_FTYPE_TXT:
			break;
			
		case SC_FTYPE_UKN:
		default:
			bError = TRUE;
			// delay loading, so that user can use reflow to replace the file
			uiFyleType = SC_FSTATE_DELAYED;
		}
	}
	SCEMFDocPage* pDocPage = new SCEMFDocPage(this);
	m_vDocPages[uiIdx] = pDocPage;

	// set information for delayed loading
	pDocPage->m_uiType = uiFyleType;
	pDocPage->m_strPath = lpszFname;

	if (!bError && m_strUniDocName.IsEmpty())
		SCForgeDocName(lpszFname);
	return TRUE;
}

BOOL SCEMFDoc::SCLoadRTFPages(LPCTSTR lpszFname, BOOL bPaste/*=FALSE*/, BOOL bRTF/*=TRUE*/)
{
	HEMFVECTOR vectHandles;
	UINT uiNbPages = SCConvertRTFtoEMF(lpszFname, vectHandles, bRTF);
	if (0==uiNbPages)
		return FALSE;

	UINT uiStartIdx=0;
	if (bPaste)
	{
		uiStartIdx = m_uiNbFiles;
		m_uiNbFiles += uiNbPages;
		m_vDocPages.resize(m_uiNbFiles);
	} else
		SCBeginAddFiles(uiNbPages);

	// EMFs are just in memory, like a paste: don't forge unidoc name
	CString strPrefix = SCFNameExtFromPath(lpszFname);
	int iPos = strPrefix.ReverseFind(_T('.'));
	if (iPos!=-1)
		strPrefix.SetAt(iPos, _T('_'));
	if (!m_strUniDocName.IsEmpty())
	{
		CString strDir;
		TCHAR drive[_MAX_DRIVE];	// drive of the playlist
		TCHAR dir[_MAX_DIR];		// dir of the playlist
		_tsplitpath(LPCTSTR(m_strUniDocName), drive, dir, NULL, NULL);
		strDir.Format(_T("%s%s"), drive, dir);
		strPrefix = strDir + strPrefix;
	}

	CString strFname;
	for (UINT uiIdx=uiStartIdx; (uiIdx<m_uiNbFiles); uiIdx++)
	{
		SCEMFDocPage* pDocPage = new SCEMFDocPage(this);
		m_vDocPages[uiIdx] = pDocPage;

		strFname.Format(_T("%s_p%d.emf"), strPrefix, (uiIdx - uiStartIdx)+1);
		pDocPage->m_bDirty = TRUE;
		pDocPage->SCAttachEMF(vectHandles[uiIdx - uiStartIdx],
			strFname, SC_FILETYPE_EMFONLY);
	}

	if (!bPaste)
		SCEndAddFiles();
	m_bDocModified = TRUE; // pages are just in memory
	return TRUE;
}

BOOL SCEMFDoc::SCGrowBank(int iNbPages)
{
	m_uiNbFiles += iNbPages;
	m_vDocPages.resize(m_uiNbFiles);
	return TRUE;
}

BOOL SCEMFDoc::SCPasteEMFPages(HEMFVECTOR& rVector)
{
	int iNbPages = rVector.size();
	if (0==iNbPages)
		return FALSE;

	UINT uiNewNbPages = m_uiNbFiles + iNbPages;
	m_vDocPages.resize(uiNewNbPages);

	// Folder of the new files
	CString strDir;
	if (!m_strUniDocName.IsEmpty())
	{
		TCHAR drive[_MAX_DRIVE];	// drive of the playlist
		TCHAR dir[_MAX_DIR];		// dir of the playlist
		_tsplitpath(LPCTSTR(m_strUniDocName), drive, dir, NULL, NULL);
		strDir.Format(_T("%s%s"), drive, dir);
	}

	// Name and paste the files
	static UINT s_uiClipNum = 0;
	CString strClipFname;
	for (UINT uiIdx=m_uiNbFiles; (uiIdx<uiNewNbPages); uiIdx++)
	{
		SCEMFDocPage* pDocPage = new SCEMFDocPage(this);
		m_vDocPages[uiIdx] = pDocPage;

		strClipFname.Format(_T("%s%s%d.emf"), strDir, SC_EMFX_CLIP_FNAME, ++s_uiClipNum);
		pDocPage->m_bDirty = TRUE;
		pDocPage->SCAttachEMF(rVector[uiIdx - m_uiNbFiles],
			strClipFname, SC_FILETYPE_EMFONLY);
	}

	m_uiNbFiles = uiNewNbPages;
	m_bDocModified = TRUE; // some pages are just in memory
	return TRUE;
}


HENHMETAFILE SCEMFDoc::SCGetPageEMF(UINT uiPage)
{
	ASSERT(uiPage<m_uiNbFiles);
	if (uiPage>=m_uiNbFiles)
		return NULL;
	return m_vDocPages[uiPage]->SCGetPageEMF();
}

void SCEMFDoc::SCResizeAllPages()
{
	m_Properties.bSizeAllPages = !m_Properties.bSizeAllPages;
	if (!m_Properties.rectDocument.IsRectEmpty())
	{
		if (m_Properties.bSizeAllPages)
		{// apply
			for (UINT uiPage=0; (uiPage<m_uiNbFiles); uiPage++)
			{
				PSCEMFDocPage pDocPage = m_vDocPages[uiPage];
				ASSERT(pDocPage);
				pDocPage->m_rectSize = m_Properties.rectDocument;
			}
		} else
		{// restore
			for (UINT uiPage=0; (uiPage<m_uiNbFiles); uiPage++)
			{
				PSCEMFDocPage pDocPage = m_vDocPages[uiPage];
				ASSERT(pDocPage);
				pDocPage->SCRecomputeElemsRect();
				if (pDocPage->m_bInflate)
					pDocPage->m_rectSize.InflateRect(pDocPage->m_rectInflate);
			}
		}

⌨️ 快捷键说明

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