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

📄 tmainfrm1.cpp

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

#include "stdafx.h"
#include "TMainFrm.h"
#include "TDataSource.h"
#include "TTreeView.h"
#include "TListView.h"
#include "TFileListDlg.h"
#include "TNewMpqDlg.h"
#include "TNewFolderDlg.h"
#include "TAddFileOptionsDlg.h"
#include "TPropertiesGeneral.h"
#include "TNameBreakerDlg.h"
#include "TOptionsDlg.h"
#include "TConsole.h"

static int _cdecl compare(const void * elem1, const void * elem2)
{
    char * szStr1 = *(char **)elem1;
    char * szStr2 = *(char **)elem2;
    return (int)stricmp(szStr1, szStr2);
}

//-----------------------------------------------------------------------------
// TMainFrame

IMPLEMENT_DYNAMIC(TMainFrame, CFrameWnd);

BEGIN_MESSAGE_MAP(TMainFrame, CFrameWnd)
	//{{AFX_MSG_MAP(TMainFrame)
	ON_WM_CREATE()
	ON_WM_CLOSE()
    ON_MESSAGE(WM_SYSTRAYEVENT, OnSystrayEvent)
    ON_WM_SYSCOMMAND()
	ON_WM_DESTROY()
    ON_MESSAGE(WM_SETSTATUSTEXT, OnSetStatusText)
    ON_MESSAGE(WM_CTLCOLOREDIT, OnCtlColorEdit)
    ON_MESSAGE(WM_CONSOLEDESTROYED, OnConsoleDestroyed)
	ON_UPDATE_COMMAND_UI(ID_FILE_NEW, MustBeIdle)
	ON_UPDATE_COMMAND_UI(ID_FILE_CLOSE, MustHaveDocAndIdle)
	ON_UPDATE_COMMAND_UI(ID_OPS_OPEN, MustHaveItemAndIdle)
	ON_COMMAND(ID_FILE_NEW, OnFileNew)
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
	ON_COMMAND(ID_FILE_CLOSE, OnFileClose)
	ON_COMMAND(ID_OPS_OPEN, OnOpsOpen)
	ON_COMMAND(ID_OPS_OPENWITH, OnOpsOpenWith)
	ON_COMMAND(ID_OPS_EXTRACT, OnOpsExtract)
	ON_COMMAND(ID_OPS_RENAME, OnOpsRename)
	ON_COMMAND(ID_OPS_REMOVE, OnOpsRemove)
	ON_COMMAND(ID_OPS_GETLISTFILE, OnOpsGetListFile)
	ON_COMMAND(ID_OPS_NEWFOLDER, OnOpsNewFolder)
	ON_COMMAND(ID_OPS_ADD_FILES, OnOpsAddFiles)
	ON_COMMAND(ID_OPS_PROPERTIES, OnOpsProperties)
	ON_COMMAND(ID_OPS_EXTRACT_ARCHIVE, OnOpsExtractArchive)
	ON_COMMAND(ID_OPS_GETATTRIBUTES, OnOpsGetAttributes)
	ON_COMMAND(ID_OPS_BUILD_ARCHIVE, OnOpsBuildArchive)
	ON_COMMAND(ID_OPS_COMPACT_ARCHIVE, OnOpsCompactArchive)
	ON_COMMAND(ID_TOOLS_NAME_BREAKER, OnToolsNameBreaker)
	ON_COMMAND(ID_TOOLS_MERGE_LISTFILES, OnToolsMergeListfiles)
	ON_COMMAND(ID_TOOLS_MPQ2K_SCRIPT, OnToolsMpq2000Script)
	ON_COMMAND(ID_TOOLS_OPTIONS, OnToolsOptions)
	ON_WM_SIZE()
	ON_WM_DROPFILES()
	ON_COMMAND(ID_TOOLS_ADDFILEOPTIONS, OnToolsAddFileOptions)
	ON_WM_ERASEBKGND()
	ON_COMMAND(ID_TOOLS_SCRIPTCONSOLE, OnToolsScriptConsole)
    ON_MESSAGE(WM_WORKCOMPLETE, OnWorkComplete)
	ON_UPDATE_COMMAND_UI(ID_FILE_OPEN, MustBeIdle)
	ON_UPDATE_COMMAND_UI(ID_OPS_OPENWITH, MustHaveItemAndIdle)
	ON_UPDATE_COMMAND_UI(ID_OPS_EXTRACT, MustHaveItemAndIdle)
	ON_UPDATE_COMMAND_UI(ID_OPS_RENAME, MustHaveItemAndIdle)
	ON_UPDATE_COMMAND_UI(ID_OPS_REMOVE, MustHaveItemAndIdle)
	ON_UPDATE_COMMAND_UI(ID_OPS_NEWFOLDER, MustHaveDocAndIdle)
	ON_UPDATE_COMMAND_UI(ID_OPS_PROPERTIES, MustHaveItemAndIdle)
	ON_UPDATE_COMMAND_UI(ID_OPS_ADD_FILES, MustHaveDocAndIdle)
	ON_UPDATE_COMMAND_UI(ID_OPS_GETLISTFILE, MustHaveDocAndIdle)
	ON_UPDATE_COMMAND_UI(ID_OPS_GETATTRIBUTES, MustHaveDocAndIdle)
	ON_UPDATE_COMMAND_UI(ID_OPS_EXTRACT_ARCHIVE, MustHaveDocAndIdle)
	ON_UPDATE_COMMAND_UI(ID_OPS_BUILD_ARCHIVE, MustBeIdle)
	ON_UPDATE_COMMAND_UI(ID_OPS_COMPACT_ARCHIVE, MustHaveDocAndIdle)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_NAME_BREAKER, MustHaveDocAndIdle)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_MPQ2K_SCRIPT, MustBeIdle)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_OPTIONS, MustBeIdle)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_ADDFILEOPTIONS, MustBeIdle)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_SCRIPTCONSOLE, MustBeIdle)
	//}}AFX_MSG_MAP
	ON_UPDATE_COMMAND_UI_RANGE(AFX_ID_VIEW_MINIMUM, AFX_ID_VIEW_MAXIMUM, OnUpdateViewStyles)
	ON_COMMAND_RANGE(AFX_ID_VIEW_MINIMUM, AFX_ID_VIEW_MAXIMUM, OnViewStyle)
END_MESSAGE_MAP()

static UINT indicators[] =
{
	ID_SEPARATOR,           // status line indicator
	ID_INDICATOR_CAPS,
	ID_INDICATOR_NUM,
	ID_INDICATOR_SCRL,
};

//-----------------------------------------------------------------------------
// TMainFrame construction/destruction

TMainFrame::TMainFrame()
{
    m_pNameBreaker = NULL;
    m_pAddFileList = NULL;
    m_pTreeView    = NULL;
    m_pListView    = NULL;
    m_hStorm       = NULL;
    m_hWorkThread  = NULL;
    m_hStopEvent   = NULL;
    m_hMpqEvent    = NULL;
    m_bUseStormDll = FALSE;
    m_bNameless    = FALSE;
    m_hBrush       = CreateSolidBrush(RGB(0, 0, 0));
    m_hConsole     = NULL;
    m_strMask      = "*";
}

TMainFrame::~TMainFrame()
{
    // Delete the brush
    if(m_hBrush != NULL)
        DeleteObject(m_hBrush);
}

//-----------------------------------------------------------------------------
// Public functions

int TMainFrame::NewMpqArchive()
{
    TWorkInfo * pWorkInfo = NULL;
    TNewMpqDlg dlg(this);

    // Show the dialog for choosing parameters of the MPQ.
    dlg.m_bNoBuildFrom = TRUE;
    if(dlg.DoModal() != IDOK)
        return ERROR_SUCCESS;

    // Create the TWorkInfo structure
    m_strMpqName  = dlg.m_strMpqName;
    pWorkInfo = CreateWorkInfo(WORK_NEW_MPQ_ARCHIVE, dlg.m_strMpqName);
    pWorkInfo->New.dwHashTableSize = dlg.m_dwHashTableSize;

    // Close the current archive and start work
    CloseMpqArchive();
    return StartWorkThread(pWorkInfo);
}

int TMainFrame::OpenMpqArchive(const char * szMpqName, const char * szFileList)
{
    TWorkInfo * pWork = CreateWorkInfo(WORK_LOAD_MPQ_ARCHIVE);
    int nError = ERROR_SUCCESS;

    // If no MPQ name given, ask the user
    if(nError == ERROR_SUCCESS)
    {
        if(szMpqName == NULL)
        {
            CString strFilters;

            // Call the open dialog
            strFilters.LoadString(IDS_MPQFILTER);
            CFileDialog dlg(TRUE, "mpq", NULL, 0, strFilters, this);
            dlg.m_ofn.Flags |= (OFN_FILEMUSTEXIST | OFN_NONETWORKBUTTON | OFN_ENABLESIZING | OFN_NOCHANGEDIR | OFN_HIDEREADONLY);
            
            // Set the pre-last filter index (All supported MPQs)
            dlg.m_ofn.nFilterIndex = 0;
            for(char * szTemp = (char *)dlg.m_ofn.lpstrFilter; *szTemp != 0;)
            {
                szTemp += strlen(szTemp) + 1;
                szTemp += strlen(szTemp) + 1;
                dlg.m_ofn.nFilterIndex++;
            }
            dlg.m_ofn.nFilterIndex--;
            dlg.m_ofn.lpstrInitialDir = cfg.szLastMpqPath;

            if(dlg.DoModal() == IDOK)
            {
                strcpy(pWork->szMpqName, dlg.GetPathName());
                strcpy(cfg.szLastMpqPath, pWork->szMpqName);
                *GetPlainName(cfg.szLastMpqPath) = 0;
                RemoveBackslash(cfg.szLastMpqPath);
            }
            else
            {
                delete pWork;
                return ERROR_SUCCESS;
            }
        }
        else
            strcpy(pWork->szMpqName, szMpqName);
    }

    // Test if the archive exists
    if(nError == ERROR_SUCCESS)
    {
        if(GetFileAttributes(pWork->szMpqName) == (DWORD)-1)
            nError = GetLastError();
    }

    // If no filelist given, ask the user
    if(nError == ERROR_SUCCESS)
    {
        if(szFileList == NULL)
        {
            TFileListDlg dlg(this);
            dlg.m_strMpqName = pWork->szMpqName;
            switch(dlg.DoModal())
            {
                case IDOK:
                    strcpy(pWork->Load.szFileList, dlg.m_strFileList);
                    pWork->Load.nListFile = 0;
                    break;

                case ID_INTERNAL_LISTFILE:
                    pWork->Load.nListFile = 1;
                    break;

                case ID_AUTODETECT_FILES:
                    pWork->Load.nListFile = 2;
                    break;

                default:
                delete pWork;
                return ERROR_SUCCESS;
            }
        }
        else
            strcpy(pWork->Load.szFileList, szFileList);
    }

    // Close the current archive and start work thread
    if(nError == ERROR_SUCCESS)
    {
        CloseMpqArchive();
        nError = StartWorkThread(pWork);
    }

    // If an error, cleanup.
    if(nError != ERROR_SUCCESS)
        delete pWork;
    return nError;
}

int TMainFrame::CloseMpqArchive()
{
    // Delete all items from list view and tree view
    TreeView_DeleteAllItems(m_pTreeView->GetHwnd());
    m_pListView->LoadListView(NULL);
    m_strMpqName  = "";
    if(m_hMpqEvent != NULL)
    {
        CloseHandle(m_hMpqEvent);
        m_hMpqEvent = NULL;
    }
    return ERROR_SUCCESS;
}

int TMainFrame::OpenSelectedFile(BOOL bOpenWith)
{
    TWorkInfo * pWork = NULL;
    int nSelected = 0;

    if(CheckListSelection(ESEL_NO_SELECTED | ESEL_MORE_SELECTED) == FALSE)
        return ERROR_SUCCESS;

    nSelected = ListView_GetNextItem(m_pListView->GetHwnd(), -1, LVNI_FOCUSED);
    if(nSelected == -1)
        return ERROR_SUCCESS;

    pWork = CreateWorkInfo(WORK_OPEN_FILE);
    pWork->Open.pInfo = m_pListView->GetItemData(nSelected, &pWork->Open.hItem);
    pWork->Open.bOpenWith = bOpenWith;
    return StartWorkThread(pWork);
}

// Extracts all selected files in list view
int TMainFrame::ExtractSelectedFiles()
{
    TWorkInfo * pWork = NULL;
    CPtrList * pFileList = NULL;

    // Check the selection. There must be at least one entry
    if(CheckListSelection(ESEL_NO_SELECTED) == FALSE)
        return ERROR_SUCCESS;

    // Create file list for the selected items
    if((pFileList = CreateFileList(m_pListView->GetHwnd())) == NULL)
        return ERROR_SUCCESS;

    pWork = CreateWorkInfo(WORK_EXTRACT_FILES);
    pWork->pFileList = pFileList;
    pWork->bKeepPath = TRUE;
    return StartWorkThread(pWork);
}

// Called before LVM_BEGINLABELEDIT
int TMainFrame::RenameFile()
{
    HWND hListView = m_pListView->GetHwnd();

    // Must be exactly one item selected, must not be a dir,
    // cannot complete when nameless access
    if(CheckListSelection(ESEL_NO_SELECTED | ESEL_MORE_SELECTED | ESEL_DIR_SELECTED | ESEL_NAMELESS) == FALSE)
        return ERROR_SUCCESS;

    // Begin label editing
    ListView_EditLabel(hListView, ListView_GetNextItem(hListView, -1, LVNI_FOCUSED));
    return ERROR_SUCCESS;
}

// Called after LVM_ENDLABELEDIT
int TMainFrame::RenameFile(TFileInfo * pInfo, const char * szNewFileName)
{
    TWorkInfo * pWork = CreateWorkInfo(WORK_RENAME_FILE);

    pWork->Ren.pInfo = pInfo;
    strcpy(pWork->Ren.szNewName, pInfo->szFullName);
    strcpy(GetPlainName(pWork->Ren.szNewName), szNewFileName);
    return StartWorkThread(pWork);
}

int TMainFrame::RemoveFiles()
{
    TWorkInfo * pWork = NULL;
    CPtrList * pList;

    // Not supported when file names were autodetected
    if(CheckListSelection(ESEL_NO_SELECTED | ESEL_NAMELESS) == FALSE)
        return ERROR_SUCCESS;

    if(AfxMessageBox(IDS_WANTDELETE, MB_YESNO | MB_ICONQUESTION) != IDYES)
        return ERROR_SUCCESS;

    // Build list of files which will be deleted
    if((pList = CreateFileList(m_pListView->GetHwnd())) == NULL)
        return ERROR_SUCCESS;

    pWork = CreateWorkInfo(WORK_REMOVE_FILES);
    pWork->pFileList = pList;
    return StartWorkThread(pWork);
}

int TMainFrame::NewFolder()
{
    TNewFolderDlg dlg(this);
    HTREEITEM hParent = NULL;
    HTREEITEM hSubItem = NULL;

    // Ask the user for the new folder name
    dlg.m_strFolderName.LoadString(IDS_NEWFOLDERNAME);
    if(dlg.DoModal() != IDOK)
        return ERROR_SUCCESS;

    // Test if the item already exists
    hParent = TreeView_GetSelection(m_pTreeView->GetHwnd());
    hSubItem = m_pTreeView->FindTreeItem(hParent, dlg.m_strFolderName);
    if(hSubItem != NULL)
    {
        AfxMessageBox(IDS_FOLDEREXISTS, MB_OK | MB_ICONINFORMATION);
        return ERROR_SUCCESS;
    }

    // Insert the new tree item
    hSubItem = m_pTreeView->InsertTreeItem(hParent, dlg.m_strFolderName);
    if(hSubItem != NULL)
        m_pListView->LoadListView(hParent);
    return ERROR_SUCCESS;
}

int TMainFrame::AddFiles(HDROP hDropInfo)
{
    TWorkInfo * pWork = NULL;
    CPtrList * pFileList = NULL;
    CString strFilters;
    DWORD nRelPathStart = 0;

    // Do nothing, if we currently do a background work or have no document.
    if(HasDocAndIsIdle() == FALSE)
        return ERROR_SUCCESS;

    // Load the filters
    strFilters.LoadString(IDS_ALLFILTER);

    // If no drop info, ask the user.
    if(hDropInfo == NULL)
    {
        CFileDialog dlg(TRUE, "", NULL, 0, strFilters, this);

        dlg.m_ofn.Flags |= (OFN_FILEMUSTEXIST | OFN_NONETWORKBUTTON | OFN_ENABLESIZING | OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT);
        if(dlg.DoModal() != IDOK)
            return ERROR_SUCCESS;

        pFileList     = CreateFileList(&dlg);
        nRelPathStart = dlg.m_ofn.nFileOffset;
    }
    else
        pFileList = CreateFileList(hDropInfo, nRelPathStart);

    // Ask for addition flags
    if(AskForAddFlags() != IDOK)
    {
        FreeStringList(pFileList);
        return ERROR_SUCCESS;
    }

    // Create list of files which will be added
    pWork = CreateWorkInfo(WORK_ADD_FILES);
    pWork->pFileList         = pFileList;
    pWork->lcLocale          = cfg.lcLocale;
    pWork->bFreeList         = TRUE;
    pWork->New.pAddFlags     = cfg.pAddFlags;
    pWork->New.nAddFlags     = cfg.nAddFlags;
    pWork->New.nRelPathStart = nRelPathStart;

⌨️ 快捷键说明

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