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

📄 tmainfrm2.cpp

📁 mpq文件的格式就是一种压缩格式
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************/
/* TMainFrm2.cpp                          Copyright (c) Ladislav Zezula 2003 */
/*---------------------------------------------------------------------------*/
/* Worker thread functions of TMainFrame                                     */
/*---------------------------------------------------------------------------*/
/*   Date    Ver   Who  Comment                                              */
/* --------  ----  ---  -------                                              */
/* 03.04.03  1.00  Lad  The first version of TMainFrm.cpp                    */
/*****************************************************************************/

#include "stdafx.h"
#include "MPQEditor.h"
#include "TMainFrm.h"
#include "TTreeView.h"
#include "TListView.h"
#include "TFileListDlg.h"
#include "TMsgBoxYNAC.h"

//-----------------------------------------------------------------------------
// Protected functions

void WINAPI TMainFrame::CompactCB(void * lpUserData, DWORD dwWorkType, DWORD dwParam1, DWORD dwParam2)
{
    TMainFrame * pMainFrame = (TMainFrame *)lpUserData;

    switch(dwWorkType)
    {
        case CCB_CHECKING_FILES:
            pMainFrame->SetStatusText(IDS_CHECKING_FILES, dwParam1, dwParam2);
            break;

        case CCB_COMPACTING_FILES:
            pMainFrame->SetStatusText(IDS_COMPACTING, dwParam1, dwParam2);
            break;

        case CCB_CLOSING_ARCHIVE:
            pMainFrame->SetStatusText(IDS_CLOSINGARCHIVE, dwParam1, dwParam2);
            break;
    }
}

TFileInfo * TMainFrame::CreateFileInfo(const char * szFileName, LCID lcLocale, DWORD dwFileSize, DWORD dwFileAttr)
{
    TFileInfo * pInfo;
//  int nSize = sizeof(TFileInfo) + strlen(szFileName);
    int nSize = sizeof(TFileInfo) + MAX_PATH;   // Must be MAXPATH because of renaming
    
    pInfo = (TFileInfo *)(new char[nSize]);
    memset(pInfo, 0, nSize);
    strcpy(pInfo->szFullName, szFileName);
    pInfo->szPlainName  = GetPlainName(pInfo->szFullName);
    pInfo->lcLocale     = lcLocale;
    pInfo->dwFileSize   = dwFileSize;
    pInfo->dwAttributes = dwFileAttr;

    return pInfo;
}

// This function checks if the file name is autodetected name
// in the form of "File########.*". If not, it returns the file name back.
// If yes, it converts the file name to the ordinal number and
// returns it as file name
const char * TMainFrame::GetFileOrdinal(const char * szFileName)
{
    // First of all, test if we auto-detected the file names.
    if(m_bNameless == FALSE)
        return szFileName;

    if(strncmp(szFileName, "File", 4))
        return szFileName;

    for(int nIndex = 4; nIndex < 12; nIndex++)
    {
        if(!isdigit(szFileName[nIndex]))
            return szFileName;
    }

    // Test the point before extension
    if(szFileName[12] != '.')
        return szFileName;

    // Now we know that it is an autodetected name.
    // Convert it to the ordinal number and return
    return (const char *)atoi(szFileName + 4);
}

char * TMainFrame::SkipSpaces(const char * ch)
{
    while(0 < *ch && *ch <= 0x20)
        ch++;
    return (char *)ch;
}

BOOL TMainFrame::GetCommandParams(char * szCmd, char * szParam1, char * szParam2)
{
    char * szNext;

    // Initialize both parameters
    *szParam1 = *szParam2 = 0;

    // Get the first parameter
    szNext = szCmd = SkipSpaces(szCmd);
    while(*szNext != 0 && *szNext > 0x20)
        szNext++;
    if(*szCmd != 0)
    {
        strncpy(szParam1, szCmd, (szNext - szCmd));
        szParam1[szNext - szCmd] = 0;
    }

    // Get the second parameter
    szNext = szCmd = SkipSpaces(szNext);
    while(*szNext != 0 && *szNext > 0x20)
        szNext++;
    if(*szCmd != 0)
    {
        strncpy(szParam2, szCmd, (szNext - szCmd));
        szParam2[szNext - szCmd] = 0;
    }
    return TRUE;
}


// Function tests if the work was stopped. Returns TRUE if yes.
BOOL TMainFrame::WorkStopped(TWorkInfo * pWork)
{
    // Test if we have to exit
    if(pWork->bStop == FALSE)
    {
        if(WaitForSingleObject(m_hStopEvent, 0) != WAIT_TIMEOUT)
            pWork->bStop = TRUE;
    }
    return pWork->bStop;
}

void TMainFrame::UpdateFileInfo(CPtrList * pFileList, const char * szFileName, LCID lcLocale, DWORD dwFileSize, DWORD dwFileAttr)
{
    POSITION pos = pFileList->GetHeadPosition();

    while(pos != NULL)
    {
        TFileInfo * pInfo = (TFileInfo *)pFileList->GetNext(pos);

        if(!stricmp(pInfo->szFullName, szFileName))
        {
            strcpy(pInfo->szFullName, szFileName);
            pInfo->lcLocale   = lcLocale;
            pInfo->dwFileSize = dwFileSize;
            pInfo->dwAttributes = dwFileAttr;
            return;
        }
    }
}

int TMainFrame::EnableDialogBars(BOOL bEnable)
{
    HWND hWnd;

    // Enable/disable the search mask
    if((hWnd = ::GetDlgItem(m_wndDlgBar.m_hWnd, IDC_SMASKTITLE)) != NULL)
        ::EnableWindow(hWnd, bEnable);
    if((hWnd = ::GetDlgItem(m_wndDlgBar.m_hWnd, IDC_MPQSEARCHMASK)) != NULL)
        ::EnableWindow(hWnd, bEnable);

    return 0;
}

int TMainFrame::ReadLine(FILE * fp, TCHAR * szBuffer, int nMaxChars)
{
    _TINT ch = 0;
    int count = 0;

    *szBuffer = 0;
    if(feof(fp))
        return -1;
    
    while(!feof(fp) && (ch = _fgettc(fp)) != (TCHAR)-1)
    {
        if(ch == _T('\n'))
            break;
        if(0 <= ch && ch <= _T(' ') && ch != _T('\t'))
            ch = _T(' ');

        *szBuffer++ = (TCHAR)ch;
        if(++count == nMaxChars)
        {
            // Skip line
            while(!feof(fp) && fgetc(fp) != _T('\n'));
            *szBuffer = 0;
            return -1;                  // Line is to long
        }
    }
    *szBuffer = 0;
    return count;
}

int TMainFrame::SetStatusText(UINT nIDText, ...)
{
    va_list argList;
    char szText[512];
    char szFmt[256];

    // Load the string from resources
    if(!LoadString(AfxGetResourceHandle(), nIDText, szFmt, sizeof(szFmt)-1))
        return GetLastError();

    // Format the string
    va_start(argList, nIDText);
    vsprintf(szText, szFmt, argList);
    va_end(argList);

    // Set the text into status bar
    ::SendMessage(m_hWnd, WM_SETSTATUSTEXT, 0, (LPARAM)szText);
    return ERROR_SUCCESS;
}

int TMainFrame::CreateMpqEvent(const char * szMpqName)
{
    HANDLE hEvent = NULL;
    char szEventName[MAX_PATH+0x20];
    int  nError = ERROR_SUCCESS;

    // Create event name
    sprintf(szEventName, "MpqEditorEvent%s", szMpqName);
    for(char * szTemp = szEventName; *szTemp != 0; szTemp++)
    {
        if(!isalnum(*szTemp))
            *szTemp = '_';
    }

    // Try to open event. If exists it means that this MPQ is already open with another instance
    if((hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, szEventName)) != NULL)
    {
        AfxMessageBox(IDS_ALREADYOPEN);
        CloseHandle(hEvent);
        return ERROR_ALREADY_EXISTS;
    }

    // Create the event
    if((m_hMpqEvent = CreateEvent(NULL, FALSE, FALSE, szEventName)) == NULL)
        nError = GetLastError();
    return nError;
}

int TMainFrame::AddFileToTree(const char * szFileName, LCID lcLocale, DWORD dwFileSize, DWORD dwFileAttr)
{
    TFileInfo * pInfo = NULL;
    HTREEITEM hRootItem = NULL;
    HTREEITEM hSubItem = NULL;
    CPtrList * pFileList = NULL;
    POSITION pos;
    char   szSubDir[MAX_PATH];
    char * szSaveFileName = (char *)szFileName;
    char * szSlash = NULL;
//  int nError = ERROR_SUCCESS;

    // Retrieve the parent tree
    if((hRootItem = TreeView_GetRoot(m_pTreeView->GetHwnd())) == NULL)
        return ERROR_CAN_NOT_COMPLETE;

    // Create directory structure
    while((szSlash = strchr(szFileName, '\\')) != NULL)
    {
        strncpy(szSubDir, szFileName, (szSlash - szFileName));
        szSubDir[szSlash - szFileName] = 0;

        // Try to find the tree item in the tree view
        if((hSubItem = m_pTreeView->FindTreeItem(hRootItem, szSubDir, &pFileList)) == NULL)
            hSubItem = m_pTreeView->InsertTreeItem(hRootItem, szSubDir, &pFileList);

        // Move to the next subdir
        szFileName = szSlash+1;
        hRootItem = hSubItem;
    }

    // For sure ....
    if(hSubItem == NULL && pFileList == NULL)
        hSubItem = m_pTreeView->GetRootTreeItem(&pFileList);

    // Test if the file name is not already in the list
    szFileName = szSaveFileName;
    pos = pFileList->GetHeadPosition();
    while(pos != NULL)
    {
        pInfo = (TFileInfo *)pFileList->GetNext(pos);
        if(!stricmp(pInfo->szFullName, szFileName) && pInfo->lcLocale == lcLocale)
            return ERROR_ALREADY_EXISTS;
    }

    // Now we know the tree item and we can add the file entry into the list
    pFileList->AddTail(CreateFileInfo(szFileName, lcLocale, dwFileSize, dwFileAttr));
    return ERROR_SUCCESS;
}

// Adds file(s) into the archive.
int TMainFrame::AddFiles(HANDLE hMpq, TWorkInfo * pWork)
{
    POSITION pos = pWork->pFileList->GetHeadPosition();
    int nError = ERROR_SUCCESS;

    SFileSetLocale(pWork->lcLocale);
    while(nError == ERROR_SUCCESS && pos != NULL)
    {
        char * szFileName = (char *)pWork->pFileList->GetNext(pos);
        char * szArchName = szFileName + pWork->New.nRelPathStart;

        // Test if the work was not stopped
        if(WorkStopped(pWork))
            break;

        // Update status text
        SetStatusText(IDS_ADDINGFILE, szFileName);
        nError = AddFileToArchive(pWork, hMpq, szFileName, szArchName);
        if(nError != ERROR_SUCCESS)
            break;
    }

    // When the adding stopped on "Already exists", it is OK.
    if(nError == ERROR_ALREADY_EXISTS)
        nError = ERROR_SUCCESS;
    return nError;
}

// Variant with Storm.dll
int TMainFrame::LoadMpqArchiveST(const char * szMpqName, const char * szFileList)
{
    HANDLE hMpq = NULL;
    int nError = ERROR_SUCCESS;

    // Open the archive
    if(nError == ERROR_SUCCESS)
    {
        if(!pSFileOpenArchive(szMpqName, 0, 0, &hMpq))
            nError = GetLastError();
    }

    // Search all files
    if(nError == ERROR_SUCCESS)
    {
        SFILE_FIND_DATA wf;
        HANDLE hFind = SFileFindFirstFileEx(NULL, m_strMask, &wf, szFileList, FALSE);
        HANDLE hFile = NULL;
        BOOL bResult = TRUE;

        while(hFind != NULL && bResult == TRUE)
        {
            // Test if we have to exit
            if(WaitForSingleObject(m_hStopEvent, 0) != WAIT_TIMEOUT)
                break;

            pSFileSetLocale(wf.lcLocale);
            if(pSFileOpenFileEx(hMpq, wf.cFileName, 0, &hFile))
            {
                wf.dwFileSize = pSFileGetFileSize(hFile, NULL);
                AddFileToTree(wf.cFileName, wf.lcLocale, wf.dwFileSize, 0);
                pSFileCloseFile(hFile);
            }
            bResult = SFileFindNextFile(hFind, &wf);
        }

        // Close the search handle
        if(hFind != NULL)
            SFileFindClose(hFind);
    }

    // Close the MPQ Archive
    if(hMpq != NULL)
        pSFileCloseArchive(hMpq);

    return nError;
}

// Variant with StormLib
int TMainFrame::LoadMpqArchiveSL(const char * szMpqName, const char * szFileList)
{
    SFILE_FIND_DATA wf;
    HANDLE hMpq = NULL;
    HANDLE hFind = NULL;
    HANDLE hFile = NULL;
    DWORD dwFiles = 0;
    DWORD dwFile = 0;
    BOOL bResult = TRUE;
    int nError = ERROR_SUCCESS;

    // Open the archive
    if(nError == ERROR_SUCCESS)
    {
        if(!SFileOpenArchive(szMpqName, 0, 0, &hMpq))
            nError = GetLastError();
    }

    // Find the first file from the archive. If it fails, use the nameless search
    if(nError == ERROR_SUCCESS && m_bNameless == FALSE)
    {
        dwFiles = SFileGetFileInfo(hMpq, SFILE_INFO_NUM_FILES);

        if((hFind = SFileFindFirstFile(hMpq, m_strMask, &wf, szFileList)) != NULL)
        {
            while(hFind != NULL && bResult == TRUE)
            {
                // Test if we have to exit
                if(WaitForSingleObject(m_hStopEvent, 0) != WAIT_TIMEOUT)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -