文件MD5获取工具开发记录(一)

今天开始,要记录一个小白的VC学习记录。

首先VC并不是一种语言,只是说在VisualStudio上用C和C++等进行开发。

这里先从一个小工具开始。记录他的开发点滴。

 

下面开始:

 

 

  首先创建一个MFC的工程,起名为:FilesMD5Builder

首先对对话框类重载 PreTranslateMessage 消息,代码如下。

BOOL CFilesMD5BuilderDlg::PreTranslateMessage(MSG* pMsg)
{
    // TODO: 在此添加专用代码和/或调用基类
    if (pMsg->message == WM_KEYDOWN)//当有按键消息的时候,进行筛选.
    {
        if (pMsg->wParam == VK_ESCAPE)//当消息内容为ESC时,不处理,直接return.
            return TRUE;
    }
    return CDialog::PreTranslateMessage(pMsg);
}

功能在上边有说明。同时,还要处理 onok。这样使得回车键也不会让dlg消失。

void CFilesMD5BuilderDlg::OnOK()
{
    // TODO: 在此添加专用代码和/或调用基类
    //
    //CDialog::OnOK();
}

空函数即可。

 

之前忘了说,这个软件的目的。这里补一下:

  软件需要对一些文件的MD5值进行计算,并生成文件。记录这些文件的文件MD5值,以及他们的相对路径,以便于更新程序读取。

接下来继续写。

 

  添加 ListCtrl控件,为listctrl控件绑定变量 m_list。添加测试按钮。过程不用复述了,基本操作。然后添加一个初始化参数。在Dlg.h里。

private:
    void Init_list();

用他来初始化listctrl控件。在这之前,首先对控件的属性做修改。更改view为  report。还有 Owner Data改为true。这里用自己处理数据的方式,以便于以后如果文件列表量大造成的卡顿。

void CFilesMD5BuilderDlg::Init_list()
{
    ListView_SetExtendedListViewStyle(m_list.m_hWnd, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES);//网格线,check
    m_list.ModifyStyle(0, LVS_SINGLESEL);//一直选中某行且只能单行选中
    m_list.InsertColumn(0, _T("文件名"), LVCFMT_LEFT, 150);
    m_list.InsertColumn(1, _T("MD5"), LVCFMT_LEFT, 250);
    m_list.InsertColumn(2, _T("相对路径"), LVCFMT_LEFT, 200);
}

 

 

关于virtual listctrl的资料:http://blog.sina.com.cn/s/blog_4ad042e50102eaml.html

 

这里我选择继承CListCtrl类。关键点就是要对几个消息做处理。

BEGIN_MESSAGE_MAP(MFC_VirtualList, CListCtrl)
    //{{AFX_MSG_MAP(CMyVirtualList)
    ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispInfo)
    ON_NOTIFY_REFLECT(LVN_KEYDOWN, OnKeydown)
    ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
    ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomdraw)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

这里OnGetdispInfo是处理当数据刷新,我们要把哪条数据放在哪列。以及check的状态变化

OnKeydow是为了使得list可以通过空格来选中check

鼠标点击也是如此。具体代码如下:

void MFC_VirtualList::OnGetdispInfo(NMHDR* pNMHDR, LRESULT* pResult)
{
    LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;

    LV_ITEM* pItem = &(pDispInfo)->item;
    COLORREF TextBkColor[2] = { RGB(255,0,0), RGB(0,255,0) };
    int itemid = pItem->iItem;//得到第几行

    //对文字信息做处理
    if (pItem->mask & LVIF_TEXT)
    {
        CString text;
        switch (pItem->iSubItem)
        {
        case 0:
            text = listdata[itemid].Name;
            break;
        case 1:
            text = listdata[itemid].MD5;
            break;
        case 2:
            text = "." + listdata[itemid].RelativePath;
            break;
        }
        lstrcpyn(pItem->pszText, text, pItem->cchTextMax);
    }

    pItem->mask |= LVIF_STATE;
    pItem->stateMask = LVIS_STATEIMAGEMASK;
    if (listdata[itemid].ischeck)
    {
        //Turn check box on..
        pItem->state = INDEXTOSTATEIMAGEMASK(2);
    }
    else
    {
        //Turn check box off
        pItem->state = INDEXTOSTATEIMAGEMASK(1);
    }

    *pResult = 0;
}
void MFC_VirtualList::OnKeydown(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMLVKEYDOWN pLVKeyDow = reinterpret_cast<LPNMLVKEYDOWN>(pNMHDR);
    if (pLVKeyDow->wVKey == VK_SPACE)
    {
        if (GetSelectionMark() != -1)
        {
            ChangeSelectionStatus(GetSelectionMark());
        }
    }
    *pResult = 0;
}
void MFC_VirtualList::OnClick(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
    LVHITTESTINFO hitinfo;
    //Copy click point
    hitinfo.pt = pNMItemActivate->ptAction;

    //Make the hit test...
    int nCurrentItemIndex = HitTest(&hitinfo);

    if (nCurrentItemIndex != -1)
    {
        if (hitinfo.flags == LVHT_ONITEMSTATEICON)//点击check的时候的处理
        {
            ChangeSelectionStatus(nCurrentItemIndex);
        }
    }
    *pResult = 0;
}

 

至于OnCustomdraw 这个,我目前其实也没什么用,他可以对你显示的数据发生变化时或者你对他的颜色进行相关设置的时候起到作用。只是我进行了一下测试而已。

 

接下来,由于这个list控件的数据是自己去处理的。这里需要根据自己的情况来自己确认数据。下边是我的数据结构体:

//list中数据的类型.
struct LISTDATA 
{
    BOOL ischeck;//是否选中
    CString Name;//名字    
    CString MD5;//MD5
    CString RelativePath;//相对路径.
    CString Extension;//拓展名
};

 

这里要最终存储的是文件的名字,MD5,相对路径。拓展名只是为了导出某些类型的拓展名的文件的MD5。

 

protected:
    vector<LISTDATA> listdata;//存放数据

 

这是存放list最终要显示数据的一个自定义类型的vector。至于为什么选择vector,这里参考下如下资料:https://www.cnblogs.com/zhaodun/p/6510161.html

接下来测试下显示:

    vector<LISTDATA> data;//存放数据
    LISTDATA item;
    item.ischeck = 1;
    item.MD5 = "DDDDDDDDDDDDDD";
    item.RelativePath = "C:\\";
    item.Extension = ".exe";

    for (int i = m_list.GetMaxItemIndex(); i < m_list.GetMaxItemIndex() + 5000; i++)
    {
        item.Name.Format("这个是 %d 个文件", i + 1);
        data.push_back(item);
    }
    m_list.AddItem(data);

速度很快。基本的界面部分搞定。接下来遍历指定文件夹或者默认目录下的所有文件的遍历以及MD5的获取。这些问题在下一篇中进行记录。

 

posted @ 2020-04-12 09:56  尼古拉斯王大拿  阅读(425)  评论(0)    收藏  举报