// MFCApplication1Dlg.cpp: 实现文件 // #include "pch.h" #include "framework.h" #include "MFCApplication1.h" #include "MFCApplication1Dlg.h" #include "afxdialogex.h" #include "CvxText.h" #include "BaseUtility.h" #include "libpdf.h" #include "AssignWords.h" #include "lib_common_depence.h" #include #include #include "Buffers.h" #include "Config.h" #include #if defined(GNUC) #pragma GCC diagnostic push #pragma GCC diagnostic ignored “-Wdeprecated-declarations” #elif defined(_MSC_VER) #pragma warning(disable : 4996) #endif #include #ifdef _DEBUG #pragma comment(lib, "libpdfd.lib") #pragma comment(lib, "lib_common_depence_d.lib") #else #pragma comment(lib, "libpdf.lib") #pragma comment(lib, "lib_common_depence.lib") #endif #ifdef _DEBUG #define new DEBUG_NEW #endif #define SAFETY_CLOSE_HANDLE( handle ) \ if( NULL != handle ) \ { \ CloseHandle( handle ); \ handle = NULL; \ } #define SAFETY_EXIT_THREAD( hThread, Timeout ) \ if( NULL != hThread ) \ { \ if( WaitForSingleObject( hThread, Timeout ) == WAIT_TIMEOUT ) \ TerminateThread( hThread, -1 ); \ CloseHandle( hThread ); \ hThread = NULL; \ } // 用于应用程序“关于”菜单项的 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() // CMFCApplication1Dlg 对话框 vector g_vecFileList;//扫描文件列表 int g_scanCount = 0;//扫描文件个数 HANDLE _threadProcess = NULL; DWORD WINAPI ProcessThread(void *param) { CMFCApplication1Dlg* pWnd = (CMFCApplication1Dlg*)theApp.m_pMainWnd; std::vector> oneList; std::vector> twoList; std::vector> errorList; std::vector> fourList; int row = 0; int ret = AssignWordsFromTest(UnicodeToGB2312(pWnd->m_strTextPath), oneList, twoList, errorList, fourList, row); if (ret < 0) { static wchar_t* erroArry[] = { L"未找到答案文件,请校验\r\n", L"题干和答案行数不一致,请确认\r\n", L"题目文件中第%d行为空,请校验\r\n", L"答案文件中第%d行为空,请校验\r\n" }; wstring erro = L"未知错误"; wchar_t erro2[64] = { 0 }; wchar_t erro3[64] = { 0 }; _stprintf(erro2, erroArry[2], row); _stprintf(erro3, erroArry[3], row); switch (ret) { default: break; case -1:erro = erroArry[0]; break; case -2:erro = erroArry[1]; break; case -3:erro = erro2; break; case -4:erro = erro3; break; } SendMessage(pWnd->m_hWnd, WM_SHOWINFO, (WPARAM)erro.c_str(), 1); return 0L; } if (ret == 0) { for (auto& iter : errorList) { wstring erroInfo; erroInfo.append(L"题目:"); erroInfo.append(CA2T(std::get<0>(iter).c_str())); erroInfo.append(L"标准答案:"); erroInfo.append(CA2T(std::get<1>(iter).c_str())); erroInfo.append(L"有问题\r\n"); SendMessage(pWnd->m_hWnd, WM_SHOWINFO, (WPARAM)erroInfo.c_str(), 0); } } HMODULE module = GetModuleHandle(0); TCHAR pFileName[MAX_PATH + 2] = { 0 }; GetModuleFileName(module, pFileName, MAX_PATH); CString csFullPath(pFileName); int nPos = csFullPath.ReverseFind(_T('\\')); CString strFileDir = csFullPath.Left(nPos); CString strFilePath = strFileDir + L"\\config.ini"; WCHAR wgray[10]; GetPrivateProfileString(L"USER", L"GrayPix", L"100", wgray, 10, strFilePath); int nLineGrayPix = _wtoi(wgray); auto CovertPdfFunc = [&](std::vector>& vctFiles, int col, int& pageNum){ std::string strPage1; for (size_t i = 0; i < vctFiles.size(); i += max_line * col) { std::vector> vecSmall; auto last = std::min(vctFiles.size(), i + max_line * col); vecSmall.insert(vecSmall.begin(), vctFiles.begin() + i, vctFiles.begin() + last); std::string strPagePath; dataCollectionPaper(col, pageNum, 30, nLineGrayPix, false, vecSmall, pWnd->m_strPdfDir, strPagePath); if (strPage1.length() == 0) { strPage1 = strPagePath; } else { CString strPdfPath; strPdfPath.Format(L"%s/pdf/%d.pdf", pWnd->m_strPdfDir, pageNum); PdfNewFromImage({ strPage1, strPagePath }, TstringToGB2312(strPdfPath.GetBuffer())); strPage1 = ""; CString strMsg = L""; strMsg.Format(L"%s\r\n", strPdfPath); SendMessage(pWnd->m_hWnd, WM_SHOWINFO, (WPARAM)strMsg.GetBuffer(), 0); strMsg.ReleaseBuffer(); } pageNum++; } if (strPage1.length() > 0) { CString strPdfPath; strPdfPath.Format(L"%s/pdf/%d.pdf", pWnd->m_strPdfDir, pageNum); PdfNewFromImage({ strPage1 }, TstringToGB2312(strPdfPath.GetBuffer())); CString strMsg = L""; strMsg.Format(L"%s\r\n", strPdfPath); SendMessage(pWnd->m_hWnd, WM_SHOWINFO, (WPARAM)strMsg.GetBuffer(), 0); strMsg.ReleaseBuffer(); } }; int pageNum = _wtoi(pWnd->m_strPageNumber); CovertPdfFunc(oneList, 1, pageNum); CovertPdfFunc(twoList, 2, pageNum); //通知发送消息到窗口 CString strErrorMsg = L""; strErrorMsg.Format(L"PDF生成完成!\r\n"); SendMessage(pWnd->m_hWnd, WM_SHOWINFO, (WPARAM)strErrorMsg.GetBuffer(), 1); strErrorMsg.ReleaseBuffer(); return 0L; } const static std::string request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/handwriting"; static std::string handwriting_result; /** * curl发送http请求调用的回调函数,回调函数中对返回的json格式的body进行了解析,解析结果储存在全局的静态变量当中 * @param 参数定义见libcurl文档 * @return 返回值定义见libcurl文档 */ static size_t callback(void *ptr, size_t size, size_t nmemb, void *stream) { char * pData = (char *)ptr; handwriting_result.append(pData, size * nmemb); // 获取到的body存放在ptr中,先将其转换为string格式 //handwriting_result = std::string((char *)ptr, size * nmemb); return size * nmemb; } /** * 手写文字识别 * @return 调用成功返回0,发生错误返回其他错误码 */ int handwriting(string strImage, 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, "image", CURLFORM_COPYCONTENTS, strImage.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; } int IdentifyCallback(result::spinfo& pinfo, void* param) { CMFCApplication1Dlg* pWnd = (CMFCApplication1Dlg*)theApp.m_pMainWnd; if (pinfo.choiceRes.size() < 3 || pinfo.vecUrlAPath.size() == 0) { pWnd->PostMessage(WM_PROCESS, NULL, NULL); pWnd->FormatScanMsg("矫正图像失败原图为:%s", pinfo.vecUrlPath.size() > 0 ? pinfo.vecUrlPath[0].c_str() : "图像为空"); } std::string strChoiceRes; for (auto& row : pinfo.choiceRes) { for (auto& col : row.vecRes) { strChoiceRes.append(col ? "1" : "0"); } } int length = strChoiceRes.length(); int number = 0; for (int i = 0; i < length; ++i) { if (strChoiceRes[i] == '1') // 其中注意if的判断两个条件相等的符号 number += pow(2, length - 1 - i); } string strToken = CT2A(CConfig::Instance()->m_strToken); string strResult; string strEncode = GetImageEncodeString(pinfo.vecUrlAPath[0]); handwriting(strEncode, strResult, strToken); std::string strJsonDir = CT2A(CConfig::Instance()->m_strMode); strJsonDir.append("/"); strJsonDir.append(std::to_string(number)); strJsonDir.append(".json"); std::string strSaveDir = CT2A(CConfig::Instance()->m_strCut); cutPaper(number, strJsonDir, pinfo.vecUrlAPath[0], strSaveDir); g_scanCount++; pWnd->PostMessage(WM_PROCESS, NULL, NULL); pWnd->FormatScanMsg("生成切割图像:%s", std::to_string(number).c_str()); return 0; } enum EnumSearFileType { file,//扫描文件 dir,//扫描文件夹 }; void GetImages(CString strPath) { queue queuePath; queuePath.push(strPath); EnumSearFileType serchType = file; CFileFind finder; do { bool bFinished = finder.FindFile(queuePath.front() + _T("\\*.JPG")); while (serchType == file && bFinished) { bFinished = finder.FindNextFile(); if (finder.IsDirectory())continue; CString strPath = finder.GetFilePath(); g_vecFileList.push_back(UnicodeToGB2312(strPath)); } serchType = dir; bFinished = finder.FindFile(queuePath.front() + _T("\\*.*")); while (bFinished) { bFinished = finder.FindNextFile(); if (finder.IsDirectory() && !finder.IsDots()) { queuePath.push(finder.GetFilePath()); } } queuePath.pop(); serchType = file; } while (queuePath.size() > 0); } string GetBatchId() { 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); return chBuf; } HANDLE _threadScan = NULL; char* g_strIdentifyMsg[7] = { "正常","内部error","批次号异常","保存路径异常","模板为空","图像列表异常","图像列表不是模板整数倍" }; DWORD WINAPI ScanThread(void *param) { g_scanCount = 0; g_vecFileList.clear(); GetImages(CConfig::Instance()->m_strImg); CMFCApplication1Dlg* pWnd = (CMFCApplication1Dlg*)theApp.m_pMainWnd; pWnd->PostMessage(WM_PROCESS, NULL, NULL); pWnd->FormatScanMsg("启动扫描线程......"); auto exitfun = [&]() { pWnd->FormatScanMsg("扫描线程退出。"); SendMessage(pWnd->m_hWnd, WM_SHOWSCANINFO, 0, 1); }; preinfo::templatesInfo temeplatInfo; preinfo::SubjChiInfo sujChiInfo; std::string strTempDir = CT2A(CConfig::Instance()->m_strCut); /*if (_access(strTempDir.c_str(), 0) == -1) { _mkdir(strTempDir.c_str()); }*/ int nRet = PareseModeJson(temeplatInfo); if (nRet) { pWnd->FormatScanMsg("模板解析失败!"); exitfun(); return 0; } //生成批次号 string strBatchId = GetBatchId(); pWnd->FormatScanMsg("创建批次id:%s", strBatchId.c_str()); nRet = api_processing_images(strBatchId.c_str(), strTempDir.c_str(), temeplatInfo, sujChiInfo, g_vecFileList, LOG_AUTO, false, OLNS, IdentifyCallback, NULL); ////启动算法扫描功能 if (nRet != RT_OK) { if (nRet >= 0 && nRet <= 6) pWnd->FormatScanMsg("扫描失败,错误描述:%s, errorCode:%d", g_strIdentifyMsg[nRet], nRet); else pWnd->FormatScanMsg("扫描失败,errorCode:%d", nRet); } exitfun(); return 0L; } CMFCApplication1Dlg::CMFCApplication1Dlg(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_MFCAPPLICATION1_DIALOG, pParent) , m_strMsg(_T("")), m_strScanMsg(_T("")) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CMFCApplication1Dlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT_MSG, m_strMsg); DDX_Text(pDX, IDC_EDIT_SCANMSG, m_strScanMsg); } BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDOK, &CMFCApplication1Dlg::OnBnClickedOk) ON_MESSAGE(WM_SHOWINFO, OnShowInfo) ON_MESSAGE(WM_SHOWSCANINFO, OnShowScanInfo) ON_MESSAGE(WM_PROCESS, OnProcessInfo) ON_BN_CLICKED(IDCANCEL, &CMFCApplication1Dlg::OnBnClickedCancel) ON_BN_CLICKED(IDC_BTN_TXT, &CMFCApplication1Dlg::OnBnClickedBtnTxt) ON_BN_CLICKED(IDC_BTN_PDF, &CMFCApplication1Dlg::OnBnClickedBtnPdf) ON_BN_CLICKED(IDC_BTN_MODEPATH, &CMFCApplication1Dlg::OnBnClickedBtnModepath) ON_BN_CLICKED(IDC_BTN_IMGPATH, &CMFCApplication1Dlg::OnBnClickedBtnImgpath) ON_BN_CLICKED(IDC_BTN_CUTPATH, &CMFCApplication1Dlg::OnBnClickedBtnCutpath) ON_BN_CLICKED(ID_BTN_SCAN, &CMFCApplication1Dlg::OnBnClickedBtnScan) END_MESSAGE_MAP() // CMFCApplication1Dlg 消息处理程序 BOOL CMFCApplication1Dlg::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); // 设置小图标 CConfig::Instance()->LoadFromINI(); GetDlgItem(IDC_EDIT_TXT)->SetWindowText(CConfig::Instance()->m_strTxt); GetDlgItem(IDC_EDIT_PDF)->SetWindowText(CConfig::Instance()->m_strPdf); GetDlgItem(IDC_EDIT_MODEPATH)->SetWindowText(CConfig::Instance()->m_strMode); GetDlgItem(IDC_EDIT_IMGPATH)->SetWindowText(CConfig::Instance()->m_strImg); GetDlgItem(IDC_EDIT_CUTPATH)->SetWindowText(CConfig::Instance()->m_strCut); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } void CMFCApplication1Dlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialogEx::OnSysCommand(nID, lParam); } } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CMFCApplication1Dlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast(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 CMFCApplication1Dlg::OnQueryDragIcon() { return static_cast(m_hIcon); } void CMFCApplication1Dlg::OnBnClickedOk() { ((CEdit*)GetDlgItem(IDC_EDIT_TXT))->GetWindowText(m_strTextPath); ((CEdit*)GetDlgItem(IDC_EDIT_PDF))->GetWindowText(m_strPdfDir); ((CEdit*)GetDlgItem(IDC_EDIT_PAGE_NUMBER))->GetWindowText(m_strPageNumber); if (m_strTextPath.GetLength() == 0) { AfxMessageBox(L"语料库文件未选择"); return; } if (m_strPdfDir.GetLength() == 0) { AfxMessageBox(L"PDF文件夹未选择"); return; } m_strPageNumber.Trim(); if (m_strPageNumber.GetLength() == 0) { AfxMessageBox(L"启始页码未输入"); return; } if (m_strPageNumber.SpanIncluding(_T("0123456789")) != m_strPageNumber) { AfxMessageBox(L"启始页码不是数字"); return; } if (_wtoi(m_strPageNumber.GetBuffer()) > 20000) { AfxMessageBox(L"启始页码小于20000"); return; } GetDlgItem(IDOK)->EnableWindow(FALSE); m_strMsg = ""; CString strJsonDir(m_strPdfDir); strJsonDir.Append(L"\\json"); if (!PathIsDirectory(strJsonDir)) { ::CreateDirectory(strJsonDir, 0); } CString strPdfDir(m_strPdfDir); strPdfDir.Append(L"\\pdf"); if (!PathIsDirectory(strPdfDir)) { ::CreateDirectory(strPdfDir, 0); } SAFETY_EXIT_THREAD(_threadProcess, 100); _threadProcess = CreateThread(NULL, 0, ProcessThread, NULL, 0, NULL); //CDialogEx::OnOK(); } void CMFCApplication1Dlg::UpdateMsg(CString strMsg) { m_strMsg += strMsg; UpdateData(FALSE); } void CMFCApplication1Dlg::UpdateScanMsg(CString strMsg) { m_strScanMsg += strMsg; UpdateData(FALSE); } LRESULT CMFCApplication1Dlg::OnShowInfo(WPARAM wParam, LPARAM lParam) { wchar_t* p = (wchar_t*)wParam; CString str; str.Format(_T("%s"), p); m_strMsg += str; UpdateData(FALSE); if (lParam == 1) { GetDlgItem(IDOK)->EnableWindow(TRUE); } return 0; } LRESULT CMFCApplication1Dlg::OnShowScanInfo(WPARAM wParam, LPARAM lParam) { if (lParam == 1) { GetDlgItem(ID_BTN_SCAN)->EnableWindow(TRUE); return 0; } wchar_t* p = (wchar_t*)wParam; CString str; str.Format(_T("%s"), p); m_strScanMsg += str; UpdateData(FALSE); return 0; } LRESULT CMFCApplication1Dlg::OnProcessInfo(WPARAM wParam, LPARAM lParam) { CString strProcess = _T("--"); if (g_vecFileList.size()) { float fProcess = (float)g_scanCount / (float)g_vecFileList.size(); strProcess.Format(L"%0.0lf%%", fProcess*100); } SetDlgItemText(IDC_EDIT_SCANPROCESS, strProcess); return 0; } void CMFCApplication1Dlg::OnBnClickedCancel() { SAFETY_EXIT_THREAD(_threadProcess, 100); SAFETY_EXIT_THREAD(_threadScan, 100); CConfig::Instance()->SaveSetting(); CDialogEx::OnCancel(); } void CMFCApplication1Dlg::SelectFolder(HWND hwnd, CString& lpszFolder) { TCHAR szFolderPath[MAX_PATH]; szFolderPath[0] = 0; BROWSEINFO sInfo; ::ZeroMemory(&sInfo, sizeof(BROWSEINFO)); sInfo.pidlRoot = 0; sInfo.lpszTitle = _T("请选择一个文件夹"); sInfo.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_EDITBOX; sInfo.lpfn = NULL; sInfo.hwndOwner = hwnd; LPITEMIDLIST lpidlBrowse = ::SHBrowseForFolder(&sInfo); if (lpidlBrowse != NULL) { if (::SHGetPathFromIDList(lpidlBrowse, szFolderPath)) { lpszFolder = szFolderPath; lpszFolder.Replace('\\', '/'); } ::CoTaskMemFree(lpidlBrowse); } } void CMFCApplication1Dlg::SelectFile(CString& lpszFile) { CString OpenFilter = _T("文本文件(*.txt)|*.txt;|"); CFileDialog FileOpen(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, OpenFilter); if (IDOK == FileOpen.DoModal()) { lpszFile = FileOpen.GetPathName(); lpszFile.Replace('\\', '/'); } } void CMFCApplication1Dlg::OnBnClickedBtnTxt() { CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_TXT); if (!pEdit) { return; } CString strText; SelectFile(strText); if (strText.GetLength() == 0) { return; } pEdit->SetWindowText(strText); CConfig::Instance()->m_strTxt = strText; } void CMFCApplication1Dlg::OnBnClickedBtnPdf() { CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_PDF); if (!pEdit) { return; } CString strText; SelectFolder(GetSafeHwnd(), strText); if (strText.GetLength() == 0) { return; } pEdit->SetWindowText(strText); CConfig::Instance()->m_strPdf = strText; } void CMFCApplication1Dlg::OnBnClickedBtnModepath() { CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_MODEPATH); if (!pEdit) { return; } CString strText; SelectFolder(GetSafeHwnd(), strText); if (strText.GetLength() == 0) { return; } pEdit->SetWindowText(strText); CConfig::Instance()->m_strMode = strText; } void CMFCApplication1Dlg::OnBnClickedBtnImgpath() { CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_IMGPATH); if (!pEdit) { return; } CString strText; SelectFolder(GetSafeHwnd(), strText); if (strText.GetLength() == 0) { return; } pEdit->SetWindowText(strText); CConfig::Instance()->m_strImg = strText; } void CMFCApplication1Dlg::OnBnClickedBtnCutpath() { CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_CUTPATH); if (!pEdit) { return; } CString strText; SelectFolder(GetSafeHwnd(), strText); if (strText.GetLength() == 0) { return; } pEdit->SetWindowText(strText); CConfig::Instance()->m_strCut = strText; } void CMFCApplication1Dlg::OnBnClickedBtnScan() { ((CEdit*)GetDlgItem(IDC_EDIT_MODEPATH))->GetWindowText(m_strModePath); ((CEdit*)GetDlgItem(IDC_EDIT_IMGPATH))->GetWindowText(m_strImgPath); ((CEdit*)GetDlgItem(IDC_EDIT_CUTPATH))->GetWindowText(m_strCutPath); if (m_strModePath.GetLength() == 0) { AfxMessageBox(L"模板文件夹未选择"); return; } if (m_strImgPath.GetLength() == 0) { AfxMessageBox(L"答题卡文件夹未选择"); return; } if (m_strCutPath.GetLength() == 0) { AfxMessageBox(L"切割生成文件夹未选择"); return; } GetDlgItem(ID_BTN_SCAN)->EnableWindow(FALSE); m_strScanMsg = ""; CString strNormal(m_strCutPath); strNormal.Append(L"/normal"); if (!PathIsDirectory(strNormal)) { ::CreateDirectory(strNormal, 0); } CString strAbnormal(m_strCutPath); strAbnormal.Append(L"/abnormal"); if (!PathIsDirectory(strAbnormal)) { ::CreateDirectory(strAbnormal, 0); } SAFETY_EXIT_THREAD(_threadScan, 100); _threadScan = CreateThread(NULL, 0, ScanThread, NULL, 0, NULL); } void CMFCApplication1Dlg::FormatScanMsg(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_SHOWSCANINFO, (WPARAM)strMsg.GetBuffer(), 0); }