已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
向导生成的所有控件变量:
<code class="lang-cpp">void CFolderMonitorDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_BTN_START, m_startbutton);
    DDX_Control(pDX, IDC_EDIT1, m_folderedit);
    DDX_Control(pDX, IDC_MFCSHELLTREE1, m_foldertree);
    DDX_Control(pDX, IDC_LIST1, m_resultlist);
    DDX_Control(pDX, IDC_CHECK1, m_flag_filename);
    DDX_Control(pDX, IDC_CHECK2, m_flag_dirname);
    DDX_Control(pDX, IDC_CHECK3, m_flag_attr);
    DDX_Control(pDX, IDC_CHECK4, m_flag_size);
    DDX_Control(pDX, IDC_CHECK5, m_flag_lastwrite);
    DDX_Control(pDX, IDC_CHECK6, m_flag_lastaccess);
    DDX_Control(pDX, IDC_CHECK7, m_flag_creation);
    DDX_Control(pDX, IDC_CHECK8, m_flag_security);
}</code>

其它变量:
<code class="lang-cpp">CString m_getpath;
CString m_getopr;
CString m_gettime;
CWinThread *m_monthread;
HANDLE m_dirhandle;
CMutex m_mutex;</code>

消息映射:
<code class="lang-cpp">#define WM_TRHEADMSG (WM_USER + 8)
BEGIN_MESSAGE_MAP(CFolderMonitorDlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_NOTIFY(TVN_SELCHANGED, IDC_MFCSHELLTREE1, &CFolderMonitorDlg::OnTvnSelchangedMfcshelltree1)
    ON_BN_CLICKED(IDC_BTN_START, &CFolderMonitorDlg::OnBnClickedBtnStart)
    ON_MESSAGE(WM_TRHEADMSG, &CFolderMonitorDlg::ThreadMsg)
    ON_WM_DESTROY()
    ON_COMMAND_RANGE(IDC_CHECK1, IDC_CHECK8, &CFolderMonitorDlg::OnCheckBox)
END_MESSAGE_MAP()</code>

核心代码(FolderMonitorDlg.h):
<code class="lang-cpp">//////////////////////////////////////////////////////////////////////////////////////
 
//BOOL CFolderMonitorDlg::OnInitDialog()
//{
//  ResetComponents();
//}
void CFolderMonitorDlg::ResetComponents(void)
{
    while (m_resultlist.DeleteColumn(0)); // 删除原有表列
    m_resultlist.InsertColumn(0, _T("路径"), 0, 200); // 添加表列
    m_resultlist.InsertColumn(1, _T("操作"), 0, 80);
    m_resultlist.InsertColumn(2, _T("时间"), 0, 80);
 
    m_resultlist.ModifyStyle(LVS_TYPEMASK, LVS_REPORT); // 设置为列表式
    DWORD exstyle = m_resultlist.GetExtendedStyle(); // 设置为全行选择、有格线
    m_resultlist.SetExtendedStyle(exstyle|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
 
    m_flag_filename.SetCheck(true); // 设置默认监控项目
    m_flag_creation.SetCheck(true);
    m_flag_lastwrite.SetCheck(true);
    OnCheckBox(IDC_CHECK1); // 更新m_monflag
}
 
void CFolderMonitorDlg::OnTvnSelchangedMfcshelltree1(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMTREEVIEW pNMTreeView = reinterpret_cast<lpnmtreeview>(pNMHDR);
    // TODO: 在此添加控件通知处理程序代码
    *pResult = 0;
    CString path;
    m_foldertree.GetItemPath(path);
    m_folderedit.SetWindowText(path); // 根据文件夹树所选项目,更新文本框
}
 
UINT MonitorThread(LPVOID pvoid);
 
void CFolderMonitorDlg::OnBnClickedBtnStart()
{
    // TODO: 在此添加控件通知处理程序代码
    CString btntext;
    m_startbutton.GetWindowText(btntext);
    if (btntext == _T("开始"))
    {
        CString path;
        m_folderedit.GetWindowText(path); // 获取文本框中的字符串
 
        m_dirhandle = ::CreateFile( // 打开所选目录!
            path, // 目录名
            FILE_LIST_DIRECTORY, // 以列出目录权限打开
            FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, // 允许其它程序读写删除
            NULL, // 没有安全选项
            OPEN_EXISTING, // 存在时打开
            FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, // 备份存取异步存取
            NULL); // 没有文件模板
        if (m_dirhandle == INVALID_HANDLE_VALUE) // 如果打开失败则退出
            return;
 
        m_monthread = new CWinThread(MonitorThread, this); // 新建并启动工作线程
        m_monthread->CreateThread();
 
        m_startbutton.SetWindowText(_T("停止"));
    }
    else if (btntext == _T("停止"))
    {
        OnDestroy(); // 停止工作线程并清理资源
        m_startbutton.SetWindowText(_T("清除"));
    }
    else if (btntext == _T("清除"))
    {
        m_resultlist.DeleteAllItems(); // 清空列表框
        m_startbutton.SetWindowText(_T("开始"));
    }
    else
    {
        AfxMessageBox(_T("出现了不该出现的情况"));
        m_startbutton.SetWindowText(_T("停止"));
    }
}
 
void CFolderMonitorDlg::OnDestroy()
{
    if (m_monthread != NULL) // 如果线程存在,则终止线程
    {
        if (m_monthread->m_hThread != INVALID_HANDLE_VALUE)
            m_monthread->SuspendThread();
        delete m_monthread;
        m_monthread = NULL;
    }
    if (m_dirhandle != INVALID_HANDLE_VALUE) // 如果目录已打开,则关闭目录
    {
        CloseHandle(m_dirhandle);
        m_dirhandle = INVALID_HANDLE_VALUE;
    }
}
 
//BEGIN_MESSAGE_MAP(CFolderMonitorDlg, CDialogEx)
//  ON_COMMAND_RANGE(IDC_CHECK1, IDC_CHECK8, &CFolderMonitorDlg::OnCheckBox)
//END_MESSAGE_MAP()
void CFolderMonitorDlg::OnCheckBox(UINT nID)
{
    m_mutex.Lock(); // 赋值时可能会被工作线程异步读取,所以要上锁
    m_monflag = 0;
    if (m_flag_attr.GetCheck()) m_monflag |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
    if (m_flag_creation.GetCheck()) m_monflag |= FILE_NOTIFY_CHANGE_CREATION;
    if (m_flag_dirname.GetCheck()) m_monflag |= FILE_NOTIFY_CHANGE_DIR_NAME;
    if (m_flag_filename.GetCheck()) m_monflag |= FILE_NOTIFY_CHANGE_FILE_NAME;
    if (m_flag_lastaccess.GetCheck()) m_monflag |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
    if (m_flag_lastwrite.GetCheck()) m_monflag |= FILE_NOTIFY_CHANGE_LAST_WRITE;
    if (m_flag_security.GetCheck()) m_monflag |= FILE_NOTIFY_CHANGE_SECURITY;
    if (m_flag_size.GetCheck()) m_monflag |= FILE_NOTIFY_CHANGE_SIZE;
    m_mutex.Unlock();
}
 
UINT MonitorThread(LPVOID pvoid)
{
    CFolderMonitorDlg *pWnd = (CFolderMonitorDlg*)pvoid;
 
    char notify[65536]; // 储存FILE_NOTIFY_INFORMATION链表的缓冲区
    DWORD dwBytes; // 返回字节数
    FILE_NOTIFY_INFORMATION *pnotify; // FILE_NOTIFY_INFORMATION指针
 
    if (pWnd->m_dirhandle == INVALID_HANDLE_VALUE) // 如果文件夹没打开则直接结束
        return 1;
 
    while(true) // 监控循环
    {
        memset(notify, 0, sizeof(notify)); // 清零缓冲区
        pnotify = (FILE_NOTIFY_INFORMATION*)notify; // 指向缓冲区开头的链表第一项
 
        pWnd->m_mutex.Lock(); // 因为可能会被主线程异步赋值,所以要进行锁定
        DWORD monflag = pWnd->m_monflag; // 获取flag(见OnCheckBox)
        pWnd->m_mutex.Unlock();
 
        if (::ReadDirectoryChangesW( 
            pWnd->m_dirhandle, // 目录句柄(见OnBnClickedBtnStart)
            ¬ify, sizeof(notify), // 缓冲区及大小
            TRUE, // 是否监控子项目
            monflag, // 监控的内容(见OnCheckBox)
            &dwBytes, // 返回字节数
            NULL, NULL)) // 异步调用相关,这里是同步调用,因此全填NULL
        {
            if (!dwBytes) // 如果缓冲区溢出
            {
                pWnd->m_getpath = _T("[缓冲区溢出]");
                pWnd->m_getopr = _T("未知");
 
                SYSTEMTIME st;
                GetLocalTime(&st);
                pWnd->m_gettime = CTime(st).Format("%H:%M:%S"); // 获取系统时间
 
                pWnd->SendMessage(WM_TRHEADMSG, 0, 0); // 通知主线程添加列表项
            }
            else
                while(true) // 链表迭代循环
                {
                    LPWSTR wbuf = pWnd->m_getpath.GetBufferSetLength(pnotify->FileNameLength / 2);
                    memcpy(wbuf, pnotify->FileName, pnotify->FileNameLength);
                    pWnd->m_getpath.ReleaseBuffer(pnotify->FileNameLength / 2); // 获取文件名
 
                    pWnd->m_getopr = // 获取操作类型
                        pnotify->Action == FILE_ACTION_ADDED ? _T("新建") :
                        pnotify->Action == FILE_ACTION_MODIFIED ? _T("更改") :
                        pnotify->Action == FILE_ACTION_REMOVED ? _T("删除") :
                        pnotify->Action == FILE_ACTION_RENAMED_OLD_NAME ? _T("重命名") :
                        pnotify->Action == FILE_ACTION_RENAMED_NEW_NAME ? _T("新名称") :
                        _T("未知");
 
                    SYSTEMTIME st;
                    GetLocalTime(&st);
                    pWnd->m_gettime = CTime(st).Format("%H:%M:%S"); // 获取系统时间
 
                    pWnd->SendMessage(WM_TRHEADMSG, 0, 0); // 通知主线程添加列表项
 
                    if (pnotify->NextEntryOffset) // 如果返回了另一个项目(通常是新文件名)
                    {
                        pnotify = (FILE_NOTIFY_INFORMATION *)
                            ((char*)pnotify + pnotify->NextEntryOffset); // 迭代链表下一项
                        continue; // 继续
                    }
                    break; // 退出
                }
        }
    }
}
 
//#define WM_THREADMSG (WM_USER + 8)
//BEGIN_MESSAGE_MAP(CFolderMonitorDlg, CDialogEx)
//  ON_MESSAGE(WM_TRHEADMSG, &CFolderMonitorDlg::ThreadMsg)
//END_MESSAGE_MAP()
LRESULT CFolderMonitorDlg::ThreadMsg(WPARAM wParam, LPARAM lParam)
{
    // 工作线程调用此消息以插入列表项
    m_resultlist.InsertItem(0, m_getpath); // 根据返回的字符串插入表项,设置其它列的值
    m_resultlist.SetItemText(0, 1, m_getopr);
    m_resultlist.SetItemText(0, 2, m_gettime);
    return TRUE;
}</lpnmtreeview></code>

(完)
文号 / 779026

千古风流
名片发私信
学术分 4
总主题 466 帖总回复 2942 楼拥有证书:进士 学者 笔友
注册于 2009-05-30 21:22最后登录 2019-01-31 17:16
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步

个人简介

暂未填写
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

插入资源
全部
图片
视频
音频
附件
全部
未使用
已使用
正在上传
空空如也~
上传中..{{f.progress}}%
处理中..
上传失败,点击重试
等待中...
{{f.name}}
空空如也~
(视频){{r.oname}}
{{selectedResourcesId.indexOf(r.rid) + 1}}
处理中..
处理失败
插入表情
我的表情
共享表情
Emoji
上传
注意事项
最大尺寸100px,超过会被压缩。为保证效果,建议上传前自行处理。
建议上传自己DIY的表情,严禁上传侵权内容。
点击重试等待上传{{s.progress}}%处理中...已上传,正在处理中
空空如也~
处理中...
处理失败
加载中...
草稿箱
加载中...
此处只插入正文,如果要使用草稿中的其余内容,请点击继续创作。
{{fromNow(d.toc)}}
{{getDraftInfo(d)}}
标题:{{d.t}}
内容:{{d.c}}
继续创作
删除插入插入
插入公式
评论控制
加载中...
文号:{{pid}}
加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}
ID: {{user.uid}}