📄 tnamebreakerdlg1.cpp
字号:
pInfo = (TNameInfo *)m_FileList.GetItemData(pHash->dwBlockIndex);
if(SetDetectInfo(pInfo, (pHash - m_pHashTable), dwName1, dwName2, wf.lcLocale, dwSeed, dwFileSize, NULL, wf.cFileName))
m_dwUnknowns--;
UpdateItemLabels(pHash->dwBlockIndex, pInfo);
InsertFolderAndExt(wf.cFileName);
SFileCloseFile(hFile);
}
bResult = SFileFindNextFile(hFind, &wf);
}
if(hFind != NULL)
SFileFindClose(hFind);
}
// Now try to detect all undetected file names
if(nError == ERROR_SUCCESS)
{
for(dwFile = 0; dwFile < dwFiles; dwFile++)
{
TNameInfo * pInfo = (TNameInfo *)m_FileList.GetItemData(dwFile);
// If the entry is incomplete, try to find it by nameless access
if((pInfo->dwFlags & DTI_FILENAME) == 0)
{
dwHashIndex = dwName1 = dwName2 = lcLocale = dwSeed = dwFileSize = 0xFFFFFFFF;
szFileName[0] = 0;
for(DWORD dwHI = 0; dwHI < dwHashTableSize; dwHI++)
{
if(m_pHashTable[dwHI].dwBlockIndex == dwFile)
{
dwHashIndex = dwHI;
dwName1 = m_pHashTable[dwHI].dwName1;
dwName2 = m_pHashTable[dwHI].dwName2;
lcLocale = m_pHashTable[dwHI].lcLocale;
break;
}
}
// Get the file size
if(pBlockTable[dwFile].dwFlags & MPQ_FILE_EXISTS)
dwFileSize = pBlockTable[dwFile].dwFSize;
if(SFileOpenFileEx(hMpq, (char *)dwFile, 0, &hFile))
{
if(SFileGetFileName(hFile, szFileName))
{
InsertFolderAndExt(szFileName);
dwSeed = SFileGetFileInfo(hFile, SFILE_INFO_SEED_UNFIXED);
}
SFileCloseFile(hFile);
}
// Set the found informations
SetDetectInfo(pInfo, dwHashIndex, dwName1, dwName2, lcLocale, dwSeed, dwFileSize, GetFileExt(szFileName), NULL);
UpdateItemLabels(dwFile, pInfo);
}
}
}
// Close the archive and return
if(hMpq != NULL)
SFileCloseArchive(hMpq);
UpdateNUnknowns();
// If required, start immediately
if(nError == ERROR_SUCCESS && m_strDirs.IsEmpty() == FALSE)
{
DetectFileNames(m_strDirs, m_strExts, m_nItem);
m_FileList.EnsureVisible(m_nItem, FALSE);
m_FileList.SetItemState(m_nItem, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
}
return nError;
}
int TNameBreakerDlg::SaveListFile(const char * szListFile)
{
TNameInfo * pInfo = NULL;
CString strFilters;
CString strListFile;
FILE * fp;
// If no listfile given, ask the user for it.
if(szListFile == NULL)
{
char szDefName[MAX_PATH] = "";
strFilters.LoadString(IDS_FILELIST_FILTERS);
CFileDialog dlg(FALSE, "txt", NULL, OFN_NONETWORKBUTTON, strFilters, this);
dlg.m_ofn.Flags |= (OFN_FILEMUSTEXIST | OFN_NONETWORKBUTTON | OFN_ENABLESIZING | OFN_NOCHANGEDIR | OFN_HIDEREADONLY);
dlg.m_ofn.lpstrInitialDir = cfg.szFileListsPath;
// Set the default saved file name
strcpy(szDefName, GetPlainName(m_strMpqName));
strcat(szDefName, ".txt");
dlg.m_ofn.lpstrFile = szDefName;
if(dlg.DoModal() != IDOK)
return ERROR_SUCCESS;
strListFile = dlg.GetPathName();
}
else
strListFile = szListFile;
// Save the listfile
if((fp = fopen(strListFile, "wt")) != NULL)
{
int nItems = m_FileList.GetItemCount();
for(int nItem = 0; nItem < nItems; nItem++)
{
pInfo = (TNameInfo *)m_FileList.GetItemData(nItem);
if(pInfo->dwFlags & DTI_FILENAME)
fprintf(fp, "%s\n", pInfo->szFullName);
}
fclose(fp);
m_nDetected = 0;
UpdateNDetected();
}
// If no default listfile given, show the info
if(szListFile == NULL)
AfxMessageBox(IDS_FILELIST_SAVED, MB_OK | MB_ICONINFORMATION);
return ERROR_SUCCESS;
}
int TNameBreakerDlg::DetectFileNames(const char * szDirs, const char * szExts, int nIndex)
{
char * pchHelper;
char * szStr;
// Prepare the TDetectNameInfo structure
memset(&m_dto, 0, sizeof(TDetectOptions));
strcpy(m_dto.szStartName, cfg.szLastTriedName);
m_dto.nMaxNameLength = 8;
m_dto.nNameLength = strlen(m_dto.szStartName);
m_dto.nIndex = nIndex;
cfg.bAutoSave = TRUE;
// Create the folder list
m_dto.pFolderList = new CPtrList;
szStr = new char[strlen(szDirs) + 1];
strcpy(szStr, szDirs);
m_dto.pFolderList->AddTail(szStr);
// Prepare the extension list to try
m_dto.nExts = 1;
pchHelper = m_dto.szExts = new char[m_dto.nExts * 8];
memset(m_dto.szExts, 0, m_dto.nExts * 8);
strcpy(pchHelper, szExts);
strupr(pchHelper);
return DoNameBreaking();
}
int TNameBreakerDlg::DetectFileNames(int nIndex)
{
TBreakOptsDlg dlg(this);
TNameInfo * pInfo = (TNameInfo *)m_FileList.GetItemData(nIndex);
POSITION pos;
char * pchHelper;
char * szExt = NULL;
// Prevent detection of Mac file names (Long extensions)
if(strlen(pInfo->szExt) > 4)
{
AfxMessageBox(IDS_EXTTOOLONG, MB_OK|MB_ICONERROR);
return 0;
}
// Set the folder and extension list.
// TBreakOptsDlg will use them for filling list boxes.
dlg.m_pFolderList = m_pFolderList;
dlg.m_pExtList = m_pExtList;
// Fill the folder, start name and extension, if any
if(pInfo->dwFlags & DTI_FILENAME)
{
int nDirLength = GetPlainName(pInfo->szFullName) - pInfo->szFullName;
if(IsMacFileName(pInfo->szFullName))
nDirLength += 3;
dlg.m_strFolder = CString(pInfo->szFullName, nDirLength);
}
dlg.m_strStartName = cfg.szLastTriedName;
if(pInfo->dwFlags & DTI_EXTENSION)
dlg.m_strExt = pInfo->szExt;
dlg.m_bAutoSave = cfg.bAutoSave;
// Ask the user for detecting options
if(dlg.DoModal() != IDOK)
return 0;
if(dlg.m_pFolderList->GetCount() == 0 || dlg.m_pExtList->GetCount() == 0)
return 0;
cfg.bAutoSave = dlg.m_bAutoSave;
// Prepare the TDetectNameInfo structure
memset(&m_dto, 0, sizeof(TDetectOptions));
strcpy(m_dto.szStartName, dlg.m_strStartName);
m_dto.nMaxNameLength = dlg.m_nMaxNameLength;
m_dto.nNameLength = dlg.m_strStartName.GetLength();
m_dto.nIndex = nIndex;
m_dto.bThisOnly = dlg.m_bThisOnly;
// Steal the folder list from the dialog
m_dto.pFolderList = dlg.m_pFolderList;
dlg.m_pFolderList = NULL;
// Prepare the list of extensions to try
m_dto.nExts = dlg.m_pExtList->GetCount();
pchHelper = m_dto.szExts = new char[m_dto.nExts * 8];
memset(m_dto.szExts, 0, m_dto.nExts * 8);
for(pos = dlg.m_pExtList->GetHeadPosition(); pos != NULL; )
{
szExt = (char *)dlg.m_pExtList->GetNext(pos);
strcpy(pchHelper, szExt);
strupr(pchHelper);
pchHelper += 8;
}
return DoNameBreaking();
}
int TNameBreakerDlg::DoNameBreaking()
{
POSITION pos;
CString str;
DWORD dwThreadID;
// Change the button "Detect" to "Stop"
str.LoadString(IDS_STOP);
GetDlgItem(IDC_DETECT)->SetWindowText(str);
UpdateNDetected();
// Initialize begin filename
if((pos = m_dto.pFolderList->GetHeadPosition()) != NULL)
strcpy(m_dto.szFileName, (char *)m_dto.pFolderList->GetNext(pos));
strcat(m_dto.szFileName, m_dto.szStartName);
if(m_dto.szExts[0] != 0)
{
strcat(m_dto.szFileName, ".");
strcat(m_dto.szFileName, m_dto.szExts);
}
strupr(m_dto.szFileName);
m_dto.pchFilePos = m_dto.szStartName;
// Start the thread and create update timer
m_dwStartTime = GetTickCount();
m_bInTimer = FALSE;
m_hThread = CreateThread(0, 0, DecryptThread, this, 0, &dwThreadID);
SetThreadPriority(m_hThread, THREAD_PRIORITY_BELOW_NORMAL);
m_nTimer = SetTimer(1, 2000, NULL);
// Set initial status text
OnTimer(1);
return 0;
}
// Asks the user if we have to stop the wotker thread.
// Returns FALSE if the user didn't allow it.
BOOL TNameBreakerDlg::StopWorkThread()
{
if(m_hThread != NULL)
{
if(AfxMessageBox(IDS_WANTEXITIFBGWORK2, MB_YESNO | MB_ICONWARNING) != IDYES)
return FALSE;
TerminateThread(m_hThread, 3);
WaitForSingleObject(m_hThread, 100);
OnWorkComplete(0, ERROR_CAN_NOT_COMPLETE);
}
return TRUE;
}
int TNameBreakerDlg::UpdateNDetected()
{
CString str;
str.Format(IDS_NDETECTED, m_nDetected);
GetDlgItem(IDC_NDETECTED)->SetWindowText(str);
return m_nDetected;
}
int TNameBreakerDlg::UpdateNUnknowns()
{
CString str;
str.Format(IDS_NAMEBRK_TITLE, (const char *)GetPlainName(m_strMpqName), m_dwUnknowns);
SetWindowText(str);
return 0;
}
int TNameBreakerDlg::FocusNextUnknown(int nStep)
{
TNameInfo * pInfo;
int nItems = m_FileList.GetItemCount();
int nItem = m_FileList.GetNextItem(-1, LVNI_FOCUSED);
for(;;)
{
nItem += nStep;
if(nItem < 0)
{
nItem = 0;
break;
}
if(nItem >= nItems)
{
nItem = nItems - 1;
break;
}
pInfo = (TNameInfo *)m_FileList.GetItemData(nItem);
if(pInfo->dwCodeName1 != 0xFFFFFFFE && (pInfo->dwFlags & DTI_FILENAME) == 0)
break;
}
// Focus the found item
m_FileList.SetItemState(nItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
m_FileList.EnsureVisible(nItem, FALSE);
return ERROR_SUCCESS;
}
int TNameBreakerDlg::RefreshDetectInfo(BOOL /* bFinished */)
{
CString str;
DWORD dwElapsedTime = GetTickCount() - m_dwStartTime;
DWORD dwHours, dwMinutes, dwSeconds;
char * szTemp;
if(m_bInTimer == FALSE)
{
m_bInTimer = TRUE;
// Show and remember the last try
SuspendThread(m_hThread);
GetDlgItem(IDC_STATUSTEXT)->SetWindowText(m_dto.szFileName);
strcpy(cfg.szLastTriedName, m_dto.pchFilePos);
ResumeThread(m_hThread);
if((szTemp = strchr(cfg.szLastTriedName, '.')) != NULL)
*szTemp = 0;
AfxGetApp()->WriteProfileString("NameBreaker", "LastTriedName", cfg.szLastTriedName);
// Show elapsed time
dwSeconds = dwElapsedTime / 1000;
dwMinutes = dwSeconds / 60;
dwHours = dwMinutes / 60;
str.Format(IDS_ELAPSEDTIME, dwHours, dwMinutes % 60, dwSeconds % 60);
GetDlgItem(IDC_ELAPSEDTIME)->SetWindowText(str);
m_bInTimer = FALSE;
}
return ERROR_SUCCESS;
}
void TNameBreakerDlg::CommandParent(UINT nShowCmd)
{
WINDOWPLACEMENT wp;
HWND hParent = ::GetParent(m_hWnd);
MSG msg;
// Save the state of parent window
if(nShowCmd == SW_SHOWMINIMIZED)
{
::GetWindowPlacement(hParent, &wp);
m_nOldShow = wp.showCmd;
}
// Change the state of parent window
::ShowWindow(hParent, nShowCmd);
while(::PeekMessage(&msg, hParent, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
int CALLBACK TNameBreakerDlg::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParam)
{
TNameBreakerDlg * pDlg = (TNameBreakerDlg *)lParam;
if(pDlg != NULL)
return pDlg->CompareItems(lParam1, lParam2);
return 0;
}
int TNameBreakerDlg::CompareItems(LPARAM lParam1, LPARAM lParam2)
{
TNameInfo * pInfo1 = (TNameInfo *)lParam1;
TNameInfo * pInfo2 = (TNameInfo *)lParam2;
int nResult = 0;
switch(m_uSortColumn)
{
case 0:
if(pInfo1->dwIndex != pInfo2->dwIndex)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -