📄 tmainfrm2.cpp
字号:
break;
SetStatusText(IDS_LOADINGMPQ2, dwFile, dwFiles);
if(AddFileToTree(wf.cFileName, wf.lcLocale, wf.dwFileSize, wf.dwFileFlags) == ERROR_SUCCESS)
dwFile++;
// Test if we have to exit
if(WaitForSingleObject(m_hStopEvent, 0) != WAIT_TIMEOUT)
break;
bResult = SFileFindNextFile(hFind, &wf);
}
// Close the search handle
SFileFindClose(hFind);
}
else
m_bNameless = TRUE;
}
// If we have to load it with nameless, do it
if(nError == ERROR_SUCCESS && m_bNameless)
{
dwFiles = SFileGetFileInfo(hMpq, SFILE_INFO_BLOCK_TABLE_SIZE);
// Open all files by ordinal number
for(DWORD dwFile = 0; dwFile < dwFiles; dwFile++)
{
// Test if we have to exit
if(WaitForSingleObject(m_hStopEvent, 0) != WAIT_TIMEOUT)
break;
SetStatusText(IDS_LOADINGMPQ2, dwFile + 1, dwFiles);
if(SFileOpenFileEx(hMpq, (const char *)dwFile, 0, &hFile))
{
char szFileName[MAX_PATH];
LCID lcLocale = SFileGetFileInfo(hFile, SFILE_INFO_LOCALEID);
DWORD dwFileSize = SFileGetFileSize(hFile, NULL);
DWORD dwFileAttr = SFileGetFileInfo(hFile, SFILE_INFO_FLAGS);
if(SFileGetFileName(hFile, szFileName))
AddFileToTree(szFileName, lcLocale, dwFileSize, dwFileAttr);
SFileCloseFile(hFile);
}
}
}
// Close the MPQ Archive
if(hMpq != NULL)
SFileCloseArchive(hMpq);
return nError;
}
int TMainFrame::ExtractFile(TWorkInfo * pWork, HANDLE hMpq, const char * szToExtract, const char * szExtracted, LCID lcLocale, BOOL bNoShowError)
{
const char * szFileOrdinal = NULL;
HANDLE hLocalFile = INVALID_HANDLE_VALUE;
HANDLE hMpqFile = NULL;
BOOL bCloseMpq = FALSE;
int nError = ERROR_SUCCESS;
// Set information about extracted file
ASSERT(szToExtract != NULL && szExtracted != NULL);
SetStatusText(IDS_EXTRACTINGFILE, szToExtract);
szFileOrdinal = GetFileOrdinal(szToExtract);
// If the extracted file already exists, ask the user
if(nError == ERROR_SUCCESS)
{
if(GetFileAttributes(szExtracted) != -1)
{
int nResult = MessageBoxYNAC(this, IDS_FILEEXISTS, AFX_IDS_APP_TITLE, MB_ICONWARNING, &pWork->bOverwriteAll, szExtracted);
if(nResult == IDNO)
return ERROR_SUCCESS;
if(nResult != IDYES)
return ERROR_CAN_NOT_COMPLETE;
}
else
{
// Ensure that the path exists
if(nError == ERROR_SUCCESS)
nError = ForcePathExist(szExtracted);
}
}
// Open the MPQ archive
if(nError == ERROR_SUCCESS && hMpq == NULL)
{
bCloseMpq = TRUE;
if(!pSFileOpenArchive(pWork->szMpqName, 0, 0, &hMpq))
nError = GetLastError();
}
// Create the local file
if(nError == ERROR_SUCCESS)
{
hLocalFile = CreateFile(szExtracted, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if(hLocalFile == INVALID_HANDLE_VALUE)
nError = GetLastError();
}
// Open the MPQ file
if(nError == ERROR_SUCCESS)
{
pSFileSetLocale(lcLocale);
if(!pSFileOpenFileEx(hMpq, szFileOrdinal, 0, &hMpqFile))
nError = GetLastError();
}
// Copy the file's content
if(nError == ERROR_SUCCESS)
{
char szBuffer[0x1000];
DWORD dwTransferred = 1;
while(dwTransferred > 0 && WorkStopped(pWork) == FALSE)
{
pSFileReadFile(hMpqFile, szBuffer, sizeof(szBuffer), &dwTransferred, NULL);
if(dwTransferred == 0)
break;
WriteFile(hLocalFile, szBuffer, dwTransferred, &dwTransferred, NULL);
if(dwTransferred == 0)
break;
}
}
// Close the files
if(hMpqFile != NULL)
pSFileCloseFile(hMpqFile);
if(hLocalFile != NULL)
CloseHandle(hLocalFile);
if(bCloseMpq)
pSFileCloseArchive(hMpq);
// If error, delete the extracted file and show the error message
if(nError != ERROR_SUCCESS)
{
DeleteFile(szExtracted);
if(bNoShowError == FALSE)
{
CString strError;
strError.Format(IDS_FAILEDTOEXTRACT, szToExtract, nError);
AfxMessageBox(strError, MB_OK | MB_ICONINFORMATION);
}
}
return nError;
}
int TMainFrame::AddFileToArchive(TWorkInfo * pWork, HANDLE hMpq, char * szFileName, char * szArchName, BOOL * pbReplaced)
{
DWORD dwAddFlags = 0;
DWORD dwQuality = 0;
BOOL bResult = TRUE;
int nFileType = GetAddFlagsByName(pWork->New.pAddFlags, pWork->New.nAddFlags, szFileName, dwAddFlags, dwQuality);
int nResult;
int nError = ERROR_SUCCESS;
if(pbReplaced != NULL)
*pbReplaced = FALSE;
// Set the right locale
SFileSetLocale(pWork->lcLocale);
// If it is a data file, add it as data file
if(nFileType == FILE_TYPE_DATA)
bResult = SFileAddFile(hMpq, szFileName, szArchName, dwAddFlags);
if(nFileType == FILE_TYPE_WAVE)
bResult = SFileAddWave(hMpq, szFileName, szArchName, dwAddFlags, dwQuality);
if(bResult)
return ERROR_SUCCESS;
// If the file already exists, ask for overwrite
nError = GetLastError();
if(nError == ERROR_ALREADY_EXISTS)
{
nResult = MessageBoxYNAC(this, IDS_ARCHFILEEXISTS, AFX_IDS_APP_TITLE, MB_ICONWARNING, &pWork->bOverwriteAll, szArchName);
if(nResult == IDCANCEL)
return nResult;
if(nResult == IDNO)
return ERROR_SUCCESS;
nError = ERROR_SUCCESS;
}
// If we have to overwrite it, do it
if(nError == ERROR_SUCCESS)
{
// Update flags
dwAddFlags |= MPQ_FILE_REPLACEEXISTING;
if(pbReplaced != NULL)
*pbReplaced = TRUE;
// Do it again
if(nFileType == FILE_TYPE_DATA)
bResult = SFileAddFile(hMpq, szFileName, szArchName, dwAddFlags);
if(nFileType == FILE_TYPE_WAVE)
bResult = SFileAddWave(hMpq, szFileName, szArchName, dwAddFlags, dwQuality);
if(bResult == FALSE)
nError = GetLastError();
}
return nError;
}
//-----------------------------------------------------------------------------
// Worker thread functions
int TMainFrame::WTNewMpqArchive(TWorkInfo * pWork)
{
HANDLE hMpq = NULL;
DWORD dwCreationDisposition = OPEN_ALWAYS;
int nError = ERROR_SUCCESS;
// Check if the file is already an archive. If yes, we'll delete it.
if(nError == ERROR_SUCCESS)
{
if(SFileOpenArchive(pWork->szMpqName, 0, 0, &hMpq))
{
dwCreationDisposition = CREATE_ALWAYS;
SFileCloseArchive(hMpq);
}
}
// Create archive.
if(nError == ERROR_SUCCESS)
{
SetStatusText(IDS_CREATINGMPQ);
if(!SFileCreateArchiveEx(pWork->szMpqName, dwCreationDisposition, pWork->New.dwHashTableSize, &hMpq))
nError = GetLastError();
}
// If a filelist was given, build the archive from the files
if(nError == ERROR_SUCCESS && pWork->pFileList != NULL)
nError = AddFiles(hMpq, pWork);
// If an archive, close it.
if(hMpq != NULL)
SFileCloseArchive(hMpq);
// If we succeeded, load the archive
if(nError == ERROR_SUCCESS && !WorkStopped(pWork))
{
pWork->Load.szFileList[0] = 0;
nError = WTLoadMPQArchive(pWork);
}
return nError;
}
int TMainFrame::WTLoadMPQArchive(TWorkInfo * pWork)
{
CString strLoc;
const char * szFileList = NULL;
BOOL bDeleteList = FALSE;
int nError = ERROR_SUCCESS;
// Check whether the archive is not open by another instance of MPQEditor
if(nError == ERROR_SUCCESS)
{
if(CreateMpqEvent(pWork->szMpqName) != ERROR_SUCCESS)
return ERROR_SUCCESS;
}
// If using Storm.dll and no filelist given, try to load the file list from
// the MPQ archive
m_bNameless = FALSE;
SetStatusText(IDS_LOADINGMPQ);
switch(pWork->Load.nListFile)
{
case 0: // Use external file list
break;
case 1: // Use internal listfile
strLoc = GetTempFileName("ListFile");
DeleteFile(strLoc);
if(ExtractFile(pWork, NULL, LISTFILE_NAME, strLoc, LANG_NEUTRAL, TRUE) == ERROR_SUCCESS)
{
strcpy(pWork->Load.szFileList, strLoc);
bDeleteList = TRUE;
break;
}
// No break here !!!
case 2:
m_bNameless = TRUE;
break;
default:
nError = ERROR_INVALID_PARAMETER;
break;
}
if(nError == ERROR_SUCCESS && !WorkStopped(pWork))
{
// Insert root tree item
m_pTreeView->InsertTreeItem(NULL, GetPlainName(pWork->szMpqName));
if(pWork->Load.szFileList[0] != 0)
szFileList = pWork->Load.szFileList;
// If a listfile and we should use Storm.dll, do it
if(szFileList != NULL && m_bNameless == FALSE && m_bUseStormDll)
nError = LoadMpqArchiveST(pWork->szMpqName, szFileList);
// ... or with StormLib
else
nError = LoadMpqArchiveSL(pWork->szMpqName, szFileList);
if(WaitForSingleObject(m_hStopEvent, 0) == WAIT_OBJECT_0)
return ERROR_SUCCESS;
}
// Delete the list file
// if(bDeleteList == TRUE)
// DeleteFile(pWork->Load.szFileList);
// Update the main window
if(nError == ERROR_SUCCESS)
{
// Save variables
m_strMpqName = pWork->szMpqName;
m_strFileList = pWork->Load.szFileList;
if(!WorkStopped(pWork))
{
HTREEITEM hTreeItem;
HWND hTree = m_pTreeView->GetHwnd();
// If no item selected yet, do it now.
if((hTreeItem = TreeView_GetSelection(hTree)) == NULL)
{
hTreeItem = TreeView_GetRoot(hTree);
TreeView_Select(hTree, hTreeItem, TVGN_CARET);
TreeView_Expand(hTree, hTreeItem, TVE_EXPAND);
}
else
{
::InvalidateRect(hTree, NULL, TRUE);
m_pListView->LoadListView(hTreeItem);
}
// Select the root item to force reloading list view
AfxGetApp()->AddToRecentFileList(pWork->szMpqName);
}
}
return nError;
}
int TMainFrame::WTOpenFile(TWorkInfo * pWork)
{
TFileInfo * pInfo = pWork->Open.pInfo;
CString strLocal;
int nError = ERROR_SUCCESS;
// If a directory chosen, call tree view to select it
if(pInfo == NULL)
{
TreeView_SelectItem(m_pTreeView->GetHwnd(), pWork->Open.hItem);
return ERROR_SUCCESS;
}
// If a file, extract the file
if(nError == ERROR_SUCCESS)
{
strLocal = GetLocalFileName(pInfo->szFullName, FALSE);
nError = ExtractFile(pWork, NULL, pInfo->szFullName, strLocal, pInfo->lcLocale);
}
// If extracted successfully, execute the file
if(nError == ERROR_SUCCESS && WorkStopped(pWork) == FALSE)
{
SHELLEXECUTEINFO sei;
TCHAR szParam[MAX_PATH*2];
ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.hwnd = m_hWnd;
sei.lpFile = szParam;
sei.nShow = SW_SHOWNORMAL;
// Try to open the file normal way.
strcpy(szParam, strLocal);
if(pWork->Open.bOpenWith == FALSE)
{
if(!ShellExecuteEx(&sei))
pWork->Open.bOpenWith = TRUE;
}
if(pWork->Open.bOpenWith)
{
sprintf(szParam, "shell32.dll,OpenAs_RunDLL \"%s\"", (const char *)strLocal);
sei.lpFile = "RunDll32.exe";
sei.lpParameters = szParam;
if(!ShellExecuteEx(&sei))
nError = GetLastError();
}
}
return nError;
}
int TMainFrame::WTExtractFiles(TWorkInfo * pWork)
{
TFileInfo * pInfo;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -