📄 scemfdoc.cpp
字号:
m_bDocModified = TRUE;
return bInserted;
}
///
/// Load the main data format supported by this class (enlist pages)
///
BOOL SCEMFDoc::SCLoadMaster(LPCTSTR lpszPathName, BOOL bInsert/*=FALSE*/)
{
ASSERT(lpszPathName);
ASSERT(FALSE==bInsert);// not supported yet
// Note: in this version, absolute file names are not supported even if they appear
// in the master. So directory information is stripped out.
TCHAR szDocDrive[_MAX_DRIVE]; // drive of the playlist
TCHAR szDocDir[_MAX_DIR]; // dir of the playlist
TCHAR szFname[_MAX_FNAME]; // name of a file
TCHAR szExt[_MAX_EXT]; // ext of a file
_tsplitpath(lpszPathName, szDocDrive, szDocDir, NULL, NULL);
TCHAR szBuff[MAX_PATH];
// Number of files
::GetPrivateProfileString(SC_DOC_GEN_SECTION, SC_DOC_NBFILES_KEY, _T(""),
szBuff, MAX_PATH, lpszPathName);
TCHAR szTxtBuff[SC_PGCOMMENT_MAXSIZE];
UINT uiNbFiles = _ttoi(szBuff);
SCBeginAddFiles(uiNbFiles, lpszPathName);
for (UINT nFile=0; (nFile<uiNbFiles); nFile++)
{
CString strKey;
strKey.Format(SC_DOC_FILEKEY_FORMAT, nFile);
::GetPrivateProfileString(SC_DOC_FILES_SECTION, strKey, _T(""),
szBuff, MAX_PATH, lpszPathName);
_tsplitpath(szBuff, NULL, NULL, szFname, szExt);
strKey.Format(_T("%s%s%s%s"), szDocDrive, szDocDir, szFname, szExt);
SCAddFile(LPCTSTR(strKey), nFile, TRUE, (nFile>0));
// Page attributes
CString strPgSection;
strPgSection.Format(SC_DOC_PGSECTION_FORMAT, nFile);
::GetPrivateProfileString(strPgSection, SC_DOC_URL_KEY, _T(""),
szTxtBuff, SC_PGCOMMENT_MAXSIZE, lpszPathName);
SCSetPageURL(nFile, szTxtBuff);
::GetPrivateProfileString(strPgSection, SC_DOC_CREDIT_KEY, _T(""),
szTxtBuff, SC_PGCOMMENT_MAXSIZE, lpszPathName);
SCSetPageCredit(nFile, szTxtBuff);
::GetPrivateProfileString(strPgSection, SC_DOC_COMMENT_KEY, _T(""),
szTxtBuff, SC_PGCOMMENT_MAXSIZE, lpszPathName);
SCSetPageComment(nFile, szTxtBuff);
}
SCEndAddFiles();
SCLoadSettings();
return TRUE;
}
// Load a single file (enlist one file)
BOOL SCEMFDoc::SCLoadSinglePage(LPCTSTR lpszFname, UINT uiFyleType, BOOL bInsert/*=FALSE*/)
{
ASSERT(lpszFname);
ASSERT(uiFyleType!=SC_FTYPE_UKN);
if (bInsert)
{
UINT uiIdx = m_uiNbFiles;
if (!SCGrowBank(1))
return FALSE;
SCAddFile(lpszFname, uiIdx, TRUE, TRUE);
m_vDocPages[uiIdx]->m_uiType = uiFyleType;
} else
{
SCBeginAddFiles(1);
SCAddFile(lpszFname, 0, TRUE, TRUE);
m_vDocPages[0]->m_uiType = uiFyleType;
SCEndAddFiles();
}
return TRUE;
}
///
/// Save the main data format supported by this class
///
BOOL SCEMFDoc::SCSaveDocument(LPCTSTR lpszPathName/*==NULL*/)
{
CString strPathName = (lpszPathName) ? lpszPathName : m_strUniDocName;
ASSERT(!strPathName.IsEmpty());
CString strDocDir = SCMakeupDocDir(strPathName);
CString strOldDocDir = SCMakeupDocDir(m_strUniDocName);
BOOL bCopyFiles = (strDocDir!=strOldDocDir);
// Main section
// erase sections
::WritePrivateProfileString(SC_DOC_GEN_SECTION, NULL, NULL, strPathName);
::WritePrivateProfileString(SC_DOC_FILES_SECTION, NULL, NULL, strPathName);
// ID
::WritePrivateProfileString(SC_DOC_GEN_SECTION, SC_DOC_FILEID_KEY, SC_DOC_FILEID_VALUE, strPathName);
// NbFiles
SCWritePrivateProfileInt(SC_DOC_GEN_SECTION, SC_DOC_NBFILES_KEY, m_uiNbFiles, strPathName);
// Files
BOOL bOneDirty = FALSE;
for (UINT uiPage=0; (uiPage<m_uiNbFiles); uiPage++)
{
PSCEMFDocPage pPage = m_vDocPages[uiPage];
ASSERT(pPage);
ASSERT(pPage->m_strPath);
CString strPagePath;
{// Note: in this version, absolute paths are not supported. Strip them out
strPagePath = SCFNameExtFromPath(pPage->m_strPath);
ASSERT(!strPagePath.IsEmpty());
}
// File EMF
if (pPage->m_bDirty)
{
ASSERT(pPage->m_hEMF);
if (pPage->m_hEMF)
{
CString strSavePath = strDocDir + strPagePath;
BOOL bExist = SCExistFile(strSavePath);
{// Note: in this version, bDirty means "new page"
// Ensure that the file is unique
int iPos = strSavePath.ReverseFind(_T('.'));
CString strPrefix;
CString strExt;
if (iPos!=-1)
{
strPrefix = strSavePath.Left(iPos); // exclude dot
strExt = strSavePath.Right(strSavePath.GetLength()-iPos); // include dot
} else
{
ASSERT(0);
strPrefix = strSavePath;
}
for (UINT i=1; (bExist && i<65635); i++)
{
strSavePath.Format(_T("%s_%d%s"), strPrefix, i, strExt);
bExist = SCExistFile(strSavePath);
}
strPagePath = SCFNameExtFromPath(strSavePath);
pPage->m_strPath = strPagePath;
}
if (SCWriteEMFtoDisk(pPage->m_hEMF, strSavePath))
pPage->m_bDirty = FALSE;
}
if (pPage->m_bDirty)
{
bOneDirty = TRUE;
continue;
}
} else
if (bCopyFiles)
{// copy file
CString strSavePath = strDocDir + strPagePath;
CString strOldPath = strOldDocDir + strPagePath;
// Note: we are overwriting files!
if (!::CopyFile(strOldPath, strSavePath, FALSE))
bOneDirty = TRUE;
}
// File path
CString strKey;
strKey.Format(SC_DOC_FILEKEY_FORMAT, uiPage);
::WritePrivateProfileString(SC_DOC_FILES_SECTION, strKey,
strPagePath, strPathName);
// Page attributes
CString strPgSection;
strPgSection.Format(SC_DOC_PGSECTION_FORMAT, uiPage);
::WritePrivateProfileString(strPgSection, NULL,
NULL, strPathName);
if (!pPage->m_strCreditURL.IsEmpty())
::WritePrivateProfileString(strPgSection, SC_DOC_URL_KEY,
pPage->m_strCreditURL, strPathName);
if (!pPage->m_strCredit.IsEmpty())
::WritePrivateProfileString(strPgSection, SC_DOC_CREDIT_KEY,
pPage->m_strCredit, strPathName);
if (!pPage->m_strComment.IsEmpty())
::WritePrivateProfileString(strPgSection, SC_DOC_COMMENT_KEY,
pPage->m_strComment, strPathName);
}
// Settings
SCSaveSettings(strPathName);
// Is it clean?
m_bDocModified = bOneDirty;
m_bForgedName = FALSE;
return (!m_bDocModified);
}
//////////////////////////////////////////////////////////////////////////////////
// Static
BOOL SCEMFDoc::SCIsNativeDoc(LPCTSTR lpszFname)
{
TCHAR szBuff[MAX_PATH];
::GetPrivateProfileString(SC_DOC_GEN_SECTION, SC_DOC_FILEID_KEY, _T(""), szBuff, MAX_PATH, lpszFname);
CString strValue = szBuff;
if (!strValue.IsEmpty() &&
(strValue.CompareNoCase(SC_DOC_FILEID_VALUE)==0))
return TRUE;
return FALSE;
}
CString SCEMFDoc::SCDocFileFromList(CStringList& rLFiles)
{
POSITION pos = rLFiles.GetHeadPosition();
int iNumFiles = rLFiles.GetCount();
if (1==iNumFiles)
{// If one file, do not create playlist file
return rLFiles.GetNext(pos);
}
CString strDocName;
WORD nFound = 0;
while (pos)
{
CString strFile = rLFiles.GetNext(pos);
if (SCEMFDoc::SCIsNativeDoc(strFile))
{// playlist found in the group
if (1==iNumFiles)
{
strDocName = strFile;
break;
}
// dont mix: ignore playlist
continue;
}
if (strDocName.IsEmpty())
{// Build the doc name (new playlist) and write the number of files
strDocName = SCEMFDoc::SCDocNameFromFilename(strFile);
if (strDocName.IsEmpty())
break; // could not create temp file
// erase sections
::WritePrivateProfileString(SC_DOC_GEN_SECTION, NULL, NULL, strDocName);
::WritePrivateProfileString(SC_DOC_FILES_SECTION, NULL, NULL, strDocName);
// ID
::WritePrivateProfileString(SC_DOC_GEN_SECTION, SC_DOC_FILEID_KEY, SC_DOC_FILEID_VALUE, strDocName);
}
// Store the file path
{
CString strKey;
strKey.Format(SC_DOC_FILEKEY_FORMAT, nFound);
::WritePrivateProfileString(SC_DOC_FILES_SECTION, strKey, strFile, strDocName);
nFound++;
}
}
if (!strDocName.IsEmpty())
{// Open the document
// Update nb files only if a new playlist was created
if (nFound)
{
ASSERT(nFound<=iNumFiles);
CString strValue;
strValue.Format(_T("%d"), nFound);
::WritePrivateProfileString(SC_DOC_GEN_SECTION, SC_DOC_NBFILES_KEY, strValue, strDocName);
}
}
return strDocName;
}
UINT SCEMFDoc::SCGetFileType(LPCTSTR lpszFname, BOOL bShowError/*=TRUE*/)
{
{// Check special headers (bgp)
TCHAR szBuff[MAX_PATH];
::GetPrivateProfileString(SC_DOC_GEN_SECTION, SC_DOC_FILEID_KEY, _T(""), szBuff, MAX_PATH, lpszFname);
CString strValue = szBuff;
if (!strValue.IsEmpty() &&
(strValue.CompareNoCase(SC_DOC_FILEID_VALUE)==0))
return SC_FTYPE_BGP;
}
UINT uiMode = SetErrorMode(SEM_FAILCRITICALERRORS);
// Open the file for reading.
HANDLE hFile = CreateFile(lpszFname, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
SetErrorMode(uiMode);
#if 1
// TODO: add string to resource, or don't use it
if (bShowError)
{
DWORD dwError = GetLastError();
CString strMsg;
strMsg.Format(_T("Unable to open %s"), lpszFname);
SCShowWinError(dwError, SC_PRODUCTNAME, strMsg);
}
#endif
return (SC_FSTATE_NOTFOUND|SC_FTYPE_UKN);
}
UINT uiType = SC_FTYPE_UKN;
// Load file type
ENHMETAHEADER hdrBuff;
DWORD dwRead;
BOOL bResult;
// wmf header
bResult = ReadFile(hFile, &hdrBuff, 22, &dwRead, NULL);
if (bResult && (22==dwRead))
{// file is long enough
BYTE* pdwKey = (BYTE*)&hdrBuff;
if (*((DWORD*)pdwKey)==WMFMETA_PLACEABLEKEY)
uiType = SC_FILETYPE_WMF; // Aldus wmf
else
if (EMR_HEADER==*((DWORD*)pdwKey))
{// check emf header
pdwKey += 22;
bResult = ReadFile(hFile, pdwKey, sizeof(ENHMETAHEADER) - 22, &dwRead, NULL) ;
if (bResult && (sizeof(ENHMETAHEADER) - 22==dwRead))
{// file is long enough
if (ENHMETA_SIGNATURE==hdrBuff.dSignature)
{
uiType = SC_FILETYPE_EMFONLY;
}
}
}
if (SC_FTYPE_UKN==uiType)
{// check Windows wmf
METAHEADER *pWinWMFHdr = (METAHEADER*)&hdrBuff;
if ((1==pWinWMFHdr->mtType || 2==pWinWMFHdr->mtType) &&
(0x0100==pWinWMFHdr->mtVersion || 0x0300==pWinWMFHdr->mtVersion))
{
uiType = SC_FILETYPE_WMF;
}
}
if (SC_FTYPE_UKN==uiType && SCIsGZCandidate((LPBYTE)&hdrBuff, 22))
{// check compressed Windows emf/wmf
if (SCUnzipGZFilePart(lpszFname, (LPBYTE)&hdrBuff, sizeof(ENHMETAHEADER)))
{
pdwKey = (BYTE*)&hdrBuff;
if (WMFMETA_PLACEABLEKEY==*((DWORD*)pdwKey))
uiType = SC_FTYPE_WMZ; // Aldus wmf
else
if (EMR_HEADER==*((DWORD*)pdwKey) &&
ENHMETA_SIGNATURE==hdrBuff.dSignature)
{
uiType = SC_FTYPE_EMZ; // emf
} else
{
METAHEADER *pWinWMFHdr = (METAHEADER*)&hdrBuff;
if ((1==pWinWMFHdr->mtType || 2==pWinWMFHdr->mtType) &&
(0x0100==pWinWMFHdr->mtVersion || 0x0300==pWinWMFHdr->mtVersion))
{
uiType = SC_FTYPE_WMZ; // Windows wmf
}
}
}
}
}
CloseHandle(hFile);
SetErrorMode(uiMode);
if (uiType != SC_FTYPE_UKN)
return uiType;
// images
#pragma message( __FILE__ "(1129): TODO: Review image filetype detection")
// we would like a detection by content, not by extension
uiType = SCFileTypeFromExt(lpszFname, TRUE);
return uiType;
}
CString SCEMFDoc::SCDocNameFromFilename(LPCTSTR lpszFname)
{
if (!SCIsWriteableMedia(lpszFname))
{// If we can't write on the media, use a temp file
TCHAR szPath[MAX_PATH];
TCHAR szBuff[MAX_PATH];
DWORD dwLength = ::GetTempPath(MAX_PATH, szPath);
if ((dwLength>0)
&& (dwLength<MAX_PATH)
&& ::GetTempFileName(szPath, _T("EMX"), 0, szBuff))
{
CString strDocName = szBuff;
return strDocName;
}
return _T("");
}
CString strBaseName = lpszFname;
int iPos = strBaseName.ReverseFind(_T('.'));
if (iPos!=-1)
strBaseName = strBaseName.Left(iPos);
CString strDocName = strBaseName + SC_DOC_EXTENSION;
// Ensure that the file is unique
for (UINT i=1; (i<65635); i++)
{
if (!SCExistFile(strDocName))
return strDocName;
strDocName.Format(_T("%s%d%s"), strBaseName, i, SC_DOC_EXTENSION);
}
return _T("");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -