// HNRNumView.cpp : implementation of the CHNRNumView class // /****************************************** 1. Select File -> Open to load an image, load "DEMOICR.tif" 2. Select OCR -> "Add Page" to the loaded image into OCR engine 3. Select OCR -> "Insert Zone" to insert specific zone into the added page. 4. Select OCR -> "Recognize" to recognize the added page. 5. Select OCR -> "Save Results" to save the recognition results to an output file ******************************************/ #include "stdafx.h" #include "HNRNUM.h" #include "HNRNumDoc.h" #include "HNRNumView.h" #include "windowsx.h" #include "EngineMsg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CHNRNumView IMPLEMENT_DYNCREATE(CHNRNumView, CScrollView) BEGIN_MESSAGE_MAP(CHNRNumView, CScrollView) //{{AFX_MSG_MAP(CHNRNumView) ON_WM_ERASEBKGND() ON_WM_CREATE() ON_WM_DESTROY() ON_MESSAGE(WM_DOREALIZE, OnDoRealize) ON_COMMAND(ID_FILE_OPEN, OnFileOpen) ON_COMMAND(ID_FILE_SAVE, OnFileSave) ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, OnUpdateFileSave) ON_COMMAND(ID_OCR_ADDPAGE, OnOcrAddpage) ON_UPDATE_COMMAND_UI(ID_OCR_ADDPAGE, OnUpdateOcrAddpage) ON_COMMAND(ID_OCR_INSERTZONES, OnOcrInsertzones) ON_UPDATE_COMMAND_UI(ID_OCR_INSERTZONES, OnUpdateOcrInsertzones) ON_COMMAND(ID_OCR_RECOGNIZE, OnOcrRecognize) ON_UPDATE_COMMAND_UI(ID_OCR_RECOGNIZE, OnUpdateOcrRecognize) ON_COMMAND(ID_OCR_SAVERESULTS, OnOcrSaveresults) ON_UPDATE_COMMAND_UI(ID_OCR_SAVERESULTS, OnUpdateOcrSaveresults) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CHNRNumView construction/destruction CHNRNumView::CHNRNumView() { L_InitBitmap(&m_LEADBitmap, sizeof(BITMAPHANDLE), 0, 0, 0); m_hDoc = NULL; m_bPageAdded = FALSE; m_bRecog = FALSE; m_bZones = FALSE; m_hZonePen = NULL; m_hSelZonePen = NULL; m_hPalette = NULL; } CHNRNumView::~CHNRNumView() { if (m_LEADBitmap.Flags.Allocated) L_FreeBitmap(&m_LEADBitmap); } BOOL CHNRNumView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CScrollView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CHNRNumView drawing void CHNRNumView::OnDraw(CDC* pDC) { CHNRNumDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); HPALETTE OldPalette = NULL; if (m_LEADBitmap.Flags.Allocated) { CRect rcDst; rcDst.SetRect(0, 0, BITMAPWIDTH(&m_LEADBitmap), BITMAPHEIGHT(&m_LEADBitmap)); CRect rcClip; if (m_hPalette) { OldPalette = ::SelectPalette(pDC->m_hDC, m_hPalette, TRUE); pDC->RealizePalette(); } pDC->GetClipBox(rcClip); if (m_bPageAdded) { if (m_hDoc && m_bPageAdded) { L_DocDrawPage(m_hDoc, pDC->GetSafeHdc(), 0, NULL, NULL, &rcDst, &rcClip, SRCCOPY, TRUE); } } else L_PaintDC(pDC->GetSafeHdc(), &m_LEADBitmap, NULL, NULL, &rcDst, &rcClip, SRCCOPY); if (OldPalette) ::SelectPalette(pDC->m_hDC, OldPalette, TRUE); } } void CHNRNumView::OnInitialUpdate() { CScrollView::OnInitialUpdate(); CSize sizeTotal; // TODO: calculate the total size of this view sizeTotal.cx = sizeTotal.cy = 0; SetScrollSizes(MM_TEXT, sizeTotal); } ///////////////////////////////////////////////////////////////////////////// // CHNRNumView printing BOOL CHNRNumView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CHNRNumView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CHNRNumView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CHNRNumView diagnostics #ifdef _DEBUG void CHNRNumView::AssertValid() const { CScrollView::AssertValid(); } void CHNRNumView::Dump(CDumpContext& dc) const { CScrollView::Dump(dc); } CHNRNumDoc* CHNRNumView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CHNRNumDoc))); return (CHNRNumDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CHNRNumView message handlers void CHNRNumView::UpdateScrollView() { CSize sizeTotal; if (m_LEADBitmap.Flags.Allocated) { sizeTotal.cx = BITMAPWIDTH(&m_LEADBitmap); sizeTotal.cy = BITMAPHEIGHT(&m_LEADBitmap); OnDoRealize((WPARAM)AfxGetApp()->m_pMainWnd->m_hWnd, (LPARAM) FALSE); } else sizeTotal.cx = sizeTotal.cy = 0; SetScrollSizes(MM_TEXT, sizeTotal); RedrawWindow(); } LONG CHNRNumView::OnDoRealize(WPARAM wParam, LPARAM lParam) { UINT nColorsChanged = 0; if (!m_LEADBitmap.Flags.Allocated) return 0; if (lParam) { if (((HWND) wParam) == m_hWnd) return(FALSE); } if (m_hPalette != NULL) { DeleteObject(m_hPalette); m_hPalette = NULL; } CClientDC dc(this); m_hPalette = L_CreatePaintPalette(dc.m_hDC, &m_LEADBitmap); if (m_hPalette) { HPALETTE oldPalette = ::SelectPalette(dc.m_hDC, m_hPalette, (BOOL) lParam); nColorsChanged = RealizePalette(dc); if (nColorsChanged > 0) Invalidate(); ::SelectPalette(dc.m_hDC, oldPalette, TRUE); } return ((LRESULT) (BOOL) (nColorsChanged > 0)); } BOOL CHNRNumView::OnEraseBkgnd(CDC* pDC) { CRect rcClient; GetClientRect(&rcClient); CBrush br(GetSysColor(DKGRAY_BRUSH)); FillOutsideRect(pDC, &br); return TRUE; } void CHNRNumView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) { if (bActivate) OnDoRealize((WPARAM)AfxGetApp()->m_pMainWnd->m_hWnd, (LPARAM) FALSE); // same as SendMessage(WM_DOREALIZE); CScrollView::OnActivateView(bActivate, pActivateView, pDeactiveView); } void CHNRNumView::CleanOpenDlgParam(LPOPENDLGPARAMS pFOParam) { if (pFOParam && pFOParam->pFileData != NULL) { for (L_INT i=0; i < pFOParam->nNumOfFiles; i++) { if (pFOParam->pFileData[i].pBitmap) { if (pFOParam->pFileData[i].pBitmap->Flags.Allocated) L_FreeBitmap(pFOParam->pFileData[i].pBitmap); GlobalFreePtr(pFOParam->pFileData[i].pBitmap); } if (pFOParam->pFileData[i].pThumbnail) { if (pFOParam->pFileData[i].pThumbnail->Flags.Allocated) L_FreeBitmap(pFOParam->pFileData[i].pThumbnail); GlobalFreePtr(pFOParam->pFileData[i].pThumbnail); } if (pFOParam->pFileData[i].pFileInfo) GlobalFreePtr(pFOParam->pFileData[i].pFileInfo); } GlobalFreePtr(pFOParam->pFileData); pFOParam->pFileData = NULL; pFOParam->nNumOfFiles = 0; } } int CHNRNumView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CScrollView::OnCreate(lpCreateStruct) == -1) return -1; if (L_IsSupportLocked(L_SUPPORT_OCR)) { AfxMessageBox(TEXT("You need to unlock the OCR engine before you can use this demo!")); return -1; } BeginWaitCursor(); L_INT nRet = L_DocStartUp(&m_hDoc); if (nRet == SUCCESS) { m_hZonePen = CreatePen(PS_SOLID, 2, RGB(128, 128, 128)); m_hSelZonePen = CreatePen(PS_SOLID, 2, RGB(0, 255, 255)); L_DocSetZonePen(m_hDoc, m_hZonePen); L_DocSetSelectedZonePen(m_hDoc, m_hSelZonePen); HKEY hKey = HKEY_LOCAL_MACHINE; L_TCHAR szSubKey[MAX_PATH]; memset(szSubKey, 0, sizeof(szSubKey)); #ifndef UNICODE strcpy(szSubKey, "SOFTWARE\\LEAD Technologies, Inc.\\Images"); #else lstrcpy(szSubKey, _T("SOFTWARE\\LEAD Technologies, Inc.\\UnicodeImages")); #endif LONG nRet = RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hKey); if (nRet == 0) { DWORD lpType; BYTE data[MAX_PATH]; DWORD sizeData = MAX_PATH; memset(data,0,sizeof(data)); nRet = RegQueryValueEx(hKey, _T(""), NULL, &lpType, data, &sizeData); if (nRet == 0) m_csImagesPath.Format(_T("%s"), (L_TCHAR *)&data); RegCloseKey(hKey); } } else { if (nRet != ERROR_DOC_INITIALIZE_ENGINE) AfxMessageBox(TEXT("Failed while initializing the OCR Engine")); else { CEngineMsg engineDlg; engineDlg.DoModal(); } return -1; } EndWaitCursor(); return 0; } void CHNRNumView::OnDestroy() { if (m_LEADBitmap.Flags.Allocated) L_FreeBitmap(&m_LEADBitmap); if (m_hDoc) L_DocShutDown(&m_hDoc); if (m_hZonePen) { DeleteObject(m_hZonePen); m_hZonePen = NULL; } if (m_hSelZonePen) { DeleteObject(m_hSelZonePen); m_hSelZonePen = NULL; } if (m_hPalette) { DeleteObject(m_hPalette); m_hPalette = NULL; } CScrollView::OnDestroy(); } void CHNRNumView::OnFileOpen() { OPENFILENAME OpenFileName; OPENDLGPARAMS FOParm; memset(&FOParm, 0, sizeof(OPENDLGPARAMS)); memset(&OpenFileName, 0, sizeof(OPENFILENAME)); FOParm.uStructSize = sizeof(OPENDLGPARAMS); FOParm.bPreviewEnabled = TRUE; FOParm.uDlgFlags = DLG_OPEN_SHOW_PROGRESSIVE | DLG_OPEN_SHOW_MULTIPAGE | DLG_OPEN_SHOW_LOADROTATED | DLG_OPEN_SHOW_LOADCOMPRESSED | DLG_OPEN_SHOW_FILEINFO | DLG_OPEN_SHOW_PREVIEW | DLG_OPEN_SHOW_DELPAGE | DLG_OPEN_SHOW_LOADOPTIONS | DLG_OPEN_SHOW_RASTEROPTIONS | DLG_OPEN_SHOW_PDFOPTIONS | DLG_OPEN_SHOW_VECTOROPTIONS | DLG_OPEN_VIEWTOTALPAGES | DLG_OPEN_ENABLESIZING | DLG_OPEN_NOFILEMUSTEXIST | DLG_OPEN_NOPATHMUSTEXIST | DLG_OPEN_USEFILESTAMP; OpenFileName.lStructSize = sizeof(OPENFILENAME); OpenFileName.hwndOwner = NULL; OpenFileName.lpstrFilter = NULL; OpenFileName.lpstrCustomFilter = NULL; OpenFileName.nMaxCustFilter = 0; OpenFileName.nFilterIndex = 0; OpenFileName.lpstrInitialDir = NULL; OpenFileName.lpstrTitle = TEXT("Open a File"); OpenFileName.nFileOffset = 0; OpenFileName.nFileExtension = 0; OpenFileName.lpstrDefExt = NULL; OpenFileName.Flags = 0; L_INT nRet = L_DlgOpen(m_hWnd, &OpenFileName, &FOParm); if (nRet == SUCCESS_DLG_OK) { FILEINFO FileInfo; memset(&FileInfo, 0, sizeof(FILEINFO)); L_INT nRet = L_FileInfo((L_TCHAR *)FOParm.pFileData[0].szFileName, &FileInfo, sizeof(FILEINFO), 0, NULL); if (nRet != SUCCESS) return; LOADFILEOPTION LoadOptions; memset(&LoadOptions, 0, sizeof(LOADFILEOPTION)); if (m_LEADBitmap.Flags.Allocated) { L_FreeBitmap(&m_LEADBitmap); Reset(); } L_GetDefaultLoadFileOption(&LoadOptions, sizeof(LOADFILEOPTION)); LoadOptions.PageNumber = FOParm.pFileData[0].nPageNumber; nRet = L_LoadBitmap((L_TCHAR *)FOParm.pFileData[0].szFileName, &m_LEADBitmap, sizeof(BITMAPHANDLE), 0, ORDER_BGRORGRAY, &LoadOptions, NULL); if (nRet == SUCCESS) { UpdateScrollView(); m_bPageAdded = FALSE; } CleanOpenDlgParam(&FOParm); } } void CHNRNumView::OnFileSave() { BeginWaitCursor(); SAVEDLGPARAMS FSParm; OPENFILENAME OpenFileName; L_TCHAR szFileName[_MAX_PATH]=TEXT(""); memset(&OpenFileName,0,sizeof(OPENFILENAME)); memset(&FSParm, 0, sizeof(SAVEDLGPARAMS)); OpenFileName.lStructSize = sizeof(OPENFILENAME); OpenFileName.lpstrInitialDir = NULL; OpenFileName.lpstrTitle = TEXT("Save a File"); OpenFileName.lpstrFile = szFileName; OpenFileName.nMaxFile = sizeof(szFileName)/sizeof(L_TCHAR); OpenFileName.lpstrFileTitle = FSParm.szFileName; OpenFileName.nMaxFileTitle = sizeof(FSParm.szFileName)/sizeof(L_TCHAR); OpenFileName.nFileOffset = 0; OpenFileName.Flags = 0; FSParm.uStructSize = sizeof(SAVEDLGPARAMS); FSParm.pBitmap = &m_LEADBitmap; FSParm.nQFactor = 2; FSParm.uDlgFlags = DLG_SAVE_AUTOPROCESS | DLG_SAVE_SHOW_FILEOPTIONS_MULTIPAGE | DLG_SAVE_SHOW_FILEOPTIONS_PROGRESSIVE | DLG_SAVE_SHOW_FILEOPTIONS_QFACTOR | DLG_SAVE_SHOW_FILEOPTIONS_STAMP | DLG_SAVE_SHOW_FILEOPTIONS_J2KOPTIONS | DLG_SAVE_SHOW_FILEOPTIONS_BASICJ2KOPTIONS; L_INT nRet = L_DlgSave(m_hWnd, &OpenFileName, &FSParm); if (!ISDLGSUCCESS(nRet)) { CString csBuffer; csBuffer.Format(TEXT("Can not save file,\nError code = %d\n"), nRet); AfxMessageBox(csBuffer); } EndWaitCursor(); } void CHNRNumView::OnUpdateFileSave(CCmdUI* pCmdUI) { pCmdUI->Enable(m_LEADBitmap.Flags.Allocated); } void CHNRNumView::OnOcrAddpage() { BeginWaitCursor(); if (!m_LEADBitmap.Flags.Allocated) return; L_INT nRet = L_DocAddPage(m_hDoc, &m_LEADBitmap, -1); if (nRet != SUCCESS) { CString csErr; csErr.Format(_T("Can't add page to engine\nError = %d\n"), nRet); AfxMessageBox(csErr); } else { L_DocExportPage(m_hDoc, &m_LEADBitmap, sizeof(BITMAPHANDLE), 0); L_DocSetActivePage(m_hDoc, 0); UpdateScrollView(); m_bPageAdded = TRUE; } EndWaitCursor(); } void CHNRNumView::OnUpdateOcrAddpage(CCmdUI* pCmdUI) { pCmdUI->Enable(m_hDoc && m_LEADBitmap.Flags.Allocated && !m_bPageAdded); } void CHNRNumView::OnOcrInsertzones() { PAGEINFO PageInfo; memset(&PageInfo, 0, sizeof(PAGEINFO)); L_DocGetPageInfo(m_hDoc, 0, &PageInfo, sizeof(PAGEINFO)); ZONEDATA zone; memset(&zone, 0, sizeof(ZONEDATA)); zone.uStructSize = sizeof(ZONEDATA); zone.rcArea.left = 0; zone.rcArea.top = 0; zone.rcArea.right = PageInfo.nWidth; zone.rcArea.bottom = PageInfo.nHeight; zone.FillMethod = FILL_HANDPRINT; zone.RecogModule = RECOGMODULE_HAND_PRINTED_NUMERAL; zone.CharFilter = ZONE_CHAR_FILTER_DIGIT; zone.Type = ZONE_FLOWTEXT; m_bZones = FALSE; L_INT nRet = L_DocAddZone(m_hDoc, 0, 0, &zone); if (nRet == SUCCESS) { AfxMessageBox(_T("The specified Zone inserted successfully")); m_bZones = TRUE; RedrawWindow(); } else AfxMessageBox(_T("Can't insert the specified Zone")); } void CHNRNumView::OnUpdateOcrInsertzones(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bPageAdded && !m_bZones); } void CHNRNumView::OnOcrRecognize() { CString csMsg; csMsg.Format(TEXT("Do you want to delete all previous output files?")); int nAnswer = MessageBox(csMsg, TEXT("Delete output files"), MB_YESNO); if (nAnswer == IDYES) { CString csFile; csFile.Format(TEXT("%s\\hnrnum.rdf"), m_csImagesPath); DeleteFile(csFile); csFile.Format(TEXT("%s\\hnrnum.pdf"), m_csImagesPath); DeleteFile(csFile); } RECOGNIZEOPTS RecogOpts; CString csDataFile; csDataFile.Format(_T("%s\\hnrnum.rdf"), m_csImagesPath); memset(&RecogOpts, 0, sizeof(RECOGNIZEOPTS)); RecogOpts.uStructSize = sizeof(RECOGNIZEOPTS); RecogOpts.nPageIndexStart = 0; RecogOpts.nPagesCount = 1; RecogOpts.bEnableSubSystem = FALSE; RecogOpts.bEnableCorrection = FALSE; RecogOpts.SpellLangId = LANG_ID_ENGLISH; RecogOpts.pszFileName = (L_TCHAR *)(LPCTSTR)csDataFile; BeginWaitCursor(); m_bRecog = FALSE; L_INT nRet = L_DocRecognize(m_hDoc, &RecogOpts, NULL, this); EndWaitCursor(); if (nRet != SUCCESS) { AfxMessageBox(_T("Can't recognize the specific pages")); return; } else { CString csMsg; csMsg.Format(_T("The recognition process successful, you will find the result at (%s)"), csDataFile); AfxMessageBox(csMsg); } m_bRecog = TRUE; RedrawWindow(); } void CHNRNumView::OnUpdateOcrRecognize(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bZones && !m_bRecog); } void CHNRNumView::OnOcrSaveresults() { RESULTOPTIONS resOpts; memset(&resOpts, 0, sizeof(RESULTOPTIONS)); L_INT nRet = L_DocGetRecognitionResultOptions(m_hDoc, &resOpts, sizeof(RESULTOPTIONS)); if (nRet == SUCCESS) { resOpts.Format = DOC_PDF; resOpts.FormatLevel = FORMAT_LEVEL_FULL; L_DocSetRecognitionResultOptions(m_hDoc, &resOpts); } CString csResultFile; csResultFile.Format(_T("%s\\hnrnum.pdf"), m_csImagesPath); nRet = L_DocSaveResultsToFile(m_hDoc, (L_TCHAR *)(LPCTSTR)csResultFile); if (nRet != SUCCESS) AfxMessageBox(_T("Can't save recognition result to specific format")); else { CString csMsg; csMsg.Format(_T("The output file saved at (%s)"), csResultFile); AfxMessageBox(csMsg); } } void CHNRNumView::OnUpdateOcrSaveresults(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bRecog); } void CHNRNumView::Reset() { L_InitBitmap(&m_LEADBitmap, sizeof(BITMAPHANDLE), 0, 0, 0); if (m_bPageAdded) L_DocRemovePage(m_hDoc, 0); m_bPageAdded = FALSE; m_bRecog = FALSE; m_bZones = FALSE; m_hZonePen = NULL; m_hSelZonePen = NULL; m_hPalette = NULL; }