欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于vs2017,MFC的MD5码生成小工具

程序员文章站 2022-06-10 20:54:14
...

因为工作需要md5码校验,之前一直依赖网上的工具,或者linux系统自带的md5sum插件。

耐不住好奇,巴拉了一下md5sum的源码,然后整合了一个mfc小工具

主要代码,如下:

MD5SUMDlg.h


// MD5SUMDlg.h: 头文件
//

#pragma once


// CMD5SUMDlg 对话框
class CMD5SUMDlg : public CDialogEx
{
// 构造
public:
	CMD5SUMDlg(CWnd* pParent = nullptr);	// 标准构造函数

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_MD5SUM_DIALOG };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()

	CEdit m_editePath;
	CButton m_btnOpen;
	CButton m_btnDo;
	CEdit m_editResult;
	CString m_strDirPath;

	std::vector<CString> m_vctFiles;
	std::vector<CString> m_vctMd5Codes;

protected:
	void GetFileFromDir(CString csDirPath);
	void Init(MD5_CONTEXT *ctx);
	void TransForm(MD5_CONTEXT *ctx, unsigned char *data);
	void Write(MD5_CONTEXT *hd, unsigned char *inbuf, size_t inlen);
	void Final(MD5_CONTEXT *hd);
	void CheckFileOrDirector(const CString & path);

public:
	afx_msg void OnBnClickedBtnOpen();
	afx_msg void OnBnClickedBtnDo();
	afx_msg void OnBnClickedBtnOpenfiles();
	afx_msg void OnBnClickedBtnClearResult();

	afx_msg void OnDropFiles(HDROP hDropInfo);
};

MD5SUMDlg.cpp


// MD5SUMDlg.cpp: 实现文件
//

#include "stdafx.h"
#include "MD5SUM.h"
#include "MD5SUMDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

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

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_ABOUTBOX };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CMD5SUMDlg 对话框



CMD5SUMDlg::CMD5SUMDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MD5SUM_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMD5SUMDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EDIT_PATH, m_editePath);
	DDX_Control(pDX, IDC_BTN_OPEN, m_btnOpen);
	DDX_Control(pDX, IDC_BTN_DO, m_btnDo);
	DDX_Control(pDX, IDC_EDIT_RESULT, m_editResult);
}

BEGIN_MESSAGE_MAP(CMD5SUMDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN_OPEN, &CMD5SUMDlg::OnBnClickedBtnOpen)
	ON_BN_CLICKED(IDC_BTN_DO, &CMD5SUMDlg::OnBnClickedBtnDo)
	ON_BN_CLICKED(IDC_BTN_OPENFILES, &CMD5SUMDlg::OnBnClickedBtnOpenfiles)
	ON_BN_CLICKED(IDC_BTN_CLEAR_RESULT, &CMD5SUMDlg::OnBnClickedBtnClearResult)
	ON_WM_DROPFILES()
END_MESSAGE_MAP()


// CMD5SUMDlg 消息处理程序

BOOL CMD5SUMDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CMD5SUMDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CMD5SUMDlg::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 CMD5SUMDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CMD5SUMDlg::OnBnClickedBtnOpen()
{
	BROWSEINFO bi;
	ZeroMemory(&bi, sizeof(BROWSEINFO));
	bi.hwndOwner = m_hWnd;
	bi.ulFlags = BIF_RETURNONLYFSDIRS;
	LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
	BOOL bRet = FALSE;
	TCHAR szFolder[MAX_PATH * 2];
	szFolder[0] = _T('\0');
	if (pidl)
	{
		if (SHGetPathFromIDList(pidl, szFolder))
			bRet = TRUE;
		IMalloc *pMalloc = NULL;
		if (SUCCEEDED(SHGetMalloc(&pMalloc))
			&& pMalloc)
		{
			pMalloc->Free(pidl);
			pMalloc->Release();
		}
	}
	m_strDirPath = szFolder;//选择的文件夹路径
	m_editePath.SetWindowTextW(m_strDirPath);

	GetFileFromDir(m_strDirPath);
}

void CMD5SUMDlg::OnBnClickedBtnOpenfiles()
{
	CFileDialog fileDlg(TRUE, _T("*"), _T("*.*"), OFN_OVERWRITEPROMPT, _T("所有文件(*.*;)|*.*||"), NULL);
	if (fileDlg.DoModal() == IDOK) {
		CString filePath = fileDlg.GetPathName();
		m_editePath.SetWindowTextW(filePath);
		m_vctFiles.clear();
		m_vctFiles.push_back(filePath);
	}
}

void CMD5SUMDlg::GetFileFromDir(CString csDirPath)
{
	CFileFind ff;
	BOOL res = ff.FindFile(csDirPath + _T("/*.*"));

	m_vctFiles.clear();
	while (res) {
		res = ff.FindNextFile();
		if (!ff.IsDirectory()) {
			m_vctFiles.push_back(ff.GetFilePath());
		}
	}

	ff.Close();
}

#include "MD5SUM.h"
void CMD5SUMDlg::OnBnClickedBtnDo()
{
	// TODO: 在此添加控件通知处理程序代码
	for (auto file : m_vctFiles) {
		FILE *fp;
		unsigned char buffer[4096];
		size_t n;
		MD5_CONTEXT ctx;
		int i;

		char szStr[512] = {};
		wcstombs(szStr, file, file.GetLength());//将宽字符转换成多字符  
		const char* pBuf = szStr;

		fp = fopen(pBuf, "rb");
		if (!fp) {
			fprintf(stderr, "can't open `%s': %s\n", pBuf, strerror(errno));
			continue;
		}

		Init(&ctx);
		while ((n = fread(buffer, 1, sizeof buffer, fp)))
			Write(&ctx, buffer, n);
		if (ferror(fp))
		{
			fprintf(stderr, "error reading `%s': %s\n", pBuf, strerror(errno));
			exit(1);
		}
		Final(&ctx);
		fclose(fp);

		CString md5;
		for (i = 0; i < 16; i++)
			md5.AppendFormat(L"%02x", ctx.buf[i]);

		m_editResult.SetSel(-1);
		md5 += L"\r\n";
		file = file + L"    " + md5;
		m_editResult.ReplaceSel(file);
	}
}

void CMD5SUMDlg::Init(MD5_CONTEXT *ctx)
{
	ctx->A = 0x67452301;
	ctx->B = 0xefcdab89;
	ctx->C = 0x98badcfe;
	ctx->D = 0x10325476;

	ctx->nblocks = 0;
	ctx->count = 0;
}

void CMD5SUMDlg::OnBnClickedBtnClearResult()
{
	m_editResult.SetWindowTextW(L"");
	m_editResult.SetFocus();
}

/****************
 * TransForm n*64 bytes
 */
void CMD5SUMDlg::TransForm(MD5_CONTEXT *ctx, unsigned char *data)
{
	u32 correct_words[16];
	u32 A = ctx->A;
	u32 B = ctx->B;
	u32 C = ctx->C;
	u32 D = ctx->D;
	u32 *cwp = correct_words;

#ifdef BIG_ENDIAN_HOST
	{
		int i;
		unsigned char *p2, *p1;
		for (i = 0, p1 = data, p2 = (unsigned char*)correct_words; i < 16; i++, p2 += 4) {
			p2[3] = *p1++;
			p2[2] = *p1++;
			p2[1] = *p1++;
			p2[0] = *p1++;
		}
	}
#else
	memcpy(correct_words, data, 64);
#endif

#define OP(a, b, c, d, s, T) \
  do {                                   \
      a += FF (b, c, d) + (*cwp++) + T;  \
      a = rol(a, s);                     \
      a += b;                            \
  } while (0)


	/* Before we start, one word about the strange constants.
	   They are defined in RFC 1321 as
	   T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
	 */


	 /* Round 1.  */
	OP(A, B, C, D, 7, 0xd76aa478);
	OP(D, A, B, C, 12, 0xe8c7b756);
	OP(C, D, A, B, 17, 0x242070db);
	OP(B, C, D, A, 22, 0xc1bdceee);
	OP(A, B, C, D, 7, 0xf57c0faf);
	OP(D, A, B, C, 12, 0x4787c62a);
	OP(C, D, A, B, 17, 0xa8304613);
	OP(B, C, D, A, 22, 0xfd469501);
	OP(A, B, C, D, 7, 0x698098d8);
	OP(D, A, B, C, 12, 0x8b44f7af);
	OP(C, D, A, B, 17, 0xffff5bb1);
	OP(B, C, D, A, 22, 0x895cd7be);
	OP(A, B, C, D, 7, 0x6b901122);
	OP(D, A, B, C, 12, 0xfd987193);
	OP(C, D, A, B, 17, 0xa679438e);
	OP(B, C, D, A, 22, 0x49b40821);


#undef OP
#define OP(f, a, b, c, d, k, s, T)  \
    do {                                          \
		a += f (b, c, d) + correct_words[k] + T;  \
		a = rol(a, s);						      \
		a += b;                                   \
    } while (0)

	/* Round 2.  */
	OP(FG, A, B, C, D, 1, 5, 0xf61e2562);
	OP(FG, D, A, B, C, 6, 9, 0xc040b340);
	OP(FG, C, D, A, B, 11, 14, 0x265e5a51);
	OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
	OP(FG, A, B, C, D, 5, 5, 0xd62f105d);
	OP(FG, D, A, B, C, 10, 9, 0x02441453);
	OP(FG, C, D, A, B, 15, 14, 0xd8a1e681);
	OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
	OP(FG, A, B, C, D, 9, 5, 0x21e1cde6);
	OP(FG, D, A, B, C, 14, 9, 0xc33707d6);
	OP(FG, C, D, A, B, 3, 14, 0xf4d50d87);
	OP(FG, B, C, D, A, 8, 20, 0x455a14ed);
	OP(FG, A, B, C, D, 13, 5, 0xa9e3e905);
	OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);
	OP(FG, C, D, A, B, 7, 14, 0x676f02d9);
	OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);


	/* Round 3.  */
	OP(FH, A, B, C, D, 5, 4, 0xfffa3942);
	OP(FH, D, A, B, C, 8, 11, 0x8771f681);
	OP(FH, C, D, A, B, 11, 16, 0x6d9d6122);
	OP(FH, B, C, D, A, 14, 23, 0xfde5380c);
	OP(FH, A, B, C, D, 1, 4, 0xa4beea44);
	OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9);
	OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60);
	OP(FH, B, C, D, A, 10, 23, 0xbebfbc70);
	OP(FH, A, B, C, D, 13, 4, 0x289b7ec6);
	OP(FH, D, A, B, C, 0, 11, 0xeaa127fa);
	OP(FH, C, D, A, B, 3, 16, 0xd4ef3085);
	OP(FH, B, C, D, A, 6, 23, 0x04881d05);
	OP(FH, A, B, C, D, 9, 4, 0xd9d4d039);
	OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);
	OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);
	OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);


	/* Round 4.  */
	OP(FI, A, B, C, D, 0, 6, 0xf4292244);
	OP(FI, D, A, B, C, 7, 10, 0x432aff97);
	OP(FI, C, D, A, B, 14, 15, 0xab9423a7);
	OP(FI, B, C, D, A, 5, 21, 0xfc93a039);
	OP(FI, A, B, C, D, 12, 6, 0x655b59c3);
	OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92);
	OP(FI, C, D, A, B, 10, 15, 0xffeff47d);
	OP(FI, B, C, D, A, 1, 21, 0x85845dd1);
	OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f);
	OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
	OP(FI, C, D, A, B, 6, 15, 0xa3014314);
	OP(FI, B, C, D, A, 13, 21, 0x4e0811a1);
	OP(FI, A, B, C, D, 4, 6, 0xf7537e82);
	OP(FI, D, A, B, C, 11, 10, 0xbd3af235);
	OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
	OP(FI, B, C, D, A, 9, 21, 0xeb86d391);


	/* Put checksum in context given as argument.  */
	ctx->A += A;
	ctx->B += B;
	ctx->C += C;
	ctx->D += D;
}

void CMD5SUMDlg::Write(MD5_CONTEXT * hd, unsigned char * inbuf, size_t inlen)
{
	if (hd->count == 64) { /* flush the buffer */
		TransForm(hd, hd->buf);
		hd->count = 0;
		hd->nblocks++;
	}
	if (!inbuf)
		return;
	if (hd->count) {
		for (; inlen && hd->count < 64; inlen--)
			hd->buf[hd->count++] = *inbuf++;
		Write(hd, NULL, 0);
		if (!inlen)
			return;
	}


	while (inlen >= 64) {
		TransForm(hd, inbuf);
		hd->count = 0;
		hd->nblocks++;
		inlen -= 64;
		inbuf += 64;
	}
	for (; inlen && hd->count < 64; inlen--)
		hd->buf[hd->count++] = *inbuf++;
}

void CMD5SUMDlg::Final(MD5_CONTEXT * hd)
{
	u32 t, msb, lsb;
	unsigned char *p;


	Write(hd, NULL, 0); /* flush */;


	t = hd->nblocks;
	/* multiply by 64 to make a byte count */
	lsb = t << 6;
	msb = t >> 26;
	/* add the count */
	t = lsb;
	if ((lsb += hd->count) < t)
		msb++;
	/* multiply by 8 to make a bit count */
	t = lsb;
	lsb <<= 3;
	msb <<= 3;
	msb |= t >> 29;


	if (hd->count < 56) { /* enough room */
		hd->buf[hd->count++] = 0x80; /* pad */
		while (hd->count < 56)
			hd->buf[hd->count++] = 0;  /* pad */
	}
	else { /* need one extra block */
		hd->buf[hd->count++] = 0x80; /* pad character */
		while (hd->count < 64)
			hd->buf[hd->count++] = 0;
		Write(hd, NULL, 0);  /* flush */;
		memset(hd->buf, 0, 56); /* fill next block with zeroes */
	}
	/* append the 64 bit count */
	hd->buf[56] = lsb;
	hd->buf[57] = lsb >> 8;
	hd->buf[58] = lsb >> 16;
	hd->buf[59] = lsb >> 24;
	hd->buf[60] = msb;
	hd->buf[61] = msb >> 8;
	hd->buf[62] = msb >> 16;
	hd->buf[63] = msb >> 24;
	TransForm(hd, hd->buf);


	p = hd->buf;
#ifdef BIG_ENDIAN_HOST
#define X(a) do { *p++ = hd-> a      ; *p++ = hd-> a >> 8;      \
                  *p++ = hd-> a >> 16; *p++ = hd-> a >> 24; } while(0)
#else /* little endian */
#define X(a) do { *(u32*)p = hd-> a ; p += 4; } while(0)
#endif
	X(A);
	X(B);
	X(C);
	X(D);
#undef X
}


void CMD5SUMDlg::OnDropFiles(HDROP hDropInfo)
{
	TCHAR filePath[MAX_PATH] = { 0 };
	CString csPath;
	UINT count = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);//从成功的拖放操作中检索文件的名称。并取代被拖拽文件的数目
    if (count == 1)//如果只拖拽一个文件夹	
	{
		DragQueryFile(hDropInfo, 0, filePath, sizeof(filePath));//获得拖拽的文件名
		csPath = filePath;
		CheckFileOrDirector(csPath);
		m_editePath.SetWindowTextW(csPath);

		UpdateData(FALSE);
		DragFinish(hDropInfo);//拖放成功后,释放内存
		CDialog::OnDropFiles(hDropInfo);
		return;
	}
	else//如果拖拽多个文件夹
	{
		m_vctFiles.clear();
		for (UINT i = 0; i<count; i++) {
			int pathLen = DragQueryFile(hDropInfo, i, filePath, sizeof(filePath));
			CString tmpPath = filePath;
			CheckFileOrDirector(tmpPath);

			csPath = tmpPath + L";";
			//m_vectorFile.push_back(filePath);
			//break;
		}
		m_editePath.SetWindowTextW(csPath);
		UpdateData(FALSE);
		DragFinish(hDropInfo);
	}

	CDialogEx::OnDropFiles(hDropInfo);
}

void CMD5SUMDlg::CheckFileOrDirector(const CString & path)
{
	if (GetFileAttributes(path) != FILE_ATTRIBUTE_DIRECTORY) {
		m_vctFiles.clear();
		m_vctFiles.push_back(path);
	}
	else {
		GetFileFromDir(path);
	}
}

附带所需要的资源文件 MD5SUM.rc

// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#ifndef APSTUDIO_INVOKED
#include "targetver.h"
#endif
#include "afxres.h"
#include "verrsrc.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// 中文(简体,中国) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
    "#ifndef APSTUDIO_INVOKED\r\n"
    "#include ""targetver.h""\r\n"
    "#endif\r\n"
    "#include ""afxres.h""\r\n"
    "#include ""verrsrc.h""\r\n"
    "\0"
END

3 TEXTINCLUDE 
BEGIN
    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
    "#define _AFX_NO_OLE_RESOURCES\r\n"
    "#define _AFX_NO_TRACKER_RESOURCES\r\n"
    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
    "\r\n"
    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n"
    "LANGUAGE 4, 2\r\n"
    "#include ""res\\MD5SUM.rc2""  // 非 Microsoft Visual C++ 编辑的资源\r\n"
    "#include ""l.CHS\\afxres.rc""      // 标准组件\r\n"
    "#if !defined(_AFXDLL)\r\n"
    "#include ""l.CHS\\afxribbon.rc""   // MFC 功能区和控制条资源\r\n"
    "#endif\r\n"
    "#endif\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME           ICON                    "res\\MD5SUM.ico"


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "关于 MD5SUM"
FONT 9, "MS Shell Dlg", 0, 0, 0x1
BEGIN
    ICON            IDR_MAINFRAME,IDC_STATIC,14,14,21,20
    LTEXT           "MD5SUM,版本 1.0",IDC_STATIC,42,14,114,8,SS_NOPREFIX
    LTEXT           "版权所有 (C) 2019",IDC_STATIC,42,26,114,8
    DEFPUSHBUTTON   "确定",IDOK,113,41,50,14,WS_GROUP
END

IDD_MD5SUM_DIALOG DIALOGEX 0, 0, 269, 170
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_ACCEPTFILES | WS_EX_APPWINDOW
FONT 9, "MS Shell Dlg", 0, 0, 0x1
BEGIN
    PUSHBUTTON      "关闭",IDCANCEL,213,65,45,94
    EDITTEXT        IDC_EDIT_PATH,62,11,196,23,ES_READONLY | ES_WANTRETURN,WS_EX_LEFTSCROLLBAR
    PUSHBUTTON      "选择文件夹",IDC_BTN_OPEN,10,11,47,23
    PUSHBUTTON      "生成MD5",IDC_BTN_DO,61,37,149,23
    EDITTEXT        IDC_EDIT_RESULT,10,65,200,94,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL,WS_EX_LEFTSCROLLBAR
    PUSHBUTTON      "选择文件",IDC_BTN_OPENFILES,10,37,47,23
    PUSHBUTTON      "清空结果",IDC_BTN_CLEAR_RESULT,213,37,45,23
END


/////////////////////////////////////////////////////////////////////////////
//
// Version
//

VS_VERSION_INFO VERSIONINFO
 FILEVERSION 1,0,0,1
 PRODUCTVERSION 1,0,0,1
 FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x40004L
 FILETYPE 0x1L
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "080404B0"
        BEGIN
            VALUE "CompanyName", "TODO: <公司名>"
            VALUE "FileDescription", "MD5SUM"
            VALUE "FileVersion", "1.0.0.1"
            VALUE "InternalName", "MD5SUM.exe"
            VALUE "LegalCopyright", "TODO:  (C) <公司名>。  保留所有权利。"
            VALUE "OriginalFilename", "MD5SUM.exe"
            VALUE "ProductName", "TODO: <产品名>"
            VALUE "ProductVersion", "1.0.0.1"
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x804, 1200
    END
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
    IDD_ABOUTBOX, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 163
        TOPMARGIN, 7
        BOTTOMMARGIN, 55
    END

    IDD_MD5SUM_DIALOG, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 262
        TOPMARGIN, 7
        BOTTOMMARGIN, 163
    END
END
#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//

IDD_MD5SUM_DIALOG AFX_DIALOG_LAYOUT
BEGIN
    0
END


/////////////////////////////////////////////////////////////////////////////
//
// String Table
//

STRINGTABLE
BEGIN
    IDS_ABOUTBOX            "关于 MD5SUM(&A)..."
END

#endif    // 中文(简体,中国) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE 4, 2
#include "res\MD5SUM.rc2"  // 非 Microsoft Visual C++ 编辑的资源
#include "l.CHS\afxres.rc"      // 标准组件
#if !defined(_AFXDLL)
#include "l.CHS\afxribbon.rc"   // MFC 功能区和控制条资源
#endif
#endif

/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED