maoyehu 2 年 前
コミット
7af19bf565

+ 29 - 1
MFCApplication1/BaseUtility.cpp

@@ -281,7 +281,7 @@ string UnicodeToGB2312(TCHAR *pData)
 }
 
 
-void UTF8toANSI(string &strUTF8)
+void UTF8toANSI(std::string &strUTF8)
 {
 	//获取转换为多字节后需要的缓冲区大小,创建多字节缓冲区  
 	UINT nLen = MultiByteToWideChar(CP_UTF8, NULL, strUTF8.c_str(), -1, NULL, NULL);
@@ -1251,4 +1251,32 @@ string GetImageEncodeString(string strPath)
 	//关闭指针
 	is.close();
 	return strTemp;
+}
+
+string GenerateGUID()
+{
+	string guid_code;
+	char buf[64] = { 0 };
+	GUID guid;
+	if (S_OK == ::CoCreateGuid(&guid))
+	{
+		_snprintf(buf, sizeof(buf)
+			, "%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x"
+			, guid.Data1
+			, guid.Data2
+			, guid.Data3
+			, guid.Data4[0], guid.Data4[1]
+			, guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5]
+			, guid.Data4[6], guid.Data4[7]
+		);
+		guid_code = buf;
+	}
+	else
+	{
+		CTime tmNow = CTime::GetCurrentTime();
+		std::wstring strNow = tmNow.Format("%Y%m%d%H%M%S");
+		/*guid_code = strW2A(strNow);*/
+	}
+
+	return guid_code;
 }

+ 3 - 2
MFCApplication1/BaseUtility.h

@@ -64,7 +64,7 @@ bool TransToPriceFormat(const tstring& strSrc, tstring& strDes, double& dDes);
 
 wstring GB2312ToUnicode(const char *pData);
 wstring UTF8ToUnicode(const char* szU8);
-void UTF8toANSI(string &strUTF8);
+void UTF8toANSI(std::string &strUTF8);
 string UnicodeToUtf8(const wchar_t* unicode);
 string UnicodeToGB2312(TCHAR* pData);
 string UnicodeToGB2312(const tstring& strSrc);
@@ -173,4 +173,5 @@ tstring FormatFloatValue(double fValue);
 string FormatFloatValue2(double fValue);
 CString GetAppPath();
 
-string GetImageEncodeString(string strPath);
+string GetImageEncodeString(string strPath);
+string GenerateGUID();

+ 6 - 0
MFCApplication1/Config.cpp

@@ -51,6 +51,10 @@ BOOL CConfig::LoadFromINI()
 	m_strRepeat = szData;
 	GetPrivateProfileString(_T("Set"), _T("Token"), _T(""), szData, sizeof(szData), strIni);
 	m_strToken = szData;
+	GetPrivateProfileString(_T("Set"), _T("CsvPath"), _T(""), szData, sizeof(szData), strIni);
+	m_strCsvPath = szData;
+	GetPrivateProfileString(_T("Set"), _T("CsvFileDir"), _T(""), szData, sizeof(szData), strIni);
+	m_strCsvFileDir = szData;
 
 	return TRUE;
 }
@@ -70,6 +74,8 @@ BOOL CConfig::SaveToINI()
 	WritePrivateProfileString(_T("Set"), _T("Cut"), m_strCut, strIni);
 
 	WritePrivateProfileString(_T("Set"), _T("Repeat"), m_strRepeat, strIni);
+	WritePrivateProfileString(_T("Set"), _T("CsvPath"), m_strCsvPath, strIni);
+	WritePrivateProfileString(_T("Set"), _T("CsvFileDir"), m_strCsvFileDir, strIni);
 
 	return TRUE;
 }

+ 2 - 0
MFCApplication1/Config.h

@@ -44,6 +44,8 @@ public:
 	CString m_strRepeat; // È¥ÖØÎļþ¼Ð·¾¶
 
 	CString m_strToken; // baidu token
+	CString m_strCsvPath;
+	CString m_strCsvFileDir;
 
 };
 

+ 36 - 0
MFCApplication1/CvxText.cpp

@@ -873,5 +873,41 @@ int PareseModeJson(preinfo::templatesInfo&  temeplatInfo)
 		page._vecQtChoices.push_back(_qstc);
 	}
 	temeplatInfo.push_back(page);
+	return 0;
+}
+
+int cutPaper(std::string strImagePath, std::string strCurDir, vector<std::tuple<cv::Rect, std::string>>& vecTranslate)
+{
+	cv::Mat src = cv::imread(strImagePath);
+	if (src.empty())
+	{
+		return 1;
+	}
+
+	int index = 1;
+	for (auto& iter : vecTranslate)
+	{
+		cv::Rect rcOcr = std::get<0>(iter);
+		std::string words = ConvertGB2312toUTF8(std::get<1>(iter).c_str());
+		
+		DWORD dwCount = GetTickCount();
+		time_t tt = std::time(0);
+
+		char szOcrJpgPath[MAX_PATH] = { 0 };
+		char szOcrJpgText[MAX_PATH] = { 0 };
+		sprintf(szOcrJpgPath, "%s\\%lld_%ld_%d.jpg", strCurDir.c_str(), tt, dwCount, index);
+		sprintf(szOcrJpgText, "%s\\%lld_%ld_%d.txt", strCurDir.c_str(), tt, dwCount, index);
+
+		CFile zip3;
+		zip3.Open(CA2T(szOcrJpgText), CFile::modeCreate | CFile::modeWrite);
+		zip3.Write((void*)words.c_str(), words.length());
+		zip3.Close();
+
+		cv::Mat cut = src(rcOcr);
+		cv::imwrite(szOcrJpgPath, cut);
+
+		index++;
+	}
+
 	return 0;
 }

+ 2 - 0
MFCApplication1/CvxText.h

@@ -66,4 +66,6 @@ int cutPaper(int pageNum, std::string strJsonPath, std::string strPaperPath, std
 
 int PareseModeJson(preinfo::templatesInfo&  temeplatInfo);
 
+int cutPaper(std::string strImagePath, std::string strCurDir, vector<std::tuple<cv::Rect, std::string>>& vecTranslate);
+
 #endif // PUTTEXT_H_

BIN
MFCApplication1/MFCApplication1.rc


+ 353 - 1
MFCApplication1/MFCApplication1Dlg.cpp

@@ -494,6 +494,7 @@ void CMFCApplication1Dlg::DoDataExchange(CDataExchange* pDX)
 	DDX_Text(pDX, IDC_EDIT_MSG, m_strMsg);
 	DDX_Text(pDX, IDC_EDIT_SCANMSG, m_strScanMsg);
 	DDX_Text(pDX, IDC_EDIT_REPEATMSG, m_strRepeatMsg);
+	DDX_Text(pDX, IDC_EDIT_CSVMSG, m_strCsvMsg);
 }
 
 BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDialogEx)
@@ -505,6 +506,7 @@ BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDialogEx)
 	ON_MESSAGE(WM_SHOWSCANINFO, OnShowScanInfo)
 	ON_MESSAGE(WM_PROCESS, OnProcessInfo)
 	ON_MESSAGE(WM_SHOWREPEATINFO, OnShowRepeatInfo)
+	ON_MESSAGE(WM_SHOWCSVINFO, OnShowCvsInfo)
 	ON_BN_CLICKED(IDCANCEL, &CMFCApplication1Dlg::OnBnClickedCancel)
 	ON_BN_CLICKED(IDC_BTN_TXT, &CMFCApplication1Dlg::OnBnClickedBtnTxt)
 	ON_BN_CLICKED(IDC_BTN_PDF, &CMFCApplication1Dlg::OnBnClickedBtnPdf)
@@ -514,6 +516,9 @@ BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDialogEx)
 	ON_BN_CLICKED(ID_BTN_SCAN, &CMFCApplication1Dlg::OnBnClickedBtnScan)
 	ON_BN_CLICKED(IDC_BTN_REPEATPATH, &CMFCApplication1Dlg::OnBnClickedBtnRepeatpath)
 	ON_BN_CLICKED(ID_BTN_REPEAT, &CMFCApplication1Dlg::OnBnClickedBtnRepeat)
+	ON_BN_CLICKED(IDC_BTN_CSVPATH, &CMFCApplication1Dlg::OnBnClickedBtnCsvpath)
+	ON_BN_CLICKED(IDC_BTN_CSVFILEDIR, &CMFCApplication1Dlg::OnBnClickedBtnCsvfiledir)
+	ON_BN_CLICKED(ID_BTN_BAIDU_IDENTIFY, &CMFCApplication1Dlg::OnBnClickedBtnBaiduIdentify)
 END_MESSAGE_MAP()
 
 
@@ -556,6 +561,11 @@ BOOL CMFCApplication1Dlg::OnInitDialog()
 	GetDlgItem(IDC_EDIT_IMGPATH)->SetWindowText(CConfig::Instance()->m_strImg);
 	GetDlgItem(IDC_EDIT_CUTPATH)->SetWindowText(CConfig::Instance()->m_strCut);
 	GetDlgItem(IDC_EDIT_REPEATPATH)->SetWindowText(CConfig::Instance()->m_strRepeat);
+	GetDlgItem(IDC_EDIT_CSVPATH)->SetWindowText(CConfig::Instance()->m_strCsvPath);
+	GetDlgItem(IDC_EDIT_CSVFILEDIR)->SetWindowText(CConfig::Instance()->m_strCsvFileDir);
+
+	GetDlgItem(IDC_STATIC_CSV_PROCESS)->SetWindowText(L"--/--");
+	
 
 	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
 }
@@ -727,6 +737,36 @@ LRESULT CMFCApplication1Dlg::OnShowRepeatInfo(WPARAM  wParam, LPARAM  lParam)
 	return 0;
 }
 
+LRESULT CMFCApplication1Dlg::OnShowCvsInfo(WPARAM  wParam, LPARAM  lParam)
+{
+	if (lParam == 1)
+	{
+		GetDlgItem(ID_BTN_BAIDU_IDENTIFY)->EnableWindow(TRUE);
+		return 0;
+	}
+	
+	wchar_t* p = (wchar_t*)wParam;
+	CString str;
+	str.Format(_T("%s"), p);
+	if (lParam == 2)
+	{
+		CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATIC_CSV_PROCESS);
+		pStatic->SetWindowText(str);
+		return 0 ;
+	}
+
+	m_strCsvMsg += str;
+	UpdateData(FALSE);
+
+	CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_CSVMSG);
+	SCROLLINFO ScroInfo; // 定义SCROLLINFO 类型变量
+	pEdit->GetScrollInfo(SB_VERT, &ScroInfo); // 获取ScrollBar信息,其中m_recv为CEdit类型变量
+	pEdit->SetScrollPos(SB_VERT, ScroInfo.nMax); // 将滚动条设置为最大,即滚动到最底下;
+	pEdit->LineScroll(ScroInfo.nMax);
+
+	return 0;
+}
+
 LRESULT CMFCApplication1Dlg::OnProcessInfo(WPARAM wParam, LPARAM lParam)
 {
 	CString strProcess = _T("--");
@@ -974,6 +1014,30 @@ void CMFCApplication1Dlg::FormatRepeatMsg(const char *szFmt, ...)
 	SendMessage(WM_SHOWREPEATINFO, (WPARAM)strMsg.GetBuffer(), 0);
 }
 
+void CMFCApplication1Dlg::FormatCsvMsg(const char *szFmt, ...)
+{
+	if (!szFmt)
+		return;
+
+	va_list ap;
+	va_start(ap, szFmt);
+	size_t nLength = _vsnprintf(nullptr, 0, szFmt, ap) + 1;
+	CBuffers buffer;
+	char* szLogMsg = buffer.GetBuf(nLength);
+	_vsnprintf(szLogMsg, nLength, szFmt, ap);
+	va_end(ap);
+	SYSTEMTIME st;
+	GetLocalTime(&st);
+	char chBuf[24] = { 0 };
+	sprintf(chBuf, "%02d-%02d-%02d %02d:%02d:%02d ",
+		st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
+
+	CString strMsg;
+	// 扫描异常
+	strMsg.Format(L"%s %s\r\n", GB2312ToTstring(chBuf).c_str(), GB2312ToTstring(szLogMsg).c_str());
+	SendMessage(WM_SHOWCSVINFO, (WPARAM)strMsg.GetBuffer(), 0);
+}
+
 HANDLE _threadRepeat = NULL;
 
 
@@ -1064,4 +1128,292 @@ void CMFCApplication1Dlg::OnBnClickedBtnRepeat()
 
 	SAFETY_EXIT_THREAD(_threadRepeat, 100);
 	_threadRepeat = CreateThread(NULL, 0, RepeatThread, NULL, 0, NULL);
-}
+}
+
+
+
+
+
+void CMFCApplication1Dlg::SelectCsvFile(CString& lpszFile)
+{
+	CString OpenFilter = _T("文本文件(*.csv)|*.csv;|");
+	CFileDialog FileOpen(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, OpenFilter);
+	if (IDOK == FileOpen.DoModal())
+	{
+		lpszFile = FileOpen.GetPathName();
+		lpszFile.Replace('\\', '/');
+	}
+}
+
+
+void CMFCApplication1Dlg::OnBnClickedBtnCsvpath()
+{
+	CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_CSVPATH);
+	if (!pEdit)
+	{
+		return;
+	}
+	CString strText;
+	SelectCsvFile(strText);
+	if (strText.GetLength() == 0)
+	{
+		return;
+	}
+	pEdit->SetWindowText(strText);
+	CConfig::Instance()->m_strCsvPath = strText;
+}
+
+
+void CMFCApplication1Dlg::OnBnClickedBtnCsvfiledir()
+{
+	CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_CSVFILEDIR);
+	if (!pEdit)
+	{
+		return;
+	}
+	CString strText;
+	SelectFolder(GetSafeHwnd(), strText);
+	if (strText.GetLength() == 0)
+	{
+		return;
+	}
+	pEdit->SetWindowText(strText);
+	CConfig::Instance()->m_strCsvFileDir = strText;
+}
+
+size_t write_data(void* ptr, size_t size, size_t nmemb, FILE* stream)
+{
+	size_t written = fwrite(ptr, size, nmemb, stream);
+	printf("file writen byte:%zu\n", written);
+
+	return written;
+}
+
+int http_download(std::string url, std::string savepath)
+{
+	CURL* handle = nullptr;
+	FILE* fp;
+	CURLcode res;
+	handle = curl_easy_init();
+	if (handle)
+	{
+		fp = fopen(savepath.c_str(), "wb");
+		curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
+		curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_data);
+		curl_easy_setopt(handle, CURLOPT_WRITEDATA, fp);
+		res = curl_easy_perform(handle);
+		fclose(fp);
+		curl_easy_cleanup(handle);
+	}
+
+	return res;
+}
+
+/**
+* 手写文字识别
+* @return 调用成功返回0,发生错误返回其他错误码
+*/
+int handwriting_baidu_url(string img_url, std::string &json_result, const std::string &access_token)
+{
+	handwriting_result = "";
+	std::string url = request_url + "?access_token=" + access_token;
+	CURL *curl = NULL;
+	CURLcode result_code;
+	int is_success;
+	curl = curl_easy_init();
+	if (curl)
+	{
+		curl_easy_setopt(curl, CURLOPT_URL, url.data());
+		curl_easy_setopt(curl, CURLOPT_POST, 1);
+		curl_httppost *post = NULL;
+		curl_httppost *last = NULL;
+		curl_formadd(&post, &last, CURLFORM_COPYNAME, "url", CURLFORM_COPYCONTENTS, img_url.c_str(), CURLFORM_END);
+
+		curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
+		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback);
+		result_code = curl_easy_perform(curl);
+		if (result_code != CURLE_OK)
+		{
+			fprintf(stderr, "curl_easy_perform() failed: %s\n",
+				curl_easy_strerror(result_code));
+			is_success = 1;
+			return is_success;
+		}
+		UTF8toANSI(handwriting_result);
+		json_result = handwriting_result;
+		curl_easy_cleanup(curl);
+		is_success = 0;
+	}
+	else
+	{
+		fprintf(stderr, "curl_easy_init() failed.");
+		is_success = 1;
+	}
+	return is_success;
+}
+
+HANDLE _threadBdIdentify = NULL;
+DWORD WINAPI ThreadBdIdentify(void *param)
+{
+	CMFCApplication1Dlg* pWnd = (CMFCApplication1Dlg*)theApp.m_pMainWnd;
+
+	pWnd->FormatCsvMsg("启动百度切图线程......");
+	auto exitfun = [&]() {
+		pWnd->FormatCsvMsg("百度切图线程退出。");
+		SendMessage(pWnd->m_hWnd, WM_SHOWCSVINFO, 0, 1);
+	};
+
+
+	std::ifstream csv_data(CConfig::Instance()->m_strCsvPath, std::ios::in);
+	std::string line;
+
+	if (!csv_data.is_open())
+	{
+		pWnd->FormatCsvMsg("打开CSV文件失败");
+		SendMessage(pWnd->m_hWnd, WM_SHOWCSVINFO, 0, 1);
+		return 0L;
+	}
+
+	pWnd->FormatCsvMsg("开始解析CSV文件");
+	std::istringstream sin;         //将整行字符串line读入到字符串istringstream中
+	std::vector<std::string> words; //声明一个字符串向量
+	std::string word;
+
+	std::list<std::tuple<std::string, std::string>> list_words;
+	// 读取标题行
+	std::getline(csv_data, line);
+	// 读取数据
+	while (std::getline(csv_data, line))
+	{
+		sin.clear();
+		sin.str(line);
+		words.clear();
+		while (std::getline(sin, word, ',')) //将字符串流sin中的字符读到field字符串中,以逗号为分隔符
+		{
+			words.push_back(word); //将每一格中的数据逐个push
+		}
+		if (words.size() >= 4)
+		{
+			list_words.push_back({ words[3],words[4] });
+		}
+	}
+	csv_data.close();
+	pWnd->FormatCsvMsg("CSV文件解析结束");
+	pWnd->FormatCsvMsg("本次共【%d】条数据", list_words.size());
+
+	wchar_t tempPath[MAX_PATH];
+	DWORD dwSize = MAX_PATH;
+	GetTempPath(dwSize, tempPath);//获取临时文件夹路径
+
+ 	string strToken = CT2A(CConfig::Instance()->m_strToken);
+	std::map<std::string, int> map_count;
+	uint current_cnt = 1;
+	for (auto& iter : list_words)
+	{
+		std::string anser_url = std::get<0>(iter);
+		std::string anser_type = std::get<1>(iter);
+		std::wstring anser_type_w = CA2T(anser_type.c_str());
+		map_count[anser_type]++;
+
+		int group = map_count[anser_type] / 10000 + 1;
+		CString save_dir_type;
+		CString save_dir_type_group;
+		save_dir_type.Format(L"%s/%s", CConfig::Instance()->m_strCsvFileDir, anser_type_w.c_str());
+		save_dir_type_group.Format(L"%s/%s/%d", CConfig::Instance()->m_strCsvFileDir, anser_type_w.c_str(), group);
+		
+		if (!PathIsDirectory(save_dir_type))
+		{
+			::CreateDirectory(save_dir_type, 0);
+		}
+		if (!PathIsDirectory(save_dir_type_group))
+		{
+			::CreateDirectory(save_dir_type_group, 0);
+		}
+
+		std::string strResult;
+		vector<std::tuple<cv::Rect, std::string>> vecTranslate;
+		int trycnt = 3;
+		bool ret = false;
+		do
+		{
+			handwriting_baidu_url(anser_url, strResult, strToken);
+			ret = ParseJson(strResult, vecTranslate);
+			if (ret)
+			{
+				break;
+			}
+			trycnt--;
+		} while (trycnt > 0);
+
+		if (!ret)
+		{
+			pWnd->FormatCsvMsg("调用百度接口,生成识别JSON失败");
+			continue;
+		}
+
+		CString save_dir_src_img;
+		DWORD dwCount = GetTickCount();
+		time_t tt = std::time(0);
+		std::wstring guid = CA2T(GenerateGUID().c_str());
+		save_dir_src_img.Format(L"%s/%s/%s_%lld_%ld.jpg", CConfig::Instance()->m_strCsvFileDir, L"src_img", guid.c_str(), tt, dwCount);
+		std::string img_path = CT2A(save_dir_src_img.GetBuffer());
+		
+		int ret_download = http_download(anser_url, img_path);
+		if (ret_download != CURLE_OK)
+		{
+			pWnd->FormatCsvMsg("下载失败");
+		}
+
+		std::string  save_dir_type_group_a = CT2A(save_dir_type_group);
+		int ret_cut = cutPaper(img_path, save_dir_type_group_a, vecTranslate);
+		if (ret_cut == 0)
+		{
+			CString strInfo;
+			strInfo.Format(L"%d/%d", current_cnt, list_words.size());
+			SendMessage(pWnd->m_hWnd, WM_SHOWCSVINFO, (WPARAM)strInfo.GetBuffer(), 2);
+		}
+		else
+		{
+			pWnd->FormatCsvMsg("生成第%d份数据失败", current_cnt);
+		}
+		current_cnt++;
+	}
+	
+	exitfun();
+	return  0L;
+}
+
+void CMFCApplication1Dlg::OnBnClickedBtnBaiduIdentify()
+{
+	if (CConfig::Instance()->m_strCsvPath.GetLength() == 0)
+	{
+		AfxMessageBox(L"CSV文件路径未选择");
+		return;
+	}
+
+	if (CConfig::Instance()->m_strCsvFileDir.GetLength() == 0)
+	{
+		AfxMessageBox(L"切图文件夹未选择");
+		return;
+	}
+
+	GetDlgItem(ID_BTN_BAIDU_IDENTIFY)->EnableWindow(FALSE);
+	m_strCsvMsg = "";
+	
+
+	CString src_img_dir(CConfig::Instance()->m_strCsvFileDir);
+	src_img_dir.Append(L"/src_img");
+	if (!PathIsDirectory(src_img_dir))
+	{
+		BOOL ret = ::CreateDirectory(src_img_dir, 0);
+		if (!ret)
+		{
+			GetDlgItem(ID_BTN_BAIDU_IDENTIFY)->EnableWindow(TRUE);
+			AfxMessageBox(L"源图文件夹路径创建失败");
+			return;
+		}
+	}
+
+	SAFETY_EXIT_THREAD(_threadBdIdentify, 100);
+	_threadBdIdentify = CreateThread(NULL, 0, ThreadBdIdentify, NULL, 0, NULL);
+}

+ 8 - 0
MFCApplication1/MFCApplication1Dlg.h

@@ -8,6 +8,7 @@
 #define WM_SHOWSCANINFO (WM_USER+0x2)
 #define WM_PROCESS (WM_USER+0x3)
 #define WM_SHOWREPEATINFO (WM_USER+0x4)
+#define WM_SHOWCSVINFO (WM_USER+0x5)
 // CMFCApplication1Dlg 对话框
 class CMFCApplication1Dlg : public CDialogEx
 {
@@ -37,18 +38,21 @@ protected:
 	afx_msg LRESULT OnShowScanInfo(WPARAM  wParam, LPARAM  lParam);
 	afx_msg LRESULT OnProcessInfo(WPARAM  wParam, LPARAM  lParam);
 	afx_msg LRESULT OnShowRepeatInfo(WPARAM  wParam, LPARAM  lParam);
+	afx_msg LRESULT OnShowCvsInfo(WPARAM  wParam, LPARAM  lParam);
 	DECLARE_MESSAGE_MAP()
 public:
 	afx_msg void OnBnClickedOk();
 	CString m_strMsg;
 	CString m_strScanMsg;
 	CString m_strRepeatMsg;
+	CString m_strCsvMsg;
 	void UpdateMsg(CString strMsg);
 	void UpdateScanMsg(CString strMsg);
 	afx_msg void OnBnClickedCancel();
 
 	void SelectFolder(HWND hwnd, CString& lpszFolder);
 	void SelectFile(CString& lpszFile);
+	void SelectCsvFile(CString& lpszFile);
 	afx_msg void OnBnClickedBtnTxt();
 	afx_msg void OnBnClickedBtnPdf();
 	
@@ -69,5 +73,9 @@ public:
 	afx_msg void OnBnClickedBtnRepeatpath();
 	void FormatScanMsg(const char * szFmt, ...);
 	void FormatRepeatMsg(const char *szFmt, ...);
+	void FormatCsvMsg(const char *szFmt, ...);
 	afx_msg void OnBnClickedBtnRepeat();
+	afx_msg void OnBnClickedBtnCsvpath();
+	afx_msg void OnBnClickedBtnCsvfiledir();
+	afx_msg void OnBnClickedBtnBaiduIdentify();
 };

+ 8 - 2
MFCApplication1/resource.h

@@ -27,8 +27,14 @@
 #define IDC_EDIT_PAGE_NUMBER            1015
 #define IDC_BTN_REPEATPATH              1016
 #define ID_BTN_REPEAT                   1017
-#define IDC_EDIT_MSG2                   1018
 #define IDC_EDIT_REPEATMSG              1018
+#define IDC_EDIT_CSVFILEDIR             1019
+#define IDC_BTN_CSVFILEDIR              1020
+#define IDC_EDIT_CSVMSG                 1021
+#define ID_BTN_BAIDU_IDENTIFY           1022
+#define IDC_EDIT_CSVPATH                1023
+#define IDC_BTN_CSVPATH                 1024
+#define IDC_STATIC_CSV_PROCESS          1025
 
 // Next default values for new objects
 // 
@@ -36,7 +42,7 @@
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE        130
 #define _APS_NEXT_COMMAND_VALUE         32771
-#define _APS_NEXT_CONTROL_VALUE         1016
+#define _APS_NEXT_CONTROL_VALUE         1026
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif