📄 tmainfrm1.cpp
字号:
/*****************************************************************************/
/* 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 + -