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

📄 tmainfrm1.cpp

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