下载本应用
有时我们安装一个软件,想知道哪些文件是该软件创建的,这时就需要,将当前的磁盘目录与安装软件前的磁盘目录进行比较。出于此目的,编写了“目录比对”Windows应用。
使用方法
软件界面有两个树控件,左侧的我们将其命名为“原始目录”,右侧的命名为“当前目录”;使用任一树控件,右击弹出右键菜单,点击“加载磁盘目录”菜单项,可以选择某个文件夹,或直接选择根目录,比如C盘;将磁盘目录加载到树控件,然后点击右键菜单项,保存到文件。可以将文件命名为“原始C目录”,这时安装需要检测其安装文件目录信息的软件,安装完成后,将“原始C目录”文件加载到“原始目录”树控件,在“当前目录”树控件加载现在的C盘目录。加载完成后,点击“开始比对”按钮,将“原始目录”树控件,与“当前目录”树控件的项文本进行比较,新增的文件和文件夹项,在其左侧添加了“+”状态图像,如果是文件夹,其所有子项都为新增项。这时,可以直观的知道那些文件新创建的。还可以将新创建的文件路径保存到TXT文件。方法是选中根目录项,或其某个子项,在右键菜单中点击“添加的文件信息”,弹出“添加的文件信息”对话框,所有添加文件的路径列表显示在窗口中,全选路径列表然后保存到文件。具有红色图像的项,表示其子项中包含具有“+”图像的项。比对完成后,“原始目录”还可以显示被删除的项,其添加了“-”图像,被删除项的所有父项将添加黑色图像。
“目录比对”开发信息
树控件是可以比较的,本示例就是比较两个树控件的项文本。相同项不做标记,给不同项添加状态图像。比较在MyCheck函数中进行,GetChildInfo函数获取指定项的所有子项的数量,项文本,项句柄,并做标记。首先传递给MyCheck函数两个NULL参数,分别获取“原始目录”,“当前目录”的NULL子项信息,也就是获取所有根项信息,将“原始目录”所有根项标记-1,将“当前目录”所有根项标记1。建立嵌套的for循环,将“原始目录”中的文本相同项,重新标记为0,将“当前目录”中的文本相同项,也标记为0,这样,“原始目录”中的不同项标记仍为-1,“当前目录”中的不同项标记仍为1,将“原始目录”中标记-1的项添加状态图像“-”,将“当前目录”中标记1的项添加状态图像“+”。不同项就没有比较的需要了,将所有相同项进行子项的比较,在MyCheck函数内,调用MyCheck函数,传入的参数为“原始目录”相同项的句柄和“当前目录”相同项的句柄。获取子项信息时,为每个子项信息都使用new创建了INFO结构对象,使用完成后,需delete。
程序使用MFC对话框应用程序创建。
“目录比对”应用的所有代码
目录比对Dlg.h
// 目录比对Dlg.h : 头文件
//
#pragma once
#include "afxcmn.h"
#include "afxwin.h"
#include "afxshelltreectrl.h"
#include "MyTree.h"
#include "MyButton.h"
#include "Dlg1.h"
#include "Dlg2.h"
class USE//用于在不同线程中访问对话框控件时,避免访问冲突
{
public:
USE()
{
hNotUse = CreateEvent(NULL, TRUE, TRUE, NULL);//手动重置,初始有信号
}
HANDLE hNotUse = NULL;//“没有占用”事件句柄
void BeginUse()//开始占用
{
WaitForSingleObject(hNotUse, INFINITE);
ResetEvent(hNotUse);
}
void EndUse()//结束占用
{
SetEvent(hNotUse);
}
};
class C目录比对Dlg : public CDialogEx
{
// 构造
public:
C目录比对Dlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_MY_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
USE use;
CStatic sta2;//静态文本控件“原始目录”
CStatic sta3;//静态文本控件“当前目录”
CStatic sta5;//静态文本控件,显示状态文本
CMyTree tree1;//树控件1
CMyTree tree2;//树控件2
CEdit edit1;//编辑控件1,显示树控件1项数量
CEdit edit2;//编辑控件2,显示树控件2项数量
CMyButton Stop_btn;//“停止比对”按钮
CMyButton Star_btn;//“开始比对”按钮
CImageList imagelist;
CFont font1;
CBrush brush;
CBrush brush1;
WCHAR* Path;//当前路径
afx_msg void OnBnClickedOk();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
void _SetPos();//定位控件
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
HANDLE hExit1;
BOOL SeekFor1(CString pstr, HTREEITEM h);
HANDLE hLoadDiskThread1 = NULL;//tree1“加载磁盘目录”线程句柄
int Count1;
afx_msg void OnTree132773();//tree1“加载磁盘目录”菜单项,单击响应函数
HANDLE hLoadFileThread1 = NULL;//tree1“加载文件”线程句柄
int FileCount1;
afx_msg void OnTree132771();//tree1“加载文件”菜单项,单击响应函数
afx_msg void OnTree132774();//tree1“保存到文件”菜单项,单击响应函数
afx_msg void OnTree132775();//tree1“折叠所有项”菜单项,单击响应函数
afx_msg void OnTree132780();//tree1“终止任务”菜单项,单击响应函数
HANDLE hExit2;
BOOL SeekFor2(CString pstr, HTREEITEM h);
HANDLE hLoadDiskThread2 = NULL;//tree2“加载磁盘目录”线程句柄
int Count2;
afx_msg void OnTree232772();//tree2"加载磁盘目录"菜单项,单击响应函数
HANDLE hLoadFileThread2 = NULL;
int FileCount2;
afx_msg void OnTree232776();//tree2“加载文件”菜单项,单击响应函数
afx_msg void OnTree232777();//tree2“保存到文件”菜单项,单击响应函数
afx_msg void OnTree232778();//tree2“折叠所有项”菜单项,单击响应函数
afx_msg void OnTree232779();//tree2“终止任务”菜单项,单击响应函数
afx_msg void OnDestroy();
void Save(CMyTree* pTree);
void Expand(CMyTree* pTree);
HANDLE hStop;//"比对停止"事件句柄
HANDLE hCheckThread = NULL;//比对线程句柄
UINT COUNT = 0;
UINT CUR = 0;
UINT XuHao = 0;
afx_msg void OnBnClickedButton1();//开始比对
afx_msg void OnBnClickedButton2();//停止比对
void MyCheck(HTREEITEM hA, HTREEITEM hB);
int GetChildInfo(CObArray& X, CMyTree* pTree, HTREEITEM hItem);//获取直接子项的信息,不包括子项的子项
void SetMask(CMyTree* pTree, HTREEITEM hItem, int index);
void SetPar(CMyTree* pTree, HTREEITEM hPar, int index);
CString StateText;
void SetStateText(CString text);//显示工作状态文本
CProgressCtrl pro;
CDlg1 dlg1;
CDlg2 dlg2;
afx_msg void OnTree132781();//“删除的文件信息”菜单项,单击响应函数
afx_msg void OnTree232782();//“增加的文件信息”菜单项,单击响应函数
CString PlusInfo;
int GetStateImage(CMyTree* pTree, HTREEITEM hItem);//获取状态图像的索引
UINT GetCJ(HTREEITEM hItem, CMyTree* pTree);//获取指定项的层次
CString GetString(HTREEITEM hItem, CMyTree* pTree);//获取项描述字符串
};
目录比对Dlg.cpp
// 目录比对Dlg.cpp : 实现文件
//
#include "stdafx.h"
#include "目录比对.h"
#include "目录比对Dlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// C目录比对Dlg 对话框
C目录比对Dlg::C目录比对Dlg(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_MY_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);//加载应用程序图标
font1.CreatePointFont(100, L"微软雅黑");
brush.CreateSolidBrush(RGB(70, 50, 50));
brush1.CreateSolidBrush(RGB(70, 90, 90));
hExit1 = CreateEvent(NULL, TRUE, FALSE, NULL);//手动重置,初始无信号
hExit2 = CreateEvent(NULL, TRUE, FALSE, NULL);//手动重置,初始无信号
hStop = CreateEvent(NULL, TRUE, FALSE, NULL);//手动重置,初始无信号
}
void C目录比对Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TREE1, tree1);
DDX_Control(pDX, IDC_TREE2, tree2);
DDX_Control(pDX, IDC_STA2, sta2);
DDX_Control(pDX, IDC_STA3, sta3);
DDX_Control(pDX, IDC_STA5, sta5);
DDX_Control(pDX, IDC_EDIT1, edit1);
DDX_Control(pDX, IDC_EDIT2, edit2);
DDX_Control(pDX, IDC_BUTTON2, Stop_btn);
DDX_Control(pDX, IDC_BUTTON1, Star_btn);
DDX_Control(pDX, IDC_PROGRESS1, pro);
}
BEGIN_MESSAGE_MAP(C目录比对Dlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDOK, &C目录比对Dlg::OnBnClickedOk)
ON_BN_CLICKED(IDC_BUTTON1, &C目录比对Dlg::OnBnClickedButton1)
ON_WM_ERASEBKGND()
ON_WM_CTLCOLOR()
ON_COMMAND(ID_TREE2_32772, &C目录比对Dlg::OnTree232772)
ON_COMMAND(ID_TREE1_32773, &C目录比对Dlg::OnTree132773)
ON_COMMAND(ID_TREE1_32771, &C目录比对Dlg::OnTree132771)
ON_COMMAND(ID_TREE1_32774, &C目录比对Dlg::OnTree132774)
ON_WM_DESTROY()
ON_COMMAND(ID_TREE1_32775, &C目录比对Dlg::OnTree132775)
ON_COMMAND(ID_TREE2_32776, &C目录比对Dlg::OnTree232776)
ON_COMMAND(ID_TREE2_32777, &C目录比对Dlg::OnTree232777)
ON_COMMAND(ID_TREE2_32778, &C目录比对Dlg::OnTree232778)
ON_COMMAND(ID_TREE1_32780, &C目录比对Dlg::OnTree132780)
ON_COMMAND(ID_TREE2_32779, &C目录比对Dlg::OnTree232779)
ON_BN_CLICKED(IDC_BUTTON2, &C目录比对Dlg::OnBnClickedButton2)
ON_COMMAND(ID_TREE1_32781, &C目录比对Dlg::OnTree132781)
ON_COMMAND(ID_TREE2_32782, &C目录比对Dlg::OnTree232782)
END_MESSAGE_MAP()
BOOL C目录比对Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
imagelist.Create(16, 16, ILC_COLOR32, 0, 0);//创建图像列表
imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON1));//第1个图像不使用
imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON2));//索引1,“+”图像
imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON3));//索引2,“-”图像
imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON4));//索引3,红色图像
imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON5));//索引4,黑色图像
tree1.SetImageList(&imagelist, TVSIL_STATE); tree2.SetImageList(&imagelist, TVSIL_STATE);
sta2.SetFont(&font1); sta3.SetFont(&font1); sta5.SetFont(&font1);
edit1.SetFont(&font1); edit2.SetFont(&font1);
tree1.SetFont(&font1); tree2.SetFont(&font1);
tree1.SetBkColor(RGB(156, 145, 132)); tree2.SetBkColor(RGB(156, 145, 132));
SetWindowTheme(pro.GetSafeHwnd(), _T(""), _T(""));//设置进度条颜色和背景颜色需关闭视觉样式
pro.SetBarColor(RGB(250, 60, 10));//设置进度条颜色
pro.SetBkColor(RGB(70, 90, 90));//设置进度条背景色
pro.SetRange(0, 100);//指定进度条范围
CRect rect(0, 0, 780, 600);//设置客户区大小,宽780像素,高600像素
DWORD style = GetExStyle();//获取对话框扩展样式
if (style & WS_EX_CLIENTEDGE)//如果对话框包含WS_EX_CLIENTEDGE样式,CalcWindowRect函数参数2使用CWnd::adjustOutside
{
CalcWindowRect(rect, CWnd::adjustOutside);//计算带边框的对话框窗口大小。CalcWindowRect函数为CWnd类函数
}
else//如果对话框不包含WS_EX_CLIENTEDGE样式,CalcWindowRect函数参数2使用CWnd::adjustBorder
{
CalcWindowRect(rect, CWnd::adjustBorder);//计算带边框的对话框窗口大小
}
MoveWindow(&rect);//设置对话框的大小
CenterWindow();//居中对话框
_SetPos();//定位控件
CreateDirectory(L"比对数据", NULL);//创建文件夹
Path = new WCHAR[MAX_PATH];
GetCurrentDirectory(MAX_PATH, Path);//获取当前路径
return TRUE;
}
void C目录比对Dlg::OnDestroy()
{
CDialogEx::OnDestroy();
delete[] Path;
}
void C目录比对Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
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;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
HCURSOR C目录比对Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void C目录比对Dlg::OnBnClickedOk()
{
}
BOOL C目录比对Dlg::OnEraseBkgnd(CDC* pDC)
{
CRect rect;
GetClientRect(rect);
pDC->FillSolidRect(rect, RGB(70, 50, 50));
CRect r2, r3;
tree1.GetWindowRect(r2); ScreenToClient(r2); r2.InflateRect(1, 1);
tree2.GetWindowRect(r3); ScreenToClient(r3); r3.InflateRect(1, 1);
pDC->FrameRect(r2, &CBrush(RGB(0, 0, 0)));
pDC->FrameRect(r3, &CBrush(RGB(0, 0, 0)));
CRect r5, r6, r7;
edit1.GetWindowRect(r5); ScreenToClient(r5); r5.InflateRect(1, 1);
edit2.GetWindowRect(r6); ScreenToClient(r6); r6.InflateRect(1, 1);
pDC->FrameRect(r5, &CBrush(RGB(0, 0, 0)));
pDC->FrameRect(r6, &CBrush(RGB(0, 0, 0)));
CRgn rgn;
rgn.CreateRectRgn(0, 0, 0, 0);
pro.GetWindowRgn((HRGN)rgn);
rgn.GetRgnBox(r7);
pro.ClientToScreen(r7); ScreenToClient(r7); r7.InflateRect(2, 2,0,0);
pDC->FrameRect(r7, &CBrush(RGB(0, 0, 0)));
return TRUE;
// return CDialogEx::OnEraseBkgnd(pDC);
}
void C目录比对Dlg::_SetPos()//
{
sta2.MoveWindow(10, 6, 376, 20);
sta3.MoveWindow(394, 6, 376, 20);
CRect Client_rect;
GetClientRect(Client_rect);
sta5.MoveWindow(12, Client_rect.bottom-30, Client_rect.right-24, 20);//静态文本控件,用作状态栏
tree1.MoveWindow(10, 30, 376, 389);
tree2.MoveWindow(394, 30, 376, 389);
edit1.MoveWindow(10, 425, 376, 20);
edit2.MoveWindow(394, 425, 376, 20);
pro.MoveWindow(9, 450, Client_rect.right - 16, 24);
Stop_btn.MoveWindow(108, 486, 180, 40);
Star_btn.MoveWindow(492, 486, 180, 40);
CRect r1;
pro.GetClientRect(r1); r1.DeflateRect(1, 1);
CRgn rgn;
rgn.CreateRectRgn(r1.left, r1.top, r1.right, r1.bottom);
pro.SetWindowRgn(rgn.operator HRGN(), 1);
}
HBRUSH C目录比对Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
if (pWnd->GetDlgCtrlID() == IDC_STA2 || pWnd->GetDlgCtrlID() == IDC_STA3 || pWnd->GetDlgCtrlID() == IDC_STA5)//
{
pDC->SetBkColor(RGB(70, 50, 50));//设置背景颜色
pDC->SetTextColor(RGB(186, 175, 162));//设置文本颜色
return (HBRUSH)brush;
}
if (pWnd->GetDlgCtrlID() == IDC_EDIT1 || pWnd->GetDlgCtrlID() == IDC_EDIT2)
{
pDC->SetBkColor(RGB(70, 90, 90));//设置背景颜色
pDC->SetTextColor(RGB(187, 186, 220));//设置文本颜色
return (HBRUSH)brush1;
}
return hbr;
}
BOOL C目录比对Dlg::SeekFor1(CString pstr, HTREEITEM h)
{
CFileFind ff;
BOOL bWorking = ff.FindFile(pstr, 0);
while (bWorking)
{
DWORD dw = WaitForSingleObject(hExit1, 0);
if (dw == WAIT_OBJECT_0)
{
return TRUE;
}
bWorking = ff.FindNextFile();
if (ff.IsDots())continue;
CString str1, str2;
str1 = ff.GetFileName(); str2 = ff.GetFilePath();
HTREEITEM hItem = tree1.InsertItem(str1, h);
Count1++;
use.BeginUse();
SetDlgItemInt(IDC_EDIT1, Count1);
use.EndUse();
if (ff.IsDirectory())//如果是文件夹
SeekFor1(str2 + L"\\*.*", hItem);
}
return FALSE;
}
UINT LoadDiskThread1(LPVOID pParam)//树控件1加载磁盘目录线程
{
C目录比对Dlg* pDlg = (C目录比对Dlg*)pParam;
BROWSEINFO bi;
char buffer[MAX_PATH];
ZeroMemory(buffer, MAX_PATH);
bi.hwndOwner = pDlg->GetSafeHwnd();
bi.pidlRoot = NULL;
bi.pszDisplayName = LPWSTR(buffer);
bi.lpszTitle = _T("选择一个文件夹");
bi.ulFlags = BIF_EDITBOX;
bi.lpfn = NULL;
bi.lParam = 0;
bi.iImage = 0;
LPITEMIDLIST pList = NULL;
if ((pList = SHBrowseForFolder(&bi)) == NULL)return (UINT)(pDlg->hLoadDiskThread1 = NULL);
char path[MAX_PATH];
ZeroMemory(path, MAX_PATH);
SHGetPathFromIDList(pList, LPWSTR(path));
CString SeekPath = LPCTSTR(path);
CString R = SeekPath.Right(1);
if (R == L"\\")SeekPath += L"*.*";
else SeekPath += L"\\*.*";
CString SeekText = SeekPath;
int find = SeekText.Find(L"\\*.*");
if (find != -1)
SeekText.Delete(find, 4);
pDlg->tree1.DeleteAllItems();
ResetEvent(pDlg->hExit1);
pDlg->use.BeginUse();
pDlg->sta2.SetWindowText(SeekText);
pDlg->sta5.SetWindowText(L"“原始目录”加载磁盘目录进行中");
pDlg->use.EndUse();
pDlg->Count1 = 0;
HTREEITEM hITEM = pDlg->tree1.InsertItem(SeekText, NULL);
pDlg->Count1++;
pDlg->SeekFor1(SeekPath, hITEM);
HTREEITEM hRoot = pDlg->tree1.GetRootItem();
pDlg->tree1.Expand(hRoot, TVE_EXPAND);
pDlg->SetStateText(L"加载磁盘目录完成");
return (UINT)(pDlg->hLoadDiskThread1 = NULL);
}
void C目录比对Dlg::OnTree132773()//tree1“加载磁盘目录”菜单项,单击响应函数
{
if (hLoadDiskThread1 != NULL)return;//如果线程正在运行,不再创建新的线程
hLoadDiskThread1 = AfxBeginThread(LoadDiskThread1, this, 0, 0, 0)->m_hThread;
}
UINT LoadFileThread1(LPVOID pParam)//树控件1加载文件线程
{
C目录比对Dlg* pDlg = (C目录比对Dlg*)pParam;
CFileDialog FD(TRUE);
FD.m_ofn.lpstrInitialDir = (CString)pDlg->Path + L"\\比对数据";//指定初始目录
FD.m_ofn.lpstrFilter = _T("DAT文件\0*.dat\0\0");//指定过滤器
if (FD.DoModal() != IDOK)return (UINT)(pDlg->hLoadFileThread1 = NULL);
ResetEvent(pDlg->hExit1);
CString PathName = FD.GetPathName();
CString Name = FD.GetFileName();
pDlg->use.BeginUse();
pDlg->sta2.SetWindowText(Name); pDlg->sta5.SetWindowText(L"“原始目录”加载文件进行中");
pDlg->use.EndUse();
pDlg->FileCount1 = 0;
pDlg->tree1.DeleteAllItems();
CFile F(PathName, CFile::modeRead);
CArchive ar(&F, CArchive::load);
HTREEITEM h[256];
CString item_str; UINT cj, count;//记录项文本,项层级,项总数
ar >> count;
for (UINT i = 0; i < count; i++)
{
ar >> item_str >> cj;
if (cj == 0)
{
h[cj] = pDlg->tree1.InsertItem(item_str, 0, 0); pDlg->FileCount1++;
}
else
{
h[cj] = pDlg->tree1.InsertItem(item_str, h[cj - 1], TVI_LAST); pDlg->FileCount1++;
}
pDlg->use.BeginUse();
pDlg->SetDlgItemInt(IDC_EDIT1, pDlg->FileCount1);
pDlg->use.EndUse();
DWORD dw = WaitForSingleObject(pDlg->hExit1, 0);
if (dw == WAIT_OBJECT_0)
{
pDlg->SetStateText(L"已终止任务");
return (UINT)(pDlg->hLoadFileThread1 = NULL);
}
}
HTREEITEM hRoot = pDlg->tree1.GetRootItem();//获取第一个根项
pDlg->tree1.Expand(hRoot, TVE_EXPAND);//展开根项的子项
pDlg->SetStateText(L"加载文件完成");
return (UINT)(pDlg->hLoadFileThread1 = NULL);
}
void C目录比对Dlg::OnTree132771()//tree1“加载文件”菜单项,单击响应函数
{
if (hLoadFileThread1 != NULL)return;
hLoadFileThread1=AfxBeginThread(LoadFileThread1, this, 0, 0, 0)->m_hThread;
}
void C目录比对Dlg::OnTree132774()//tree1“保存到文件”菜单项,单击响应函数
{
Save(&tree1);
}
void C目录比对Dlg::OnTree132775()//tree1“折叠所有项”菜单项,单击响应函数
{
Expand(&tree1);
}
void C目录比对Dlg::OnTree132780()//tree1“终止任务”菜单项,单击响应函数
{
SetEvent(hExit1);
}
BOOL C目录比对Dlg::SeekFor2(CString pstr, HTREEITEM h)
{
CFileFind ff;
BOOL bWorking = ff.FindFile(pstr, 0);
while (bWorking)
{
DWORD dw = WaitForSingleObject(hExit2, 0);
if (dw == WAIT_OBJECT_0)
{
return TRUE;
}
bWorking = ff.FindNextFile();
if (ff.IsDots())continue;
CString str1, str2;
str1 = ff.GetFileName(); str2 = ff.GetFilePath();
HTREEITEM hItem = tree2.InsertItem(str1, h);
Count2++;
use.BeginUse();
SetDlgItemInt(IDC_EDIT2, Count2);
use.EndUse();
if (ff.IsDirectory())//如果是文件夹
SeekFor2(str2 + L"\\*.*", hItem);
}
return FALSE;
}
UINT LoadDiskThread2(LPVOID pParam)//树控件2加载磁盘目录线程
{
C目录比对Dlg* pDlg = (C目录比对Dlg*)pParam;
BROWSEINFO bi;
char buffer[MAX_PATH];
ZeroMemory(buffer, MAX_PATH);
bi.hwndOwner = pDlg->GetSafeHwnd();
bi.pidlRoot = NULL;
bi.pszDisplayName = LPWSTR(buffer);
bi.lpszTitle = _T("选择一个文件夹");
bi.ulFlags = BIF_EDITBOX;
bi.lpfn = NULL;
bi.lParam = 0;
bi.iImage = 0;
LPITEMIDLIST pList = NULL;
if ((pList = SHBrowseForFolder(&bi)) == NULL)return (UINT)(pDlg->hLoadDiskThread2 = NULL);
char path[MAX_PATH];
ZeroMemory(path, MAX_PATH);
SHGetPathFromIDList(pList, LPWSTR(path));
CString SeekPath = LPCTSTR(path);
CString R = SeekPath.Right(1);
if (R == L"\\")SeekPath += L"*.*";
else SeekPath += L"\\*.*";
CString SeekText = SeekPath;
int find = SeekText.Find(L"\\*.*");
if (find != -1)
SeekText.Delete(find, 4);
pDlg->tree2.DeleteAllItems();
ResetEvent(pDlg->hExit2);
pDlg->use.BeginUse();
pDlg->sta3.SetWindowText(SeekText);
pDlg->sta5.SetWindowText(L"“当前目录”加载磁盘目录进行中");
pDlg->use.EndUse();
pDlg->Count2 = 0;
HTREEITEM hITEM = pDlg->tree2.InsertItem(SeekText, NULL);
pDlg->Count2++;
pDlg->SeekFor2(SeekPath, hITEM);
HTREEITEM hRoot = pDlg->tree2.GetRootItem();
pDlg->tree2.Expand(hRoot, TVE_EXPAND);
pDlg->SetStateText(L"加载磁盘目录完成");
return (UINT)(pDlg->hLoadDiskThread2 = NULL);
}
void C目录比对Dlg::OnTree232772()//tree2"加载磁盘目录"菜单项,单击响应函数
{
if (hLoadDiskThread2 != NULL)return;//如果线程正在运行,不再创建新的线程
hLoadDiskThread2 = AfxBeginThread(LoadDiskThread2, this, 0, 0, 0)->m_hThread;
}
UINT LoadFileThread2(LPVOID pParam)//树控件2加载文件线程
{
C目录比对Dlg* pDlg = (C目录比对Dlg*)pParam;
CFileDialog FD(TRUE);
FD.m_ofn.lpstrInitialDir = (CString)pDlg->Path + L"\\比对数据";//指定初始目录
FD.m_ofn.lpstrFilter = _T("DAT文件\0*.dat\0\0");//指定过滤器
if (FD.DoModal() != IDOK)return (UINT)(pDlg->hLoadFileThread2 = NULL);
ResetEvent(pDlg->hExit2);
CString PathName = FD.GetPathName();
CString Name = FD.GetFileName();
pDlg->use.BeginUse();
pDlg->sta3.SetWindowText(Name); pDlg->sta5.SetWindowText(L"“当前目录”加载文件进行中");
pDlg->use.EndUse();
pDlg->FileCount2 = 0;
pDlg->tree2.DeleteAllItems();
CFile F(PathName, CFile::modeRead);
CArchive ar(&F, CArchive::load);
HTREEITEM h[256];
CString item_str; UINT cj, count;//记录项文本,项层级,项总数
ar >> count;
for (UINT i = 0; i < count; i++)
{
ar >> item_str >> cj;
if (cj == 0)
{
h[cj] = pDlg->tree2.InsertItem(item_str, 0, 0); pDlg->FileCount2++;
}
else
{
h[cj] = pDlg->tree2.InsertItem(item_str, h[cj - 1], TVI_LAST); pDlg->FileCount2++;
}
pDlg->use.BeginUse();
pDlg->SetDlgItemInt(IDC_EDIT2, pDlg->FileCount2);
pDlg->use.EndUse();
DWORD dw = WaitForSingleObject(pDlg->hExit2, 0);
if (dw == WAIT_OBJECT_0)
{
pDlg->SetStateText(L"已终止任务");
return (UINT)(pDlg->hLoadFileThread2 = NULL);
}
}
HTREEITEM hRoot = pDlg->tree2.GetRootItem();//获取第一个根项
pDlg->tree2.Expand(hRoot, TVE_EXPAND);//展开根项的子项
pDlg->SetStateText(L"加载文件完成");
return (UINT)(pDlg->hLoadFileThread2 = NULL);
}
void C目录比对Dlg::OnTree232776()//tree2“加载文件”菜单项,单击响应函数
{
if (hLoadFileThread2 != NULL)return;
hLoadFileThread2 = AfxBeginThread(LoadFileThread2, this, 0, 0, 0)->m_hThread;
}
void C目录比对Dlg::OnTree232777()//tree2“保存到文件”菜单项,单击响应函数
{
Save(&tree2);
}
void C目录比对Dlg::OnTree232778()//tree2“折叠所有项”菜单项,单击响应函数
{
Expand(&tree2);
}
void C目录比对Dlg::OnTree232779()//tree2“终止任务”菜单项,单击响应函数
{
SetEvent(hExit2);
}
void C目录比对Dlg::Save(CMyTree* pTree)
{
HTREEITEM h_item = pTree->GetRootItem();//获取第一个根项
CString item_str; UINT cj = 0; //记录项文本,项层级
if (h_item == NULL)return; //如果树控件不包含任何项返回
else
{
item_str = pTree->GetItemText(h_item); //获取项文本
}
CFileDialog FD(FALSE, L"dat", NULL, OFN_FILEMUSTEXIST, NULL);
FD.m_ofn.lpstrInitialDir = (CString)Path + L"\\比对数据";//指定初始目录
FD.m_ofn.lpstrFilter = _T("DAT文件\0*.dat\0\0");//指定过滤器
if (FD.DoModal() != IDOK)return;
if (*pTree == tree1)
{
sta5.SetWindowText(L"“原始目录”保存到文件进行中");
}
else
{
sta5.SetWindowText(L"“当前目录”保存到文件进行中");
}
CString PathName = FD.GetPathName();
CFile F(PathName, CFile::modeCreate | CFile::modeWrite);
CArchive ar(&F, CArchive::store);
UINT count = pTree->GetCount();
ar << count;
ar << item_str << cj;//写入项文本,项层级
jump1:
if (pTree->ItemHasChildren(h_item)) //如果有子项
{
h_item = pTree->GetChildItem(h_item);//获取子项
cj += 1;//层级加1
item_str = pTree->GetItemText(h_item);//获取项文本
ar << item_str << cj;//写入项文本,项层级
goto jump1;
}
jump2:
if (pTree->GetNextSiblingItem(h_item) == NULL) //如果没有下一个兄弟项
{
if (cj == 0)goto end;//如果层级到达0,且没有下一个兄弟项,跳出循环
h_item = pTree->GetParentItem(h_item);//获取父项
cj -= 1;//层级减1
goto jump2;
}
else //如果有下一个兄弟项
{
h_item = pTree->GetNextSiblingItem(h_item);//获取下一个兄弟项
item_str = pTree->GetItemText(h_item);//获取项文本
ar << item_str << cj;//写入项文本,项层级
goto jump1;
}
end:
SetStateText(L"保存到文件完成");
}
void C目录比对Dlg::Expand(CMyTree* pTree)//折叠树控件所有项
{
HTREEITEM h_item = pTree->GetRootItem();//获取第一个根项
if (h_item == NULL)return; //如果树控件不包含任何项返回
int cj = 0;
jump1:
if (pTree->ItemHasChildren(h_item)) //如果有子项
{
pTree->Expand(h_item, TVE_COLLAPSE);
h_item = pTree->GetChildItem(h_item);//获取子项
cj += 1;//层级加1
goto jump1;
}
jump2:
if (pTree->GetNextSiblingItem(h_item) == NULL) //如果没有下一个兄弟项
{
if (cj == 0)goto end;//如果层级到达0,且没有下一个兄弟项,跳出循环
h_item = pTree->GetParentItem(h_item);//获取父项
cj -= 1;//层级减1
goto jump2;
}
else //如果有下一个兄弟项
{
h_item = pTree->GetNextSiblingItem(h_item);//获取下一个兄弟项
goto jump1;
}
end:
SetStateText(L"折叠所有项完成");
}
UINT CheckThread(LPVOID pParam)//比对线程
{
C目录比对Dlg* pDlg = (C目录比对Dlg*)pParam;
pDlg->COUNT = pDlg->tree1.GetCount();//获取树控件1项总数
pDlg->CUR = 0;
ResetEvent(pDlg->hStop);
pDlg->sta5.SetWindowText(L"比对进行中");
pDlg->MyCheck(NULL, NULL);
pDlg->SetStateText(L"比对完成");
pDlg->MessageBox(L"比对完成");
return (UINT)(pDlg->hCheckThread = NULL);
}
void C目录比对Dlg::OnBnClickedButton1()//开始比对
{
if (hCheckThread || hLoadDiskThread1 || hLoadDiskThread2 || hLoadFileThread1 || hLoadFileThread2)return;
hCheckThread = AfxBeginThread(CheckThread, this, 0, 0, 0)->m_hThread;
}
void C目录比对Dlg::OnBnClickedButton2()//停止比对
{
SetEvent(hStop);
}
struct INFO {
HTREEITEM hItem;//项句柄
WCHAR name[MAX_PATH];//项文本
int mask;//标记
BOOL Child = FALSE;//TRUE有子项,FALSE没有子项
};
struct T {
INFO* pA = NULL;
INFO* pB = NULL;
};
void C目录比对Dlg::MyCheck(HTREEITEM hA, HTREEITEM hB)
{
DWORD dw = WaitForSingleObject(hStop, 0);
if (dw == WAIT_OBJECT_0)return;
CObArray OA, OB, OT;
int CountA = GetChildInfo(OA, &tree1, hA);//获取直接子项的信息
int CountB = GetChildInfo(OB, &tree2, hB);//获取直接子项的信息
CUR += CountA;
pro.SetPos(CUR * 100 / COUNT);//进度条设置当前位置
for (int i = 0; i < CountA; i++)//标记树控件1中的相同项
{
INFO* pInfoA = (INFO*)OA.GetAt(i);
for (int j = 0; j < CountB; j++)
{
INFO* pInfoB = (INFO*)OB.GetAt(j);
if (wcscmp(pInfoA->name, pInfoB->name)==0)//如果项文本相同
{
pInfoA->mask = 0;//相同项标记0
}
}
}
for (int i = 0; i < CountB; i++)//标记树控件2中的相同项
{
INFO* pInfoB = (INFO*)OB.GetAt(i);
for (int j = 0; j < CountA; j++)
{
INFO* pInfoA = (INFO*)OA.GetAt(j);
if (wcscmp(pInfoA->name, pInfoB->name) == 0)//如果项文本相同
{
pInfoB->mask = 0;//相同项标记0
T* pT = new T();
pT->pA = pInfoA;
pT->pB = pInfoB;
OT.Add((CObject*)pT);//将相同项加入OT数组
}
}
}
for (int i = 0; i < CountA; i++)//将树控件1中标记-1的项,添加状态图像“-”
{
INFO* pInfoA = (INFO*)OA.GetAt(i);
if (pInfoA->mask == -1)
{
SetMask(&tree1, pInfoA->hItem, 2);
}
}
for (int i = 0; i < CountB; i++)//将树控件2中标记1的项,添加状态图像“+”
{
INFO* pInfoB = (INFO*)OB.GetAt(i);
if (pInfoB->mask == 1)
{
SetMask(&tree2, pInfoB->hItem, 1);
}
}
int TCount = OT.GetCount();
for (int i = 0; i < TCount; i++)//将相同项进行迭代
{
T* pT = (T*)OT.GetAt(i);
MyCheck(pT->pA->hItem, pT->pB->hItem);
}
for (int i = 0; i < CountA; i++)//删除OA数组中所有元素
{
INFO* pInfo = (INFO*)OA.GetAt(i); delete pInfo;
}
for (int i = 0; i < CountB; i++)//删除OB数组中所有元素
{
INFO* pInfo = (INFO*)OB.GetAt(i); delete pInfo;
}
for (int i = 0; i < OT.GetCount(); i++)//删除OT数组中所有元素
{
T* pT = (T*)OT.GetAt(i); delete pT;
}
}
int C目录比对Dlg::GetChildInfo(CObArray& X, CMyTree* pTree, HTREEITEM hItem)//获取直接子项的信息,不包括子项的子项
{
int Count = 0;
HTREEITEM hChild = pTree->GetChildItem(hItem);//获取第1个子项
if(hChild==NULL)return 0;
CString text = pTree->GetItemText(hChild);
Count++;
INFO* pInfo = new INFO();
pInfo->hItem = hChild;
wmemset(pInfo->name, 0, MAX_PATH);
CopyMemory(pInfo->name, text, (text.GetLength() + 1) * 2);
if (*pTree == tree1)pInfo->mask = -1;
if (*pTree == tree2)pInfo->mask = 1;
if (pTree->ItemHasChildren(hChild))pInfo->Child=TRUE;//如果该子项也有子项,Child标记TRUE
else pInfo->Child = FALSE;//没有子项,标记FALSE
X.Add((CObject*)pInfo);
HTREEITEM hNext = pTree->GetNextSiblingItem(hChild);//获取下一个兄弟项
while (hNext != NULL)
{
Count++;
text = pTree->GetItemText(hNext);
INFO* pInfo = new INFO();
pInfo->hItem = hNext;
wmemset(pInfo->name, 0, MAX_PATH);
CopyMemory(pInfo->name, text, (text.GetLength() + 1) * 2);
if (*pTree == tree1)pInfo->mask = -1;
if (*pTree == tree2)pInfo->mask = 1;
if (pTree->ItemHasChildren(hNext))pInfo->Child = TRUE;//如果该子项也有子项,Child标记TRUE
else pInfo->Child = FALSE;//没有子项,标记FALSE
X.Add((CObject*)pInfo);
hNext = pTree->GetNextSiblingItem(hNext);
}
return Count;
}
void C目录比对Dlg::SetMask(CMyTree* pTree, HTREEITEM hItem, int index)//给指定项添加状态图像“+”或“-”
{
TVITEM tvItem;
tvItem.mask = TVIF_HANDLE | TVIF_STATE;
tvItem.hItem = hItem;//要设置状态图像的项的句柄
tvItem.stateMask = TVIS_STATEIMAGEMASK;//此掩码指定项使用状态图像
tvItem.state = INDEXTOSTATEIMAGEMASK(index);
pTree->SetItem(&tvItem);
if (index == 1)//如果状态图像是“+”
SetPar(pTree, hItem, 3);
else//如果状态图像是“-”
SetPar(pTree, hItem, 4);
}
void C目录比对Dlg::SetPar(CMyTree* pTree, HTREEITEM hPar, int index)//给所有父项添加红色或黑色状态图像
{
hPar = pTree->GetParentItem(hPar);
while (hPar != NULL)
{
TVITEM tvItem;
tvItem.mask = TVIF_HANDLE | TVIF_STATE;
tvItem.hItem = hPar;//要设置状态图像的项的句柄
tvItem.stateMask = TVIS_STATEIMAGEMASK;//此掩码指定项使用状态图像
tvItem.state = INDEXTOSTATEIMAGEMASK(index);
pTree->SetItem(&tvItem);
hPar = pTree->GetParentItem(hPar);
}
}
UINT StateTextThread(LPVOID pParam)
{
C目录比对Dlg* pDlg = (C目录比对Dlg*)pParam;
pDlg->use.BeginUse();
pDlg->sta5.SetWindowText(pDlg->StateText);
pDlg->use.EndUse();
Sleep(5000);
pDlg->use.BeginUse();
pDlg->sta5.SetWindowText(NULL);
pDlg->use.EndUse();
return 1;
}
void C目录比对Dlg::SetStateText(CString text)//显示工作状态文本
{
StateText = text;
AfxBeginThread(StateTextThread, this, 0, 0, 0);
}
void C目录比对Dlg::OnTree132781()//“删除的文件信息”菜单项,单击响应函数
{
XuHao = 0;
CString Info;
UINT cj, cj0;
HTREEITEM hSel = tree1.GetSelectedItem();
if (hSel != NULL)
{
if (GetStateImage(&tree1, hSel) == 2)//如果具有“-”图像
{
Info += GetString(hSel, &tree1);
}
HTREEITEM h_item = tree1.GetChildItem(hSel);
if (h_item == NULL)goto End;
if (GetStateImage(&tree1, h_item) == 2)//如果具有“-”图像
{
Info += GetString(h_item, &tree1);
}
cj = cj0 = GetCJ(h_item, &tree1);//获取h_item项的层级
jump1:
if (tree1.ItemHasChildren(h_item))//如果有子项
{
h_item = tree1.GetChildItem(h_item);//获取子项
cj += 1;
if (GetStateImage(&tree1, h_item) == 2)//如果具有“ - ”图像
{
Info += GetString(h_item, &tree1);
}
goto jump1;
}
jump2:
if (tree1.GetNextItem(h_item, TVGN_NEXT) == NULL)//如果没有下一个兄弟项
{
if (cj == cj0)goto End;//如果层级到达cj0,且没有下一个兄弟项,跳出循环
h_item = tree1.GetParentItem(h_item);//获取父项
cj -= 1;
goto jump2;
}
else//如果有下一个兄弟项
{
h_item = tree1.GetNextItem(h_item, TVGN_NEXT);//获取下一个兄弟项
if (GetStateImage(&tree1, h_item) == 2)//如果具有“-”图像
{
Info += GetString(h_item, &tree1);
}
goto jump1;
}
}
End:
int len = Info.GetLength();
Info.Delete(len - 2, 2);//删除最后的“\r\n”
dlg2.Info = Info;
dlg2.DestroyWindow();
dlg2.Create(IDD_DIALOG2);
}
void C目录比对Dlg::OnTree232782()//“增加的文件信息”菜单项,单击响应函数
{
XuHao = 0;
CString Info;
UINT cj, cj0;
HTREEITEM hSel = tree2.GetSelectedItem();
if (hSel != NULL)
{
if (GetStateImage(&tree2, hSel) == 1)//如果具有“+”图像
{
Info += GetString(hSel, &tree2);
}
HTREEITEM h_item = tree2.GetChildItem(hSel);
if (h_item == NULL)goto End;
if (GetStateImage(&tree2, h_item) == 1)//如果具有“+”图像
{
Info += GetString(h_item, &tree2);
}
cj = cj0 = GetCJ(h_item, &tree2);//获取h_item项的层级
jump1:
if (tree2.ItemHasChildren(h_item))//如果有子项
{
h_item = tree2.GetChildItem(h_item);//获取子项
cj += 1;
if (GetStateImage(&tree2, h_item) == 1)//如果具有“+”图像
{
Info += GetString(h_item, &tree2);
}
goto jump1;
}
jump2:
if (tree2.GetNextItem(h_item, TVGN_NEXT) == NULL)//如果没有下一个兄弟项
{
if (cj == cj0)goto End;//如果层级到达cj0,且没有下一个兄弟项,跳出循环
h_item = tree2.GetParentItem(h_item);//获取父项
cj -= 1;
goto jump2;
}
else//如果有下一个兄弟项
{
h_item = tree2.GetNextItem(h_item, TVGN_NEXT);//获取下一个兄弟项
if (GetStateImage(&tree2, h_item) == 1)//如果具有“+”图像
{
Info += GetString(h_item, &tree2);
}
goto jump1;
}
}
End:
int len = Info.GetLength();
Info.Delete(len - 2, 2);//删除最后的“\r\n”
dlg1.Info = Info;
dlg1.DestroyWindow();
dlg1.Create(IDD_DIALOG1);
}
int C目录比对Dlg::GetStateImage(CMyTree* pTree, HTREEITEM hItem)//获取状态图像的索引
{
TVITEM tvItem;
tvItem.mask = TVIF_HANDLE | TVIF_STATE;
tvItem.hItem = hItem;
pTree->GetItem(&tvItem);
int index = (tvItem.state & TVIS_STATEIMAGEMASK) >> 12;
return index;
}
UINT C目录比对Dlg::GetCJ(HTREEITEM hItem, CMyTree* pTree)//获取指定项的层次
{
UINT cj = 0;
HTREEITEM hPar = pTree->GetParentItem(hItem);
while (hPar != NULL)
{
cj++;
hPar = pTree->GetParentItem(hPar);
}
return cj;
}
CString C目录比对Dlg::GetString(HTREEITEM hItem, CMyTree* pTree)//获取项描述字符串
{
CString str;
CString item = pTree->GetItemText(hItem);
str = item + L"\r\n";
HTREEITEM hPar = pTree->GetParentItem(hItem);
while (hPar != NULL)
{
item = pTree->GetItemText(hPar);
str = item + L"\\" + str;
hPar = pTree->GetParentItem(hPar);
}
XuHao++;
CString xh;
xh.Format(L"%u\t", XuHao);
str = xh + str;
return str;
}
Dlg1.h
#pragma once
#include "afxcmn.h"
#include "MyRichEdit.h"
// CDlg1 对话框
class CDlg1 : public CDialogEx
{
DECLARE_DYNAMIC(CDlg1)
public:
CDlg1(CWnd* pParent = NULL); // 标准构造函数
virtual ~CDlg1();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG1 };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedOk();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
virtual BOOL OnInitDialog();
BOOL B = TRUE;
CMyRichEdit richedit;
CString Info;
afx_msg void OnPaint();
afx_msg void OnRichedit32783();//全选
afx_msg void OnRichedit32784();//复制
afx_msg void OnRichedit32785();//粘贴
afx_msg void OnRichedit32786();//剪切
afx_msg void OnRichedit32787();//撤销
afx_msg void OnRichedit32788();//重做
afx_msg void OnRichedit32789();//保存到文件
afx_msg void OnRichedit32790();//打开文件
void SetFormat();
afx_msg void OnSize(UINT nType, int cx, int cy);
};
Dlg1.cpp
// Dlg1.cpp : 实现文件
//
#include "stdafx.h"
#include "目录比对.h"
#include "Dlg1.h"
#include "afxdialogex.h"
#include "目录比对Dlg.h"
// CDlg1 对话框
IMPLEMENT_DYNAMIC(CDlg1, CDialogEx)
CDlg1::CDlg1(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_DIALOG1, pParent)
{
}
CDlg1::~CDlg1()
{
}
void CDlg1::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_RICHEDIT21, richedit);
}
BEGIN_MESSAGE_MAP(CDlg1, CDialogEx)
ON_BN_CLICKED(IDOK, &CDlg1::OnBnClickedOk)
ON_WM_ERASEBKGND()
ON_WM_PAINT()
ON_COMMAND(ID_RICHEDIT_32783, &CDlg1::OnRichedit32783)
ON_COMMAND(ID_RICHEDIT_32784, &CDlg1::OnRichedit32784)
ON_COMMAND(ID_RICHEDIT_32785, &CDlg1::OnRichedit32785)
ON_COMMAND(ID_RICHEDIT_32786, &CDlg1::OnRichedit32786)
ON_COMMAND(ID_RICHEDIT_32787, &CDlg1::OnRichedit32787)
ON_COMMAND(ID_RICHEDIT_32788, &CDlg1::OnRichedit32788)
ON_COMMAND(ID_RICHEDIT_32789, &CDlg1::OnRichedit32789)
ON_COMMAND(ID_RICHEDIT_32790, &CDlg1::OnRichedit32790)
ON_WM_SIZE()
END_MESSAGE_MAP()
void CDlg1::OnBnClickedOk()
{
}
BOOL CDlg1::OnEraseBkgnd(CDC* pDC)
{
CRect rect;
GetClientRect(rect);
pDC->FillSolidRect(rect, RGB(50, 50, 50));
return TRUE;
// return CDialogEx::OnEraseBkgnd(pDC);
}
BOOL CDlg1::OnInitDialog()
{
CDialogEx::OnInitDialog();
CRect rectC(0, 0, 780, 600);//设置客户区大小,宽780像素,高600像素
DWORD style = GetExStyle();//获取对话框扩展样式
if (style & WS_EX_CLIENTEDGE)//如果对话框包含WS_EX_CLIENTEDGE样式,CalcWindowRect函数参数2使用CWnd::adjustOutside
{
CalcWindowRect(rectC, CWnd::adjustOutside);//计算带边框的对话框窗口大小。CalcWindowRect函数为CWnd类函数
}
else//如果对话框不包含WS_EX_CLIENTEDGE样式,CalcWindowRect函数参数2使用CWnd::adjustBorder
{
CalcWindowRect(rectC, CWnd::adjustBorder);//计算带边框的对话框窗口大小
}
MoveWindow(&rectC);//设置对话框的大小
CenterWindow();//居中对话框
richedit.SetBackgroundColor(FALSE, RGB(255, 193, 132));
CRect rect;
GetClientRect(rect);
rect.DeflateRect(5, 5, 5, 5);
richedit.MoveWindow(rect);
richedit.SetWindowText(Info);
SetFormat();
B = TRUE;
return TRUE;
}
void CDlg1::OnPaint()
{
CPaintDC dc(this); // device context for painting
if (B)
{
B = FALSE;
richedit.SetSel(0, 0);
}
}
void CDlg1::OnRichedit32783()//全选
{
richedit.SetSel(0, -1);
}
void CDlg1::OnRichedit32784()//复制
{
richedit.Copy();
}
void CDlg1::OnRichedit32785()//粘贴
{
richedit.Paste();
}
void CDlg1::OnRichedit32786()//剪切
{
richedit.Cut();
}
void CDlg1::OnRichedit32787()//撤销
{
richedit.Undo();
}
void CDlg1::OnRichedit32788()//重做
{
richedit.Redo();
}
void CDlg1::OnRichedit32789()//保存到文件
{
C目录比对Dlg* pDlg = (C目录比对Dlg*)theApp.m_pMainWnd;
CStringA Text = (CStringA)richedit.GetSelText();
CFileDialog FD(FALSE, L"txt", NULL, OFN_FILEMUSTEXIST, NULL);
FD.m_ofn.lpstrInitialDir = (CString)pDlg->Path + L"\\比对数据";//指定初始目录
FD.m_ofn.lpstrFilter = _T("TXT文件\0*.txt\0\0");//指定过滤器
if (FD.DoModal() != IDOK)return;
CString PathName = FD.GetPathName();
CFile F(PathName, CFile::modeCreate | CFile::modeWrite);
F.Write(Text, Text.GetLength() + 1);
F.Close();
}
void CDlg1::OnRichedit32790()//打开文件
{
C目录比对Dlg* pDlg = (C目录比对Dlg*)theApp.m_pMainWnd;
CFileDialog FD(TRUE);
FD.m_ofn.lpstrInitialDir = (CString)pDlg->Path + L"\\比对数据";//指定初始目录
FD.m_ofn.lpstrFilter = _T("TXT文件\0*.txt\0\0");//指定过滤器
if (FD.DoModal() != IDOK)return;
CString PathName = FD.GetPathName();
CStringA Text;
CFile F(PathName, CFile::modeRead);
UINT len = (UINT)F.GetLength();
F.Read(Text.GetBufferSetLength(len), len);
F.Close();
richedit.SetWindowText((CString)Text);
Text.ReleaseBuffer();
SetFormat();
}
void CDlg1::SetFormat()//为多格式编辑控件文本指定字体格式
{
richedit.SetSel(0, -1);
CHARFORMAT2 cf;
cf.cbSize = sizeof(CHARFORMAT2);
cf.dwMask = CFM_FACE | CFM_SIZE | CFM_COLOR | CFM_WEIGHT | CFM_CHARSET;
wcsncpy_s(cf.szFaceName, LF_FACESIZE, _T("微软雅黑"), LF_FACESIZE);//设置字体名称
cf.yHeight = 10 * 20;//设置字体大小为12点
cf.crTextColor = RGB(123, 36, 6);//设置字体颜色
cf.wWeight = 400;//400为正常字体
cf.dwEffects = 0;//字符效果设置为0
cf.bCharSet = GB2312_CHARSET;//设置中文字符集
richedit.SetWordCharFormat(cf);//设置当前字符格式
wcsncpy_s(cf.szFaceName, LF_FACESIZE, _T("Cambria"), LF_FACESIZE);//设置字体名称
cf.bCharSet = ANSI_CHARSET;
richedit.SetWordCharFormat(cf);//设置当前字符格式
richedit.SetSel(0, 0);
}
void CDlg1::OnSize(UINT nType, int cx, int cy)
{
CDialogEx::OnSize(nType, cx, cy);
CRect rect;
GetClientRect(rect);
rect.DeflateRect(5, 5, 5, 5);
if (richedit.GetSafeHwnd())
richedit.MoveWindow(rect);
}
Dlg2.h
#pragma once
#include "afxcmn.h"
#include "MyRichEdit.h"
// CDlg2 对话框
class CDlg2 : public CDialogEx
{
DECLARE_DYNAMIC(CDlg2)
public:
CDlg2(CWnd* pParent = NULL); // 标准构造函数
virtual ~CDlg2();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG2 };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
BOOL B = TRUE;
CString Info;
virtual BOOL OnInitDialog();
CMyRichEdit richedit;
afx_msg void OnPaint();
afx_msg void OnRichedit32783();//全选
afx_msg void OnRichedit32784();//复制
afx_msg void OnRichedit32785();//粘贴
afx_msg void OnRichedit32786();//剪切
afx_msg void OnRichedit32787();//撤销
afx_msg void OnRichedit32788();//重做
afx_msg void OnRichedit32789();//保存到文件
afx_msg void OnRichedit32790();//打开文件
void SetFormat();
afx_msg void OnSize(UINT nType, int cx, int cy);
};
Dlg2.cpp
// Dlg2.cpp : 实现文件
//
#include "stdafx.h"
#include "目录比对.h"
#include "Dlg2.h"
#include "afxdialogex.h"
#include "目录比对Dlg.h"
IMPLEMENT_DYNAMIC(CDlg2, CDialogEx)
CDlg2::CDlg2(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_DIALOG2, pParent)
{
}
CDlg2::~CDlg2()
{
}
void CDlg2::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_RICHEDIT22, richedit);
}
BEGIN_MESSAGE_MAP(CDlg2, CDialogEx)
ON_WM_ERASEBKGND()
ON_WM_PAINT()
ON_COMMAND(ID_RICHEDIT_32783, &CDlg2::OnRichedit32783)
ON_COMMAND(ID_RICHEDIT_32784, &CDlg2::OnRichedit32784)
ON_COMMAND(ID_RICHEDIT_32785, &CDlg2::OnRichedit32785)
ON_COMMAND(ID_RICHEDIT_32786, &CDlg2::OnRichedit32786)
ON_COMMAND(ID_RICHEDIT_32787, &CDlg2::OnRichedit32787)
ON_COMMAND(ID_RICHEDIT_32788, &CDlg2::OnRichedit32788)
ON_COMMAND(ID_RICHEDIT_32789, &CDlg2::OnRichedit32789)
ON_COMMAND(ID_RICHEDIT_32790, &CDlg2::OnRichedit32790)
ON_WM_SIZE()
END_MESSAGE_MAP()
BOOL CDlg2::OnEraseBkgnd(CDC* pDC)
{
CRect rect;
GetClientRect(rect);
pDC->FillSolidRect(rect, RGB(50, 50, 50));
return TRUE;
// return CDialogEx::OnEraseBkgnd(pDC);
}
BOOL CDlg2::OnInitDialog()
{
CDialogEx::OnInitDialog();
CRect rectC(0, 0, 780, 600);//设置客户区大小,宽780像素,高600像素
DWORD style = GetExStyle();//获取对话框扩展样式
if (style & WS_EX_CLIENTEDGE)//如果对话框包含WS_EX_CLIENTEDGE样式,CalcWindowRect函数参数2使用CWnd::adjustOutside
{
CalcWindowRect(rectC, CWnd::adjustOutside);//计算带边框的对话框窗口大小。CalcWindowRect函数为CWnd类函数
}
else//如果对话框不包含WS_EX_CLIENTEDGE样式,CalcWindowRect函数参数2使用CWnd::adjustBorder
{
CalcWindowRect(rectC, CWnd::adjustBorder);//计算带边框的对话框窗口大小
}
MoveWindow(&rectC);//设置对话框的大小
CenterWindow();//居中对话框
richedit.SetBackgroundColor(FALSE, RGB(255, 193, 132));
CRect rect;
GetClientRect(rect);
rect.DeflateRect(5, 5, 5, 5);
richedit.MoveWindow(rect);
richedit.SetWindowText(Info);
SetFormat();
B = TRUE;
return TRUE;
}
void CDlg2::OnPaint()
{
CPaintDC dc(this);
if (B)
{
B = FALSE;
richedit.SetSel(0, 0);
}
}
void CDlg2::OnRichedit32783()//全选
{
richedit.SetSel(0, -1);
}
void CDlg2::OnRichedit32784()//复制
{
richedit.Copy();
}
void CDlg2::OnRichedit32785()//粘贴
{
richedit.Paste();
}
void CDlg2::OnRichedit32786()//剪切
{
richedit.Cut();
}
void CDlg2::OnRichedit32787()//撤销
{
richedit.Undo();
}
void CDlg2::OnRichedit32788()//重做
{
richedit.Redo();
}
void CDlg2::OnRichedit32789()//保存到文件
{
C目录比对Dlg* pDlg = (C目录比对Dlg*)theApp.m_pMainWnd;
CStringA Text = (CStringA)richedit.GetSelText();
CFileDialog FD(FALSE, L"txt", NULL, OFN_FILEMUSTEXIST, NULL);
FD.m_ofn.lpstrInitialDir = (CString)pDlg->Path + L"\\比对数据";//指定初始目录
FD.m_ofn.lpstrFilter = _T("TXT文件\0*.txt\0\0");//指定过滤器
if (FD.DoModal() != IDOK)return;
CString PathName = FD.GetPathName();
CFile F(PathName, CFile::modeCreate | CFile::modeWrite);
F.Write(Text, Text.GetLength() + 1);
F.Close();
}
void CDlg2::OnRichedit32790()//打开文件
{
C目录比对Dlg* pDlg = (C目录比对Dlg*)theApp.m_pMainWnd;
CFileDialog FD(TRUE);
FD.m_ofn.lpstrInitialDir = (CString)pDlg->Path + L"\\比对数据";//指定初始目录
FD.m_ofn.lpstrFilter = _T("TXT文件\0*.txt\0\0");//指定过滤器
if (FD.DoModal() != IDOK)return;
CString PathName = FD.GetPathName();
CStringA Text;
CFile F(PathName, CFile::modeRead);
UINT len = (UINT)F.GetLength();
F.Read(Text.GetBufferSetLength(len), len);
F.Close();
richedit.SetWindowText((CString)Text);
Text.ReleaseBuffer();
SetFormat();
}
void CDlg2::SetFormat()//为多格式编辑控件文本指定字体格式
{
richedit.SetSel(0, -1);
CHARFORMAT2 cf;
cf.cbSize = sizeof(CHARFORMAT2);
cf.dwMask = CFM_FACE | CFM_SIZE | CFM_COLOR | CFM_WEIGHT | CFM_CHARSET;
wcsncpy_s(cf.szFaceName, LF_FACESIZE, _T("微软雅黑"), LF_FACESIZE);//设置字体名称
cf.yHeight = 10 * 20;//设置字体大小为12点
cf.crTextColor = RGB(123, 36, 6);//设置字体颜色
cf.wWeight = 400;//400为正常字体
cf.dwEffects = 0;//字符效果设置为0
cf.bCharSet = GB2312_CHARSET;//设置中文字符集
richedit.SetWordCharFormat(cf);//设置当前字符格式
wcsncpy_s(cf.szFaceName, LF_FACESIZE, _T("Cambria"), LF_FACESIZE);//设置字体名称
cf.bCharSet = ANSI_CHARSET;
richedit.SetWordCharFormat(cf);//设置当前字符格式
richedit.SetSel(0, 0);
}
void CDlg2::OnSize(UINT nType, int cx, int cy)
{
CDialogEx::OnSize(nType, cx, cy);
CRect rect;
GetClientRect(rect);
rect.DeflateRect(5, 5, 5, 5);
if (richedit.GetSafeHwnd())
richedit.MoveWindow(rect);
}
MyButton.h
#pragma once
// CMyButton
class CMyButton : public CButton
{
DECLARE_DYNAMIC(CMyButton)
public:
CMyButton();
virtual ~CMyButton();
protected:
DECLARE_MESSAGE_MAP()
public:
CFont font1;
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
};
MyButton.cpp
// MyButton.cpp : 实现文件
//
#include "stdafx.h"
#include "目录比对.h"
#include "MyButton.h"
// CMyButton
IMPLEMENT_DYNAMIC(CMyButton, CButton)
CMyButton::CMyButton()
{
font1.CreatePointFont(130, L"微软雅黑");
}
CMyButton::~CMyButton()
{
}
BEGIN_MESSAGE_MAP(CMyButton, CButton)
END_MESSAGE_MAP()
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC dc; CDC comdc;
dc.Attach(lpDrawItemStruct->hDC);
if (lpDrawItemStruct->CtlID == IDC_BUTTON1 || lpDrawItemStruct->CtlID == IDC_BUTTON2)//绘制按钮
{
CRect rect(lpDrawItemStruct->rcItem);
dc.FillSolidRect(&rect, RGB(70, 50, 50));
CRgn rgn; rgn.CreateRoundRectRgn(rect.left, rect.top, rect.right, rect.bottom, 6, 6);
dc.FillRgn(&rgn, &CBrush(RGB(150, 150, 150)));
CRect r1; r1.CopyRect(rect); r1.DeflateRect(2, 2);
CRgn rgn1; rgn1.CreateRoundRectRgn(r1.left, r1.top, r1.right, r1.bottom, 4, 4);
CRgn rgnA; rgnA.CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom);
rgnA.CombineRgn(&rgn, &rgn1, RGN_DIFF);
dc.FillRgn(&rgnA, &CBrush(RGB(0, 0, 0)));
dc.SelectObject(&font1); dc.SetTextColor(RGB(0, 0, 0)); dc.SetBkColor(RGB(150, 150, 150));
CString str; GetWindowText(str);
dc.DrawText(str, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
dc.Detach();
}
MyRichEdit.h
#pragma once
// CMyRichEdit
class CMyRichEdit : public CRichEditCtrl
{
DECLARE_DYNAMIC(CMyRichEdit)
public:
CMyRichEdit();
virtual ~CMyRichEdit();
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
};
MyRichEdit.cpp
// MyRichEdit.cpp : 实现文件
//
#include "stdafx.h"
#include "目录比对.h"
#include "MyRichEdit.h"
// CMyRichEdit
IMPLEMENT_DYNAMIC(CMyRichEdit, CRichEditCtrl)
CMyRichEdit::CMyRichEdit()
{
}
CMyRichEdit::~CMyRichEdit()
{
}
BEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl)
ON_WM_RBUTTONDOWN()
END_MESSAGE_MAP()
void CMyRichEdit::OnRButtonDown(UINT nFlags, CPoint point)
{
if (GetDlgCtrlID() == IDC_RICHEDIT21 )
{
CMenu menu;
menu.LoadMenu(IDR_MENU1);
CMenu* pmenu = menu.GetSubMenu(2);
ClientToScreen(&point);//需将point转换为屏幕坐标
pmenu->TrackPopupMenu(TPM_LEFTBUTTON | TPM_LEFTALIGN | TPM_TOPALIGN, point.x, point.y, GetParent());
}
if (GetDlgCtrlID() == IDC_RICHEDIT22)
{
CMenu menu;
menu.LoadMenu(IDR_MENU1);
CMenu* pmenu = menu.GetSubMenu(3);
ClientToScreen(&point);//需将point转换为屏幕坐标
pmenu->TrackPopupMenu(TPM_LEFTBUTTON | TPM_LEFTALIGN | TPM_TOPALIGN, point.x, point.y, GetParent());
}
CRichEditCtrl::OnRButtonDown(nFlags, point);
}
MyTree.h
#pragma once
// CMyTree
class CMyTree : public CTreeCtrl
{
DECLARE_DYNAMIC(CMyTree)
public:
CMyTree();
virtual ~CMyTree();
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
};
MyTree.cpp
// MyTree.cpp : 实现文件
//
#include "stdafx.h"
#include "目录比对.h"
#include "MyTree.h"
#include "目录比对Dlg.h"
// CMyTree
IMPLEMENT_DYNAMIC(CMyTree, CTreeCtrl)
CMyTree::CMyTree()
{
}
CMyTree::~CMyTree()
{
}
BEGIN_MESSAGE_MAP(CMyTree, CTreeCtrl)
ON_WM_RBUTTONDOWN()
END_MESSAGE_MAP()
void CMyTree::OnRButtonDown(UINT nFlags, CPoint point)
{
C目录比对Dlg* pDlg = (C目录比对Dlg*)theApp.m_pMainWnd;
if (GetDlgCtrlID() == IDC_TREE1 && pDlg->hCheckThread == NULL)
{
CMenu menu; menu.LoadMenu(IDR_MENU1);
CMenu* p = menu.GetSubMenu(0);
if (pDlg->hLoadDiskThread1 || pDlg->hLoadFileThread1)
{
p->EnableMenuItem(0, MF_BYPOSITION | MF_DISABLED);
p->EnableMenuItem(1, MF_BYPOSITION | MF_DISABLED);
p->EnableMenuItem(2, MF_BYPOSITION | MF_DISABLED);
p->EnableMenuItem(3, MF_BYPOSITION | MF_DISABLED);
p->EnableMenuItem(5, MF_BYPOSITION | MF_DISABLED);
}
if (pDlg->tree1.GetSelectedItem() == NULL)
{
p->EnableMenuItem(5, MF_BYPOSITION | MF_DISABLED);
}
ClientToScreen(&point);
p->TrackPopupMenu(TPM_LEFTBUTTON | TPM_LEFTALIGN | TPM_TOPALIGN, point.x + 20, point.y, GetParent());//
menu.DestroyMenu();
}
if (GetDlgCtrlID() == IDC_TREE2 && pDlg->hCheckThread == NULL)
{
CMenu menu; menu.LoadMenu(IDR_MENU1);
CMenu* p = menu.GetSubMenu(1);
if (pDlg->hLoadDiskThread2 || pDlg->hLoadFileThread2)
{
p->EnableMenuItem(0, MF_BYPOSITION | MF_DISABLED);
p->EnableMenuItem(1, MF_BYPOSITION | MF_DISABLED);
p->EnableMenuItem(2, MF_BYPOSITION | MF_DISABLED);
p->EnableMenuItem(3, MF_BYPOSITION | MF_DISABLED);
p->EnableMenuItem(5, MF_BYPOSITION | MF_DISABLED);
}
if (pDlg->tree2.GetSelectedItem() == NULL)
{
p->EnableMenuItem(5, MF_BYPOSITION | MF_DISABLED);
}
ClientToScreen(&point);
p->TrackPopupMenu(TPM_LEFTBUTTON | TPM_LEFTALIGN | TPM_TOPALIGN, point.x + 20, point.y, GetParent());//
menu.DestroyMenu();
}
CTreeCtrl::OnRButtonDown(nFlags, point);
}