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

📄 fcomparedlg.cpp

📁 二进制文件比较程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// FCompareDlg.cpp : implementation file
// (c) Codeguru & friends
// Coded by Antonio Tejada Lacaci. 1999
// atejada@espanet.com
//

#include "stdafx.h"
#include "FCompare.h"
#include "FCompareDlg.h"
#include "DirDialog.h"
#include <Shlwapi.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

#include "HyperLink.h"

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	CHyperLink m_urlHomepage;
	CHyperLink m_urlCodeguru;
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	DDX_Control(pDX, URL_HOMEPAGE, m_urlHomepage);
	DDX_Control(pDX, URL_CODEGURU, m_urlCodeguru);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFCompareDlg dialog

CFCompareDlg::CFCompareDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CFCompareDlg::IDD, pParent) {
	//{{AFX_DATA_INIT(CFCompareDlg)
	m_bRecurse = FALSE;
	m_nMatchCriteria = 0;
	m_dwUpto = 0;
	m_strAllowedMasks = _T("*.*");
	m_strDirectory = _T("");
	m_bCompareDuplicates = FALSE;
	//}}AFX_DATA_INIT
   m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

   // Flags
   m_bExit = FALSE;
   m_bAbort = FALSE;
   m_bAddInProgress = FALSE;
   m_bFillInProgress = FALSE;
   m_bCompareInProgress = FALSE;
   m_bsState = BS_IDLE;

   // Logical data
   m_msaMatchedInfos.SetSize(0,20);
}

void CFCompareDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CFCompareDlg)
	DDX_Control(pDX, LBL_STATUS, m_lblStatus);
	DDX_Control(pDX, LBL_TARGETFILES, m_lblTargetFiles);
	DDX_Control(pDX, LBL_SOURCEFILES, m_lblSourceFiles);
	DDX_Control(pDX, LBL_MATCHEDFILES, m_lblMatchedFiles);
	DDX_Control(pDX, LST_MATCHEDFILES, m_lstMatchedFiles);
	DDX_Control(pDX, TAB_ACTION, m_tabAction);
	DDX_Control(pDX, LST_TARGETFILES, m_lstTargetFiles);
	DDX_Control(pDX, LST_SOURCEFILES, m_lstSourceFiles);
	DDX_Control(pDX, PRG_PROGRESS, m_prgProgress);
	DDX_Check(pDX, CHK_RECURSEDIR, m_bRecurse);
	DDX_Radio(pDX, RAD_MATCHCRITERIA, m_nMatchCriteria);
	DDX_Text(pDX, EDT_UPTO, m_dwUpto);
	DDX_Text(pDX, EDT_ALLOWEDMASKS, m_strAllowedMasks);
	DDX_Text(pDX, EDT_DIRECTORY, m_strDirectory);
	DDX_Check(pDX, CHK_COMPAREDUPLICATES, m_bCompareDuplicates);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CFCompareDlg, CDialog)
	//{{AFX_MSG_MAP(CFCompareDlg)
   ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(RAD_MATCHCONTENTS, OnMatchContents)
	ON_BN_CLICKED(RAD_MATCHCRITERIA, OnMatchCriteria)
	ON_BN_CLICKED(BTN_COMPARE, OnCompare)
	ON_WM_TIMER()
	ON_NOTIFY(LVN_GETDISPINFO, LST_SOURCEFILES, OnGetdispinfoSearchFiles)
	ON_BN_CLICKED(BTN_EXIT, OnExit)
	ON_NOTIFY(TCN_SELCHANGE, TAB_ACTION, OnSelchangeAction)
	ON_NOTIFY(LVN_GETDISPINFO, LST_MATCHEDFILES, OnGetdispinfoMatchedFiles)
	ON_BN_CLICKED(BTN_EXPLOREDIR, OnExploreDirectory)
	ON_BN_CLICKED(BTN_ADDSOURCEFILES, OnAddSourceFiles)
	ON_BN_CLICKED(BTN_ADDTARGETFILES, OnAddTargetFiles)
	ON_BN_CLICKED(BTN_CLEARSOURCEFILES, OnClearSourceFiles)
	ON_BN_CLICKED(BTN_CLEARTARGETFILES, OnClearTargetFiles)
	ON_WM_CLOSE()
	ON_NOTIFY(LVN_GETDISPINFO, LST_TARGETFILES, OnGetdispinfoSearchFiles)
	ON_BN_CLICKED(RAD_MATCHCHECKSUM, OnMatchContents)
	ON_BN_CLICKED(RAD_MATCHCRC, OnMatchContents)
	ON_BN_CLICKED(BTN_EXPORT, OnExport)
	//}}AFX_MSG_MAP
   ON_MESSAGE(WM_SEARCH_FINISHED, OnSearchFinished)
   ON_MESSAGE(WM_COMPARE_FINISHED, OnCompareFinished)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFCompareDlg message handlers

BOOL CFCompareDlg::OnInitDialog() {
	CDialog::OnInitDialog();

	// 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);
		}
      // Invalidate maximize & resize
      pSysMenu->EnableMenuItem(SC_SIZE,MF_GRAYED);
      pSysMenu->EnableMenuItem(SC_MAXIMIZE,MF_GRAYED);
      pSysMenu->EnableMenuItem(SC_RESTORE,MF_GRAYED);
	}

	// 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
	
   m_lstSourceFiles.InsertColumn(0,_T("Filename"),LVCFMT_LEFT,300);
   m_lstSourceFiles.InsertColumn(1,_T("Size"),LVCFMT_RIGHT,65);

   m_lstTargetFiles.InsertColumn(0,_T("Filename"),LVCFMT_LEFT,300);
   m_lstTargetFiles.InsertColumn(1,_T("Size"),LVCFMT_RIGHT,65);

   m_lstMatchedFiles.InsertColumn(0,_T("Source Filename"),LVCFMT_LEFT,268);
   m_lstMatchedFiles.InsertColumn(1,_T("Target Filename"),LVCFMT_LEFT,268);
   m_lstMatchedFiles.InsertColumn(2,_T("Size"),LVCFMT_RIGHT,65);

   UpdateCounters();

   m_tabAction.InsertItem(PPG_SEARCH,_T(" Search "));
   m_tabAction.InsertItem(PPG_COMPARE,_T(" Compare "));

   GetDlgItem(LBL_TARGETFILES)->ShowWindow(SW_SHOW);
   GetDlgItem(LBL_SOURCEFILES)->ShowWindow(SW_SHOW);
   GetDlgItem(LST_TARGETFILES)->ShowWindow(SW_SHOW);
   GetDlgItem(LST_SOURCEFILES)->ShowWindow(SW_SHOW);
   GetDlgItem(CHK_RECURSEDIR)->ShowWindow(SW_SHOW);
   GetDlgItem(BTN_COMPARE)->ShowWindow(SW_SHOW);
   GetDlgItem(LBL_MATCHEDFILES)->ShowWindow(SW_HIDE);
   GetDlgItem(LST_MATCHEDFILES)->ShowWindow(SW_HIDE);

   UpdateData(FALSE);
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CFCompareDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::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 CFCompareDlg::OnPaint() {
	if (IsIconic()) {
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (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 {
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CFCompareDlg::OnQueryDragIcon() {
	return (HCURSOR) m_hIcon;
}

void CFCompareDlg::OnExploreDirectory() {
   CDirDialog dlgDir;
   
   dlgDir.m_strTitle = _T("Select directory for file search");
   UpdateData(TRUE);
   dlgDir.m_strSelDir = m_strDirectory;
   dlgDir.m_strWindowTitle = _T("Select directory");
   if (dlgDir.DoBrowse(this) == IDOK) {
      m_strDirectory = dlgDir.m_strPath;
      // Append backslash if necessary
      if ((m_strDirectory.GetLength()>0) && 
          (m_strDirectory[m_strDirectory.GetLength()-1] != TCHAR('\\'))) 
          m_strDirectory += TCHAR('\\');
      UpdateData(FALSE);
   }
}

void CFCompareDlg::OnMatchContents() {
   GetDlgItem(EDT_UPTO)->EnableWindow(TRUE);	
}

void CFCompareDlg::OnMatchCriteria() {
   GetDlgItem(EDT_UPTO)->EnableWindow(FALSE);
}

UINT SearchThread(CFCompareDlg *pcdlg) {
   // Retrieve directories
   LVITEM lvi;
   CString strMask;
   int nPos=0;
   int nNextPos=0;

   memset(&lvi,0,sizeof(lvi));
   pcdlg->m_bAddInProgress = TRUE;

   // Delete files' listview (if files were added, listviews are no longer up to date due 
   // to possible reordering of items in FileInfoArray).
   pcdlg->m_plstFiles->DeleteAllItems();

   // Retrieve files: Sorted by size and ascending, do not include dirs.
   while (nPos < pcdlg->m_strAllowedMasks.GetLength()) {
      nNextPos = pcdlg->m_strAllowedMasks.Find(";",nPos);
      if (nNextPos == -1) nNextPos = pcdlg->m_strAllowedMasks.GetLength();
      strMask = pcdlg->m_strAllowedMasks.Mid(nPos, nNextPos-nPos);
      strMask.TrimLeft();
      strMask.TrimRight();
      TRACE("strMask is %s\n",strMask);
      if (strMask != "")
         pcdlg->m_pfiaInfos->AddDir(pcdlg->m_strDirectory, strMask, pcdlg->m_bRecurse, 
            CFileInfoArray::AP_SORTBYSIZE | CFileInfoArray::AP_SORTASCENDING, FALSE, 
            &pcdlg->m_bAbort);
      nPos = nNextPos+1;
   }

   pcdlg->m_lblStatus.SetWindowText(_T("Filling listview..."));

   pcdlg->m_ulProgress = 0;
   pcdlg->m_ulProgressMax = pcdlg->m_pfiaInfos->GetSize();

   pcdlg->m_bAddInProgress = FALSE;
   pcdlg->m_bFillInProgress = TRUE;
   

   // Set common LVITEM attributes
   lvi.pszText = LPSTR_TEXTCALLBACK;
   lvi.mask = LVIF_TEXT | LVIF_PARAM;
   lvi.iSubItem = 0;

   // Insert files
   pcdlg->m_plstFiles->LockWindowUpdate();
   for (int i=0;((i<pcdlg->m_pfiaInfos->GetSize()) && (!pcdlg->m_bAbort));i++) {
      lvi.iItem = i;
      lvi.lParam = (LPARAM) &(*pcdlg->m_pfiaInfos)[i];
      pcdlg->m_plstFiles->InsertItem(&lvi);
      pcdlg->m_ulProgress++;
   }
   pcdlg->m_plstFiles->UnlockWindowUpdate();

   pcdlg->m_bFillInProgress = FALSE;
   pcdlg->PostMessage(WM_SEARCH_FINISHED);
   return 0;
}

BOOL CompareContents(CFileInfo* pfinSrc, CFileInfo* pfinDest, const DWORD dwUpTo, 
   volatile BOOL* pbAbort) {
   // Note this method is not "win64 friendly"
   FILE* fSrc;
   FILE* fDest;
   DWORD dwCount = 0;
   BYTE cSrc, cDest;

   if ((dwUpTo == 0) || (dwUpTo > pfinSrc->GetLength())) 
      dwCount = pfinSrc->GetLength();
   else
      dwCount = dwUpTo;

   fSrc = fopen(pfinSrc->GetFilePath(),"rb");
   fDest = fopen(pfinDest->GetFilePath(),"rb");
   if (fSrc && fDest) {
      while (!feof(fSrc) && !feof(fDest) && !(*pbAbort) && (dwCount>0) && 
         fread(&cSrc,1,1,fSrc) && fread(&cDest,1,1,fDest) && (cSrc == cDest)) {
         dwCount--;
      }
   }
   if (fSrc) fclose(fSrc);
   if (fDest) fclose(fDest);
   return (dwCount == 0);
}

UINT CompareThread(CFCompareDlg *pcdlg) {
   CFileInfo* pfinSource;
   CFileInfo* pfinTarget;
   MATCHSTRUCT ms;
   DWORD dwMatchSize=0;
   DWORD dwMatchNumber=0;
   LVITEM lviMatched;
   // Compare
   
   int iSource=0;
   int iTarget=0;

   pcdlg->m_bCompareInProgress = TRUE;
   pcdlg->m_ulProgress = 0;
   pcdlg->m_ulProgressMax = pcdlg->m_fiaSourceInfos.GetSize() + 
      pcdlg->m_fiaTargetInfos.GetSize();

   while ((!pcdlg->m_bAbort) && 
          (iSource<pcdlg->m_fiaSourceInfos.GetSize()) && 
          (iTarget<pcdlg->m_fiaTargetInfos.GetSize())) {

      pfinSource = &pcdlg->m_fiaSourceInfos[iSource];
      pfinTarget = &pcdlg->m_fiaTargetInfos[iTarget];

      // Compare pfinSource with all the files of target with the same size of pfinSource
      for (int i=iTarget;(i<pcdlg->m_fiaTargetInfos.GetSize()) && 
         (pcdlg->m_fiaTargetInfos[i].GetLength64() == pfinSource->GetLength64());i++) {
         pfinTarget = &pcdlg->m_fiaTargetInfos[i];
         if (// Not the same file or Ignore duplicates unchecked
             (pcdlg->m_bCompareDuplicates ||
              (pfinSource->GetFilePath().CompareNoCase(pfinTarget->GetFilePath()) != 0)) &&
             // Checksum criteria
             ((pcdlg->m_nMatchCriteria != 1) || 
             (pfinSource->GetChecksum(pcdlg->m_dwUpto, FALSE, &pcdlg->m_bAbort) == 
              pfinTarget->GetChecksum(pcdlg->m_dwUpto, FALSE, &pcdlg->m_bAbort))) &&
             // CRC criteria
             ((pcdlg->m_nMatchCriteria != 2) || 
             (pfinSource->GetCRC(pcdlg->m_dwUpto, FALSE, &pcdlg->m_bAbort) == 
              pfinTarget->GetCRC(pcdlg->m_dwUpto, FALSE, &pcdlg->m_bAbort))) &&
             // Contents criteria
             ((pcdlg->m_nMatchCriteria != 3) || 
             (CompareContents(pfinSource, pfinTarget, pcdlg->m_dwUpto, &pcdlg->m_bAbort)))
             ) {
             // Match!
             ms.pfinTarget = pfinTarget;
             ms.pfinSource = pfinSource;
             pcdlg->m_msaMatchedInfos.InsertAt(pcdlg->m_msaMatchedInfos.GetSize(), ms);
             dwMatchSize += pfinTarget->GetLength();
             dwMatchNumber++;
         }

⌨️ 快捷键说明

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