DragonNest/Client/DuplicateFinder/DuplicateFinderDlg.cpp

379 lines
10 KiB
C++
Raw Normal View History

2024-12-19 09:48:26 +08:00
// DuplicateFinderDlg.cpp : implementation file
//
#include "stdafx.h"
#include "DuplicateFinder.h"
#include "DuplicateFinderDlg.h"
#include "SundriesFunc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CAboutDlg dialog used for App About
class CAboutDlg : public CXTResizeDialog
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CXTResizeDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CXTResizeDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CXTResizeDialog)
END_MESSAGE_MAP()
// CDuplicateFinderDlg dialog
CDuplicateFinderDlg::CDuplicateFinderDlg(CWnd* pParent /*=NULL*/)
: CXTResizeDialog(CDuplicateFinderDlg::IDD, pParent)
, m_szFolder(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CDuplicateFinderDlg::DoDataExchange(CDataExchange* pDX)
{
CXTResizeDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST2, m_ListCtrl);
DDX_Text(pDX, IDC_EDIT2, m_szFolder);
}
BEGIN_MESSAGE_MAP(CDuplicateFinderDlg, CXTResizeDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDOK, &CDuplicateFinderDlg::OnBnClickedOk)
ON_BN_CLICKED(IDC_BUTTON1, &CDuplicateFinderDlg::OnBnClickedButton1)
ON_WM_DESTROY()
END_MESSAGE_MAP()
// CDuplicateFinderDlg message handlers
BOOL CDuplicateFinderDlg::OnInitDialog()
{
CXTResizeDialog::OnInitDialog();
SetResize( IDOK, SZ_BOTTOM_RIGHT, SZ_BOTTOM_RIGHT );
SetResize( IDCANCEL, SZ_BOTTOM_RIGHT, SZ_BOTTOM_RIGHT );
SetResize( IDC_EDIT2, SZ_TOP_LEFT, SZ_TOP_RIGHT );
SetResize( IDC_BUTTON1, SZ_TOP_RIGHT, SZ_TOP_RIGHT );
SetResize( IDC_LIST2, SZ_TOP_LEFT, SZ_BOTTOM_RIGHT );
LoadPlacement( _T("CDuplicateFinderDlg") );
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
CRect rcRect;
m_ListCtrl.GetWindowRect( &rcRect );
m_ListCtrl.AddColumn( "Location", rcRect.Width() - 110 );
m_ListCtrl.AddColumn( "Size", 90, LVCFMT_RIGHT );
return TRUE; // return TRUE unless you set the focus to a control
}
void CDuplicateFinderDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CXTResizeDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CDuplicateFinderDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CXTResizeDialog::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CDuplicateFinderDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void FindFileListInDirectoryXXX( const char *szFolderName, const char *szExt, std::vector<std::string> &szVecResult, std::vector<int> &nVecFileSize, bool bIncludeFolder, bool bSearchSubDir, bool bIncludeFolderName )
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
char szFindFile[512];
sprintf_s( szFindFile, "%s\\%s", szFolderName, szExt );
hFind = FindFirstFile( szFindFile, &FindFileData );
while( hFind != INVALID_HANDLE_VALUE ) {
if( !( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ) ) {
if( !( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) || bIncludeFolder == true ) {
if( bIncludeFolderName )
{
char szFullName[ _MAX_PATH ];
sprintf_s( szFullName, "%s\\%s", szFolderName, FindFileData.cFileName );
szVecResult.push_back( szFullName );
nVecFileSize.push_back( FindFileData.nFileSizeLow );
}
else
{
szVecResult.push_back( FindFileData.cFileName );
nVecFileSize.push_back( FindFileData.nFileSizeLow );
}
}
if( ( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) && bSearchSubDir == true ) {
if( strcmp( FindFileData.cFileName, "." ) && strcmp( FindFileData.cFileName, ".." ) ) {
char szFolder[512] = { 0, };
sprintf_s( szFolder, "%s\\%s", szFolderName, FindFileData.cFileName );
FindFileListInDirectoryXXX( szFolder, szExt, szVecResult, nVecFileSize, bIncludeFolder, bSearchSubDir, bIncludeFolderName );
}
}
}
if( !FindNextFile( hFind, &FindFileData ) ) break;
}
FindClose( hFind );
}
std::string NumToDecimalStr( int nValue )
{
char szTemp[128];
std::string szTemp2;
itoa( nValue, szTemp, 10 );
szTemp2 = szTemp;
int nOffset = 0;
for( int k=szTemp2.size()-1; k>=0; k-- ) {
nOffset++;
if( nOffset % 3 == 0 && k != 0 ) {
szTemp2.insert( szTemp2.begin() + k, ',' );
nOffset = 0;
}
}
return szTemp2;
}
int GetMin( std::vector<int> &nVecList )
{
int nValue = INT_MAX;
for( DWORD i=0; i<nVecList.size(); i++ ) {
if( nVecList[i] < nValue ) nValue = nVecList[i];
}
return nValue;
}
int GetMax( std::vector<int> &nVecList )
{
int nValue = INT_MIN;
for( DWORD i=0; i<nVecList.size(); i++ ) {
if( nVecList[i] > nValue ) nValue = nVecList[i];
}
return nValue;
}
void CDuplicateFinderDlg::OnBnClickedOk()
{
m_ListCtrl.DeleteAllItems();
// TODO: Add your control notification handler code here
std::vector<std::string> szVecList;
std::vector<int> nVecSizeList;
struct FileInfoStruct {
std::string szFileName;
long lSize;
};
std::map<std::string,std::vector<FileInfoStruct>> szMapSearch;
char szFileName[_MAX_PATH];
std::vector<std::string> szVecResult;
FindFileListInDirectoryXXX( m_szFolder.GetBuffer(), "*.*", szVecList, nVecSizeList, false, true, true );
std::map<std::string,std::vector<FileInfoStruct>>::iterator it;
for( DWORD i=0; i<szVecList.size(); i++ ) {
_GetFullFileName( szFileName, szVecList[i].c_str() );
strlwr( szFileName );
if( strcmp( szFileName, "." ) == NULL || strcmp( szFileName, ".." ) == NULL ) continue;
if( strstr( szVecList[i].c_str(), "\\Grid\\" ) ) continue;
if( strstr( szVecList[i].c_str(), "\\MapData_" ) ) continue;
if( strstr( szVecList[i].c_str(), "\\Resource_" ) ) continue;
it = szMapSearch.find( szFileName );
if( it == szMapSearch.end() ) {
std::vector<FileInfoStruct> VecTemp;
FileInfoStruct Struct;
Struct.szFileName = szVecList[i];
Struct.lSize = nVecSizeList[i];
VecTemp.push_back( Struct );
szMapSearch.insert( make_pair( szFileName, VecTemp ) );
}
else {
FileInfoStruct Struct;
Struct.szFileName = szVecList[i];
Struct.lSize = nVecSizeList[i];
it->second.push_back( Struct );
}
}
char szExt[128];
std::string szTemp;
int nCount = 0;
int nDelCount = 0;
int nTotalSize = 0;
int nMinSize = 0;
int nMaxSize = 0;
std::vector<int> nVecSizeTemp;
std::map<std::string, int> szMapExtList;
std::map<std::string, int>::iterator it2;
for( it = szMapSearch.begin(); it != szMapSearch.end(); it++ ) {
if( it->second.size() > 1 ) {
nVecSizeTemp.clear();
for( DWORD i=0; i<it->second.size(); i++ ) {
int nItemID = m_ListCtrl.InsertItem( m_ListCtrl.GetItemCount(), it->second[i].szFileName.c_str() );
szTemp = NumToDecimalStr( it->second[i].lSize );
m_ListCtrl.SetItemText( nItemID, 1, szTemp.c_str() );
nTotalSize += it->second[i].lSize;
nVecSizeTemp.push_back( it->second[i].lSize );
}
nMinSize += GetMin( nVecSizeTemp );
nMaxSize += GetMax( nVecSizeTemp );
_GetExt( szExt, it->first.c_str() );
it2 = szMapExtList.find( szExt );
if( it2 == szMapExtList.end() ) {
szMapExtList.insert( make_pair( szExt, 1 ) );
}
else {
it2->second++;
}
int nItemID = m_ListCtrl.InsertItem( m_ListCtrl.GetItemCount(), "---------------------------------------------------------------------------------------------------------------------------------------" );
m_ListCtrl.SetItemText( nItemID, 1, "-------------------------------------" );
nCount++;
nDelCount += ( it->second.size() - 1 );
}
}
char szStr[256];
m_ListCtrl.InsertItem( m_ListCtrl.GetItemCount(), "-------------- Ȯ<><C8AE><EFBFBD><EFBFBD> <20><> <20>ߺ<EFBFBD> <20>׸<EFBFBD> <20><>----------------" );
for( it2 = szMapExtList.begin(); it2 != szMapExtList.end(); it2++ ) {
sprintf_s( szStr, "%s : %d <20><>", it2->first.c_str(), it2->second );
m_ListCtrl.InsertItem( m_ListCtrl.GetItemCount(), szStr );
}
m_ListCtrl.InsertItem( m_ListCtrl.GetItemCount(), "---------------------------------------------------------------------------------------------------------------------------------------" );
sprintf_s( szStr, "<EFBFBD>ߺ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>׸<EFBFBD> <20><> : %d <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> : %d", nCount, nDelCount );
m_ListCtrl.InsertItem( m_ListCtrl.GetItemCount(), szStr );
sprintf_s( szStr, "<EFBFBD>ߺ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>뷮 : %s", NumToDecimalStr(nTotalSize).c_str() );
m_ListCtrl.InsertItem( m_ListCtrl.GetItemCount(), szStr );
sprintf_s( szStr, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٰ<EFBFBD> <20><> <20>ּ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>뷮 : %s", NumToDecimalStr(nMinSize).c_str() );
m_ListCtrl.InsertItem( m_ListCtrl.GetItemCount(), szStr );
sprintf_s( szStr, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٰ<EFBFBD> <20><> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>뷮 : %s", NumToDecimalStr(nMaxSize).c_str() );
m_ListCtrl.InsertItem( m_ListCtrl.GetItemCount(), szStr );
m_ListCtrl.UpdateData( FALSE );
// OnOK();
}
void CDuplicateFinderDlg::OnBnClickedButton1()
{
if( UpdateData(TRUE) )
{
CXTBrowseDialog dlg;
dlg.SetTitle(_T("Select Search Directory"));
if (!m_szFolder.IsEmpty())
{
TCHAR path[_MAX_PATH];
STRCPY_S(path, _MAX_PATH, m_szFolder);
dlg.SetSelPath(path);
}
if (dlg.DoModal() == IDOK)
{
m_szFolder = dlg.GetSelPath();
UpdateData(FALSE);
}
}
}
void CDuplicateFinderDlg::OnDestroy()
{
CXTResizeDialog::OnDestroy();
// TODO: Add your message handler code here
SavePlacement( _T("CDuplicateFinderDlg") );
}