📄 scemfdoc.cpp
字号:
/*
* 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 + -