📄 stormhelp.cpp
字号:
/*****************************************************************************/
/* StormHelp.cpp Copyright (c) Ladislav Zezula 2003 */
/*---------------------------------------------------------------------------*/
/* Helps with some MPQ operations */
/*---------------------------------------------------------------------------*/
/* Date Ver Who Comment */
/* -------- ---- --- ------- */
/* 05.04.03 1.00 Lad The first version of StormHelp.cpp */
/*****************************************************************************/
#include "StdAfx.h"
//-----------------------------------------------------------------------------
// Helper functions
BOOL IsMacFileName(const char * szFileName)
{
// Convert file name to plain name
szFileName = GetPlainName(szFileName);
// Mac file names begin with 'RF.' or 'DF.', case insensitive
if((toupper(szFileName[0]) == 'R' || toupper(szFileName[0]) == 'D') &&
toupper(szFileName[1]) == 'F' && toupper(szFileName[2]) == '.')
return TRUE;
return FALSE;
}
// If the windows shell is not able to load the type name, supply our own
int GetBlizzardFileTypeName(const char * szFileName, SHFILEINFO & sfi)
{
char szExt[16];
int nIDTypeName;
// If the type name already exists, do nothing
if(sfi.szTypeName[0] != 0)
return ERROR_SUCCESS;
if((szFileName = strrchr(szFileName, '.')) == NULL)
return ERROR_CAN_NOT_COMPLETE;
strncpy(szExt, szFileName, sizeof(szExt));
strlwr(szExt);
switch(*(DWORD *)szExt)
{
case 'qpm.' : nIDTypeName = IDS_MPQ_TYPE; break;
case 'plb.' : nIDTypeName = IDS_BLP_TYPE; break;
case 'xdm.' : nIDTypeName = IDS_MDX_TYPE; break;
case 'kms.' : nIDTypeName = IDS_SMK_TYPE; break;
case 'kib.' : nIDTypeName = IDS_BIK_TYPE; break;
case 'tnf.' : nIDTypeName = IDS_FNT_TYPE; break;
case 'lbt.' : nIDTypeName = IDS_TBL_TYPE; break;
case 'lec.' : nIDTypeName = IDS_CEL_TYPE; break;
case '2lc.' : nIDTypeName = IDS_CL2_TYPE; break;
case 'prg.' : nIDTypeName = IDS_GRP_TYPE; break;
case '6cd.' : nIDTypeName = IDS_DC6_TYPE; break;
case 'ccd.' : nIDTypeName = IDS_DCC_TYPE; break;
case '1td.' : nIDTypeName = IDS_DT1_TYPE; break;
case 'xxx.' : nIDTypeName = IDS_XXX_TYPE; break;
default : return ERROR_CAN_NOT_COMPLETE;
}
LoadString(AfxGetResourceHandle(), nIDTypeName, sfi.szTypeName, sizeof(sfi.szTypeName)-1);
return ERROR_SUCCESS;
}
char * GetPlainName(const char * szFileName)
{
char * szName = strrchr(szFileName, '\\');
return (szName != NULL) ? szName + 1 : (char *)szFileName;
}
char * GetFileExt(const char * szFileName)
{
char * szExt;
// On Mac names, skip the beginning 'RF.' or 'DF.'
if(IsMacFileName(szFileName))
szFileName = GetPlainName(szFileName) + 3;
szExt = strrchr(szFileName, '.');
return (szExt != NULL) ? szExt + 1 : (char *)szFileName + strlen(szFileName);
}
// Ensures that the path for the extracted file already exists
// or creates it.
int ForcePathExist(const char * szFileName)
{
char szFullPath[MAX_PATH] = "";
char * szTemp;
int nError = ERROR_SUCCESS;
// Network path - cannot run
if(szFileName[0] == '\\' && szFileName[1] == '\\')
return ERROR_NOT_SUPPORTED;
// Pre-init the path with search path
while((szTemp = strchr(szFileName, '\\')) != NULL)
{
// Append the (next) path part
AddBackslash(szFullPath);
strncat(szFullPath, szFileName, (szTemp - szFileName));
// Create the directory, except for root dir
if(!(szFullPath[1] == ':' && szFullPath[2] == 0))
{
if(!CreateDirectory(szFullPath, NULL))
{
nError = GetLastError();
if(nError != ERROR_ALREADY_EXISTS)
break;
nError = ERROR_SUCCESS;
}
}
szFileName = szTemp + 1;
}
return nError;
}
// Creates the name of a local file from archived file name
CString GetLocalFileName(const char * szArchivedName, BOOL bKeepPath)
{
char szLocalFile[MAX_PATH] = "";
strcpy(szLocalFile, cfg.szWorkPath);
if(bKeepPath == FALSE)
szArchivedName = GetPlainName(szArchivedName);
AddBackslash(szLocalFile);
strcat(szLocalFile, szArchivedName);
return CString(szLocalFile);
}
// Creates the name of a temporary file
CString GetTempFileName(const char * szFileName)
{
char szTempPath[MAX_PATH] = "";
char szTempFile[MAX_PATH] = "";
GetTempPath(sizeof(szTempPath)-1, szTempPath);
GetTempFileName(szTempPath, szFileName, 0, szTempFile);
return CString(szTempFile);
}
void RemoveBackslash(char * szPathName)
{
int nLength = strlen(szPathName);
if(nLength > 1)
{
if(szPathName[nLength-1] == '\\')
szPathName[nLength-1] = 0;
}
}
void AddBackslash(char * szPathName)
{
int nLength = strlen(szPathName);
if(nLength > 1)
{
if(szPathName[nLength-1] != '\\')
{
szPathName[nLength] = '\\';
szPathName[nLength+1] = 0;
}
}
}
// Frees the CPtrList, containing strings allocated by 'new char'
void FreeStringList(CPtrList *& pList)
{
POSITION pos;
char * szStr;
if(pList != NULL)
{
// Free all strings blocks
for(pos = pList->GetHeadPosition(); pos != NULL;)
{
szStr = (char *)pList->GetNext(pos);
delete szStr;
}
// Remove all list items and the list itself
pList->RemoveAll();
delete pList;
pList = NULL;
}
}
// Fills a combobox with locales and selects the right item
static CComboBox * pLocalesCombo = NULL;
BOOL CALLBACK EnumLocalesProc(LPTSTR lpLocaleString)
{
if(pLocalesCombo != NULL)
{
char szLanguage[128];
char * szTemp = NULL;
LCID lcID = strtol(lpLocaleString, &szTemp, 16);
int nIndex;
if(GetLocaleInfo(lcID, LOCALE_SLANGUAGE, szLanguage, sizeof(szLanguage)-1) != 0)
{
nIndex = pLocalesCombo->AddString(szLanguage);
pLocalesCombo->SetItemData(nIndex, lcID);
}
}
return TRUE;
}
void FillLocalesAndSelect(CComboBox * pCombo, LCID lcID)
{
char szLanguage[128];
int nIndex;
int nItems;
// Fill the combo box
pCombo->ResetContent();
pLocalesCombo = pCombo;
EnumSystemLocales(EnumLocalesProc, LCID_SUPPORTED);
pLocalesCombo = NULL;
// Insert the "Neutral" string to the begin of the list
LoadString(AfxGetResourceHandle(), IDS_NEUTRAL, szLanguage, sizeof(szLanguage)-1);
nIndex = pCombo->InsertString(0, szLanguage);
pCombo->SetItemData(nIndex, 0);
// Find the right item
if(lcID != (LCID)-1)
{
nItems = pCombo->GetCount();
for(int i = 0; i < nItems; i++)
{
if(pCombo->GetItemData(i) == lcID)
{
pCombo->SetCurSel(i);
return;
}
}
}
}
// Converts the string to long. this function was written because
// the builtin strtol does not work correctly (try to convert 0xAABBCCDD !!!)
int StrToInt(const char * ptr, char ** end, int root)
{
int nDigit;
int acc = 0;
while((nDigit = *ptr) != 0)
{
// If the character is not an alphanumeric, break
if(!isalnum(nDigit))
break;
// Convert to digit
nDigit -= '0';
if(nDigit > 9)
nDigit -= ('A' - '9' - 1);
if(nDigit > root-1)
break;
// Move the value to the next rank and add the digit
acc *= root;
acc += nDigit;
ptr++;
}
if(end != NULL)
*end = (char *)ptr;
return acc;
}
// This function searches the file-storing flags by its type.
int GetAddFlagsByName(TAddFlags * pFlags, int nFlags, const char * szName, DWORD & dwFlags, DWORD & dwQuality)
{
TExt Ext;
char * szTemp = strrchr(szName, '.');
// Set defaults
Ext.dwExt = 0;
dwFlags = (MPQ_FILE_COMPRESS_MULTI | MPQ_FILE_ENCRYPTED);
dwQuality = 0;
if(szTemp != NULL)
strncpy(Ext.szExt, szTemp+1, sizeof(TExt));
for(int i = 0; i < nFlags; i++, pFlags++)
{
if(pFlags->Ext.dwExt == Ext.dwExt || i == nFlags - 1)
{
if(pFlags->nFileType == FILE_TYPE_DATA)
{
dwFlags = 0;
if(pFlags->nCompression == 1)
dwFlags |= MPQ_FILE_COMPRESS_PKWARE;
if(pFlags->nCompression == 2)
dwFlags |= MPQ_FILE_COMPRESS_MULTI;
}
if(pFlags->nFileType == FILE_TYPE_WAVE)
dwQuality = pFlags->nCompression;
if(pFlags->bEncrypt)
dwFlags |= MPQ_FILE_ENCRYPTED;
return pFlags->nFileType;
}
}
return pFlags->nFileType;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -