⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tmainfrm2.cpp

📁 mpq文件的格式就是一种压缩格式
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                    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 + -