📄 tmainfrm1.cpp
字号:
return StartWorkThread(pWork);
}
int TMainFrame::ShowProperties()
{
TFileInfo * pInfo = NULL;
HANDLE hMpq = NULL;
HANDLE hFile = NULL;
HWND hListView = m_pListView->GetHwnd();
UINT nSelected = ListView_GetSelectedCount(hListView);
UINT iIndex = ListView_GetNextItem(hListView, -1, LVNI_FOCUSED);
LCID lcNewID = LANG_NEUTRAL;
BOOL bChanged = FALSE;
int nError = ERROR_SUCCESS;
// Must be exactly one item selected
if(nSelected > 1)
{
AfxMessageBox(IDS_CANTDOWITHMULTIPLE, MB_OK | MB_ICONERROR);
return ERROR_SUCCESS;
}
// Not supported on directories
if((pInfo = m_pListView->GetItemData(iIndex, NULL)) == NULL)
{
AfxMessageBox(IDS_CANTDOWITHDIRS, MB_OK | MB_ICONERROR);
return ERROR_SUCCESS;
}
// Open the archive
if(nError == ERROR_SUCCESS)
{
if(!SFileOpenArchive(m_strMpqName, 0, 0, &hMpq))
nError = GetLastError();
}
// Then open the file
if(nError == ERROR_SUCCESS)
{
SFileSetLocale(pInfo->lcLocale);
if(!SFileOpenFileEx(hMpq, GetFileOrdinal(pInfo->szFullName), 0, &hFile))
nError = GetLastError();
}
// Fill the property sheet
if(nError == ERROR_SUCCESS)
{
TPropertiesGeneral page1;
CPropertySheet ps(pInfo->szPlainName, this, 0);
page1.SetInfo(m_strMpqName, pInfo->szFullName, hMpq, hFile);
page1.m_psp.dwFlags &= ~PSP_HASHELP;
ps.m_psh.dwFlags |= (PSH_NOAPPLYNOW | PSH_PROPTITLE);
ps.AddPage(&page1);
ps.DoModal();
bChanged = page1.m_bChanged;
lcNewID = page1.m_lcLocale;
}
// Cleanup and exit
if(hFile != NULL)
SFileCloseFile(hFile);
if(hMpq != NULL)
SFileCloseArchive(hMpq);
// If the locale has been changed, apply it.
if(bChanged)
{
if(SFileCreateArchiveEx(m_strMpqName, OPEN_EXISTING, 0, &hMpq))
{
if(SFileOpenFileEx(hMpq, GetFileOrdinal(pInfo->szFullName), 0, &hFile))
{
SFileSetFileLocale(hFile, lcNewID);
SFileCloseFile(hFile);
pInfo->lcLocale = lcNewID;
m_pListView->LoadListView(TreeView_GetSelection(m_pTreeView->GetHwnd()));
}
SFileCloseArchive(hMpq);
}
}
return nError;
}
int TMainFrame::ExtractListFile()
{
return StartWorkThread(CreateWorkInfo(WORK_EXTRACT_LISTFILE));
}
int TMainFrame::ExtractAttributes()
{
return StartWorkThread(CreateWorkInfo(WORK_EXTRACT_ATTRIBUTES));
}
int TMainFrame::ExtractArchive()
{
TWorkInfo * pWork;
HTREEITEM hRoot = TreeView_GetRoot(m_pTreeView->GetHwnd());
if(AfxMessageBox(IDS_WANTEXTRACTARCHIVE, MB_YESNO | MB_ICONWARNING) != IDYES)
return ERROR_SUCCESS;
pWork = CreateWorkInfo(WORK_EXTRACT_FILES);
pWork->pFileList = new CPtrList;
pWork->bKeepPath = TRUE;
pWork->lcLocale = LANG_NEUTRAL;
AddFolderToList(pWork->pFileList, hRoot);
RemoveNonNeutralItems(pWork->pFileList);
return StartWorkThread(pWork);
}
int TMainFrame::BuildArchive()
{
TNewMpqDlg dlg(this);
TWorkInfo * pWork = NULL;
CPtrList * pFileList;
// Show the dialog for choosing parameters of the MPQ.
dlg.m_bNoBuildFrom = FALSE;
dlg.m_dwHashTableSize = 0x8000;
if(dlg.DoModal() != IDOK)
return ERROR_SUCCESS;
// Close the current archive
CloseMpqArchive();
// Build the complete file list
pFileList = new CPtrList;
AddFolderToList(pFileList, dlg.m_strBuildFrom);
// Create work info
pWork = CreateWorkInfo(WORK_NEW_MPQ_ARCHIVE, dlg.m_strMpqName, dlg.m_strBuildFrom);
pWork->pFileList = pFileList;
pWork->bFreeList = TRUE;
pWork->New.dwHashTableSize = dlg.m_dwHashTableSize;
pWork->New.pAddFlags = cfg.pAddFlags;
pWork->New.nAddFlags = cfg.nAddFlags;
pWork->New.nRelPathStart = strlen(pWork->szWorkDir) + 1;
// Start the worker thread for this
return StartWorkThread(pWork);
}
int TMainFrame::CompactArchive()
{
TFileListDlg dlg;
TWorkInfo * pWork;
if(AfxMessageBox(IDS_WANT_COMPACT_ARCHIVE, MB_YESNO | MB_ICONQUESTION) != IDYES)
return ERROR_SUCCESS;
dlg.m_strMpqName.LoadString(IDS_MPQCOMPACTING);
dlg.m_bNoAutoDetect = TRUE;
if(dlg.DoModal() != IDOK)
return ERROR_SUCCESS;
pWork = CreateWorkInfo(WORK_COMPACT_ARCHIVE, m_strMpqName);
strcpy(pWork->Cmpct.szFileList, dlg.m_strFileList);
return StartWorkThread(pWork);
}
int TMainFrame::NameBreaker(const char * szMpqName, const char * szFileList,
const char * szDirs, const char * szExts, int nItem)
{
TNameBreakerDlg dlg(this);
int nResult;
m_pNameBreaker = &dlg;
nResult = dlg.RunBreaker(szMpqName, szFileList, szDirs, szExts, nItem);
m_pNameBreaker = NULL;
return nResult;
}
int TMainFrame::MergeListfiles()
{
CMapStringToPtr Map;
CPtrArray Array;
POSITION pos = NULL;
CString strFilters;
CString strDlg1Title;
CString strDlg2Title;
CString str;
FILE * fp = NULL;
void * pValue = NULL;
char * szStr = NULL;
char szLine[MAX_PATH] = "";
char szKey[MAX_PATH] = "";
int nIndex = 0;
int nItems = 0;
int nError = ERROR_SUCCESS;
int i;
// Load the filters for listfiles
strDlg1Title.LoadString(IDS_MERGE_LISTFILES_TITLE);
strDlg2Title.LoadString(IDS_SAVE_LISTFILE_TITLE);
strFilters.LoadString(IDS_FILELIST_FILTERS);
// Ask the user for the listfiles to add
CFileDialog dlg1(TRUE, "txt", NULL, OFN_NONETWORKBUTTON, strFilters, this);
dlg1.m_ofn.lpstrFile = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 0x8000);
dlg1.m_ofn.nMaxFile = 0x7FFF;
dlg1.m_ofn.Flags |= (OFN_FILEMUSTEXIST | OFN_NONETWORKBUTTON | OFN_ENABLESIZING | OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT);
dlg1.m_ofn.lpstrTitle = strDlg1Title;
if(dlg1.DoModal() == IDOK)
{
// Ask for the result merged listfile
CFileDialog dlg2(FALSE, "txt", NULL, OFN_NONETWORKBUTTON, strFilters, this);
dlg2.m_ofn.lpstrTitle = strDlg2Title;
if(dlg2.DoModal() == IDOK)
{
// Merge the files
Map.InitHashTable(0x8001);
for(pos = dlg1.GetStartPosition(); pos != NULL; )
{
CString strFileName = dlg1.GetNextPathName(pos);
// Open the file
SetStatusText(IDS_MERGING_LISTFILE, (const char *)strFileName);
if((fp = fopen(strFileName, "rt")) == NULL)
{
str.Format(IDS_EOPENFILE, (const char *)strFileName);
AfxMessageBox(str, MB_OK | MB_ICONEXCLAMATION);
nError = ERROR_FILE_NOT_FOUND;
break;
}
// Load all lines from the file
while(!feof(fp))
{
// Load one line. If empty, do nothing
if(!ReadLine(fp, szLine, sizeof(szLine)))
continue;
// Try if the line already exists in the map
strcpy(szKey, szLine);
strupr(szKey);
if(Map.Lookup(szKey, pValue))
continue;
// The name is not in the map yet. Insert it.
szStr = new char[strlen(szLine) + 1];
strcpy(szStr, szLine);
Map.SetAt(szKey, szStr);
}
// Close the file
fclose(fp);
}
// Move the items from the map to the array
nItems = Map.GetCount();
if(nItems > 0)
{
Array.SetSize(nItems);
for(pos = Map.GetStartPosition(); pos != NULL; )
{
Map.GetNextAssoc(pos, str, (void *&)szStr);
Array.SetAt(nIndex++, szStr);
}
Map.RemoveAll();
}
// Now save the result file
if(nError == ERROR_SUCCESS && nItems > 0)
{
SetStatusText(IDS_SORTING_LIST);
qsort(Array.GetData(), nItems, sizeof(char *), compare);
// Create the file and save the array
SetStatusText(IDS_SAVING_LISTFILE);
if((fp = fopen(dlg2.GetPathName(), "wt")) != NULL)
{
for(i = 0; i < nItems; i++)
fprintf(fp, "%s\n", Array.GetAt(i));
fclose(fp);
str.Format(IDS_LISTFILE_MERGED, (const char *)dlg2.GetPathName());
AfxMessageBox(str, MB_OK | MB_ICONINFORMATION);
}
else
{
str.Format(IDS_EOPENFILE, (const char *)dlg2.GetPathName());
AfxMessageBox(str, MB_OK | MB_ICONEXCLAMATION);
nError = ERROR_FILE_NOT_FOUND;
}
}
// Free all items from array
for(i = 0; i < nItems; i++)
delete Array.GetAt(i);
Array.RemoveAll();
}
}
// Cleanup and exit
SetStatusText(AFX_IDS_IDLEMESSAGE);
if(dlg1.m_ofn.lpstrFile != NULL)
HeapFree(GetProcessHeap(), 0, dlg1.m_ofn.lpstrFile);
return nError;
}
int TMainFrame::RunMpq2000Script(const char * szScriptName)
{
char szScript[MAX_PATH] = "";
if(szScriptName == NULL)
{
CString strFilters;
SetCurrentDirectory(cfg.szWorkPath);
strFilters.LoadString(IDS_ALLFILTER);
CFileDialog dlg(TRUE, "", NULL, 0, strFilters, this);
dlg.m_ofn.Flags |= (OFN_FILEMUSTEXIST | OFN_NONETWORKBUTTON | OFN_ENABLESIZING | OFN_NOCHANGEDIR | OFN_HIDEREADONLY);
if(dlg.DoModal() != IDOK)
return ERROR_SUCCESS;
strcpy(szScript, dlg.GetPathName());
}
else
strcpy(szScript, szScriptName);
return WTRunMPQ2000Script(szScript);
// TWorkInfo * pWork = CreateWorkInfo(WORK_RUN_SCRIPT);
// strcpy(pWork->Runsc.szScript, szScript);
// return StartWorkThread(pWork);
}
int TMainFrame::Options()
{
TOptionsDlg dlg(this);
dlg.m_strWorkDir = cfg.szWorkPath;
dlg.m_strListFileDir = cfg.szFileListsPath;
dlg.m_bUseStorm = m_bUseStormDll;
if(dlg.DoModal() == IDOK)
{
strcpy(cfg.szWorkPath, dlg.m_strWorkDir);
strcpy(cfg.szFileListsPath, dlg.m_strListFileDir);
if(dlg.m_bUseStorm != m_bUseStormDll)
InitFunctionTable(dlg.m_bUseStorm);
}
return ERROR_SUCCESS;
}
int TMainFrame::AddFileOptions()
{
TAddFileOptionsDlg dlg;
return dlg.DoModal();
}
// TRUE if MPQ Editor has no work.
BOOL TMainFrame::IsIdle()
{
return (m_hWorkThread == NULL && m_hConsole == NULL);
}
// TRUE if MPQ Editor has no work and a document open
BOOL TMainFrame::HasDocAndIsIdle()
{
return (IsIdle() && m_strMpqName.IsEmpty() == FALSE);
}
// TRUE if MPQ Editor has no work and has at least one item selected
BOOL TMainFrame::IsItemSelAndIdle()
{
if(IsIdle() == FALSE)
return FALSE;
// If at least one item is selected, OK.
if(ListView_GetSelectedCount(m_pListView->GetHwnd()) > 0)
return TRUE;
// If an item is focused, OK.
if(ListView_GetSelectionMark(m_pListView->GetHwnd()) != -1)
return TRUE;
return FALSE;
}
//-----------------------------------------------------------------------------
// Protected functions
TWorkInfo * TMainFrame::CreateWorkInfo(DWORD dwWorkType, const char * szMpqName, const char * szWorkDir)
{
TWorkInfo * pWorkInfo = new TWorkInfo;
// If no MPQ archive name given, use ours.
if(szMpqName == NULL)
szMpqName = (const char *)m_strMpqName;
// If no work directory entered, use the one from cfg.
if(szWorkDir == NULL)
szWorkDir = cfg.szWorkPath;
// Create and fill TWorkInfo
memset(pWorkInfo, 0, sizeof(TWorkInfo));
pWorkInfo->dwWorkType = dwWorkType;
pWorkInfo->pMainFrame = this;
strcpy(pWorkInfo->szMpqName, szMpqName);
strcpy(pWorkInfo->szWorkDir, szWorkDir);
return pWorkInfo;
}
void TMainFrame::AddFolderToList(CPtrList * pList, HTREEITEM hItem)
{
TFileInfo * pInfo;
CPtrList * pFileList;
HTREEITEM hSubItem;
POSITION pos;
HWND hTreeView = m_pTreeView->GetHwnd();
// Get the first child item
hSubItem = TreeView_GetNextItem(hTreeView, hItem, TVGN_CHILD);
// Add all subitems
while(hSubItem != NULL)
{
AddFolderToList(pList, hSubItem);
hSubItem = TreeView_GetNextItem(hTreeView, hSubItem, TVGN_NEXT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -